Skip to content

Commit

Permalink
Classes, validation and update logic for CProUpRevTX
Browse files Browse the repository at this point in the history
  • Loading branch information
codablock committed Aug 31, 2018
1 parent 185416b commit 9653af2
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 4 deletions.
24 changes: 22 additions & 2 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ std::string CDeterministicMNState::ToString() const
operatorRewardAddress = CBitcoinAddress(dest).ToString();
}

return strprintf("CDeterministicMNState(nRegisteredHeight=%d, nLastPaidHeight=%d, nPoSePenalty=%d, nPoSeRevivedHeight=%d, nPoSeBanHeight=%d, "
return strprintf("CDeterministicMNState(nRegisteredHeight=%d, nLastPaidHeight=%d, nPoSePenalty=%d, nPoSeRevivedHeight=%d, nPoSeBanHeight=%d, nRevocationReason=%d, "
"keyIDOwner=%s, keyIDOperator=%s, keyIDVoting=%s, addr=%s, nProtocolVersion=%d, payoutAddress=%s, operatorRewardAddress=%s)",
nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight,
nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight, nRevocationReason,
keyIDOwner.ToString(), keyIDOperator.ToString(), keyIDVoting.ToString(), addr.ToStringIPPort(false), nProtocolVersion, payoutAddress, operatorRewardAddress);
}

Expand All @@ -47,6 +47,7 @@ void CDeterministicMNState::ToJson(UniValue& obj) const
obj.push_back(Pair("PoSePenalty", nPoSePenalty));
obj.push_back(Pair("PoSeRevivedHeight", nPoSeRevivedHeight));
obj.push_back(Pair("PoSeBanHeight", nPoSeBanHeight));
obj.push_back(Pair("revocationReason", nRevocationReason));
obj.push_back(Pair("keyIDOwner", keyIDOwner.ToString()));
obj.push_back(Pair("keyIDOperator", keyIDOperator.ToString()));
obj.push_back(Pair("keyIDVoting", keyIDVoting.ToString()));
Expand Down Expand Up @@ -459,6 +460,25 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C

LogPrintf("CDeterministicMNManager::%s -- MN %s updated at height %d: %s\n",
__func__, proTx.proTxHash.ToString(), nHeight, proTx.ToString());
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
CProUpRevTx proTx;
if (!GetTxPayload(tx, proTx)) {
assert(false); // this should have been handled already
}

CDeterministicMNCPtr dmn = newList.GetMN(proTx.proTxHash);
if (!dmn) {
return _state.DoS(100, false, REJECT_INVALID, "bad-protx-hash");
}
auto newState = std::make_shared<CDeterministicMNState>(*dmn->pdmnState);
newState->ResetOperatorFields();
newState->BanIfNotBanned(nHeight);
newState->nRevocationReason = proTx.nReason;

newList.UpdateMN(proTx.proTxHash, newState);

LogPrintf("CDeterministicMNManager::%s -- MN %s revoked operator key at height %d: %s\n",
__func__, proTx.proTxHash.ToString(), nHeight, proTx.ToString());
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class CDeterministicMNState
int nPoSePenalty{0};
int nPoSeRevivedHeight{-1};
int nPoSeBanHeight{-1};
uint16_t nRevocationReason{CProUpRevTx::REASON_NOT_SPECIFIED};

CKeyID keyIDOwner;
CKeyID keyIDOperator;
Expand Down Expand Up @@ -63,6 +64,7 @@ class CDeterministicMNState
READWRITE(nPoSePenalty);
READWRITE(nPoSeRevivedHeight);
READWRITE(nPoSeBanHeight);
READWRITE(nRevocationReason);
READWRITE(keyIDOwner);
READWRITE(keyIDOperator);
READWRITE(keyIDVoting);
Expand All @@ -78,7 +80,7 @@ class CDeterministicMNState
addr = CService();
nProtocolVersion = 0;
scriptOperatorPayout = CScript();
revocationReason = CProUpRevTx::REASON_NOT_SPECIFIED;
nRevocationReason = CProUpRevTx::REASON_NOT_SPECIFIED;
}
void BanIfNotBanned(int height)
{
Expand All @@ -94,6 +96,7 @@ class CDeterministicMNState
nPoSePenalty == rhs.nPoSePenalty &&
nPoSeRevivedHeight == rhs.nPoSeRevivedHeight &&
nPoSeBanHeight == rhs.nPoSeBanHeight &&
nRevocationReason == rhs.nRevocationReason &&
keyIDOwner == rhs.keyIDOwner &&
keyIDOperator == rhs.keyIDOperator &&
keyIDVoting == rhs.keyIDVoting &&
Expand Down
43 changes: 43 additions & 0 deletions src/evo/providertx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,33 @@ bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal
return true;
}

bool CheckProUpRevTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state)
{
AssertLockHeld(cs_main);

CProUpRevTx ptx;
if (!GetTxPayload(tx, ptx))
return state.DoS(100, false, REJECT_INVALID, "bad-tx-payload");

if (ptx.nVersion > CProRegTx::CURRENT_VERSION)
return state.DoS(100, false, REJECT_INVALID, "bad-protx-version");

if (ptx.nReason < CProUpRevTx::REASON_NOT_SPECIFIED || ptx.nReason > CProUpRevTx::REASON_LAST)
return state.DoS(100, false, REJECT_INVALID, "bad-protx-reason");

if (pindexPrev) {
auto mnList = deterministicMNManager->GetListForBlock(pindexPrev->GetBlockHash());
auto dmn = mnList.GetMN(ptx.proTxHash);
if (!dmn)
return state.DoS(100, false, REJECT_INVALID, "bad-protx-hash");

if (!CheckInputsHashAndSig(tx, ptx, dmn->pdmnState->keyIDOperator, state))
return false;
}

return true;
}

std::string CProRegTx::ToString() const
{
CTxDestination dest;
Expand Down Expand Up @@ -307,6 +334,22 @@ void CProUpRegTx::ToJson(UniValue& obj) const
obj.push_back(Pair("inputsHash", inputsHash.ToString()));
}

std::string CProUpRevTx::ToString() const
{
return strprintf("CProUpRevTx(nVersion=%d, proTxHash=%s, nReason=%d)",
nVersion, proTxHash.ToString(), nReason);
}

void CProUpRevTx::ToJson(UniValue& obj) const
{
obj.clear();
obj.setObject();
obj.push_back(Pair("version", nVersion));
obj.push_back(Pair("proTxHash", proTxHash.ToString()));
obj.push_back(Pair("reason", (int)nReason));
obj.push_back(Pair("inputsHash", inputsHash.ToString()));
}

bool IsProTxCollateral(const CTransaction& tx, uint32_t n)
{
return GetProTxCollateralIndex(tx) == n;
Expand Down
42 changes: 42 additions & 0 deletions src/evo/providertx.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,52 @@ class CProUpRegTx
void ToJson(UniValue& obj) const;
};

class CProUpRevTx
{
public:
static const uint16_t CURRENT_VERSION = 1;

// these are just informational and do not have any effect on the revocation
enum {
REASON_NOT_SPECIFIED = 0,
REASON_TERMINATION_OF_SERVICE = 1,
REASON_COMPROMISED_KEYS = 2,
REASON_CHANGE_OF_KEYS = 3,
REASON_LAST = REASON_CHANGE_OF_KEYS
};

public:
uint16_t nVersion{CURRENT_VERSION}; // message version
uint256 proTxHash;
uint16_t nReason{REASON_NOT_SPECIFIED};
uint256 inputsHash; // replay protection
std::vector<unsigned char> vchSig;

public:
ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action)
{
READWRITE(nVersion);
READWRITE(proTxHash);
READWRITE(nReason);
READWRITE(inputsHash);
if (!(s.GetType() & SER_GETHASH)) {
READWRITE(vchSig);
}
}

public:
std::string ToString() const;
void ToJson(UniValue& obj) const;
};


bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state);
bool CheckProUpServTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state);
bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state);
bool CheckProUpRevTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state);

bool IsProTxCollateral(const CTransaction& tx, uint32_t n);
uint32_t GetProTxCollateralIndex(const CTransaction& tx);
Expand Down
4 changes: 4 additions & 0 deletions src/evo/specialtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVali
return CheckProUpServTx(tx, pindexPrev, state);
case TRANSACTION_PROVIDER_UPDATE_REGISTRAR:
return CheckProUpRegTx(tx, pindexPrev, state);
case TRANSACTION_PROVIDER_UPDATE_REVOKE:
return CheckProUpRevTx(tx, pindexPrev, state);
}

return state.DoS(10, false, REJECT_INVALID, "bad-tx-type");
Expand All @@ -45,6 +47,7 @@ bool ProcessSpecialTx(const CTransaction& tx, const CBlockIndex* pindex, CValida
case TRANSACTION_PROVIDER_REGISTER:
case TRANSACTION_PROVIDER_UPDATE_SERVICE:
case TRANSACTION_PROVIDER_UPDATE_REGISTRAR:
case TRANSACTION_PROVIDER_UPDATE_REVOKE:
return true; // handled in batches per block
}

Expand All @@ -60,6 +63,7 @@ bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
case TRANSACTION_PROVIDER_REGISTER:
case TRANSACTION_PROVIDER_UPDATE_SERVICE:
case TRANSACTION_PROVIDER_UPDATE_REGISTRAR:
case TRANSACTION_PROVIDER_UPDATE_REVOKE:
return true; // handled in batches per block
}

Expand Down
1 change: 1 addition & 0 deletions src/primitives/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum {
TRANSACTION_PROVIDER_REGISTER = 1,
TRANSACTION_PROVIDER_UPDATE_SERVICE = 2,
TRANSACTION_PROVIDER_UPDATE_REGISTRAR = 3,
TRANSACTION_PROVIDER_UPDATE_REVOKE = 4,
};

/** An outpoint - a combination of a transaction hash and an index n into its vout */
Expand Down
7 changes: 7 additions & 0 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
proTx.ToJson(proTxObj);
entry.push_back(Pair("proUpRegTx", proTxObj));
}
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
CProUpRevTx proTx;
if (GetTxPayload(tx, proTx)) {
UniValue proTxObj;
proTx.ToJson(proTxObj);
entry.push_back(Pair("proUpRevTx", proTxObj));
}
}

if (!hashBlock.IsNull()) {
Expand Down
3 changes: 2 additions & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,8 @@ bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state,
if (tx.nType != TRANSACTION_NORMAL &&
tx.nType != TRANSACTION_PROVIDER_REGISTER &&
tx.nType != TRANSACTION_PROVIDER_UPDATE_SERVICE &&
tx.nType != TRANSACTION_PROVIDER_UPDATE_REGISTRAR) {
tx.nType != TRANSACTION_PROVIDER_UPDATE_REGISTRAR &&
tx.nType != TRANSACTION_PROVIDER_UPDATE_REVOKE) {
return state.DoS(100, false, REJECT_INVALID, "bad-txns-type");
}
if (tx.IsCoinBase() && tx.nType != TRANSACTION_NORMAL)
Expand Down

0 comments on commit 9653af2

Please sign in to comment.