Skip to content

Commit a822a03

Browse files
committed
[Tests] Add provider-update-revoke to dip3_protx unit-test
check: - valid payload - payload malleability
1 parent a4a0afb commit a822a03

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

src/evo/providertx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class ProUpRevPL
132132
static const uint16_t CURRENT_VERSION = 1;
133133

134134
// these are just informational and do not have any effect on the revocation
135-
enum {
135+
enum RevocationReason {
136136
REASON_NOT_SPECIFIED = 0,
137137
REASON_TERMINATION_OF_SERVICE = 1,
138138
REASON_COMPROMISED_KEYS = 2,

src/test/evo_deterministicmns_tests.cpp

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,28 @@ static CMutableTransaction CreateProUpRegTx(SimpleUTXOMap& utxos, const uint256&
181181
return tx;
182182
}
183183

184+
static CMutableTransaction CreateProUpRevTx(SimpleUTXOMap& utxos, const uint256& proTxHash, ProUpRevPL::RevocationReason reason, const CKey& operatorKey, const CKey& coinbaseKey)
185+
{
186+
CAmount change;
187+
auto inputs = SelectUTXOs(utxos, 1 * COIN, change);
188+
189+
ProUpRevPL pl;
190+
pl.proTxHash = proTxHash;
191+
pl.nReason = reason;
192+
193+
CMutableTransaction tx;
194+
tx.nVersion = CTransaction::TxVersion::SAPLING;
195+
tx.nType = CTransaction::TxType::PROUPREV;
196+
const CScript& s = GetScriptForDestination(coinbaseKey.GetPubKey().GetID());
197+
FundTransaction(tx, utxos, s, s, 1 * COIN);
198+
pl.inputsHash = CalcTxInputsHash(tx);
199+
BOOST_ASSERT(CHashSigner::SignHash(::SerializeHash(pl), operatorKey, pl.vchSig));
200+
SetTxPayload(tx, pl);
201+
SignTransaction(tx, coinbaseKey);
202+
203+
return tx;
204+
}
205+
184206
static CScript GenerateRandomAddress()
185207
{
186208
CKey key;
@@ -212,6 +234,17 @@ static CMutableTransaction MalleateProUpServTx(const CMutableTransaction& tx)
212234
return tx2;
213235
}
214236

237+
static CMutableTransaction MalleateProUpRevTx(const CMutableTransaction& tx)
238+
{
239+
ProUpRevPL pl;
240+
GetTxPayload(tx, pl);
241+
BOOST_ASSERT(pl.nReason != ProUpRevPL::RevocationReason::REASON_CHANGE_OF_KEYS);
242+
pl.nReason = ProUpRevPL::RevocationReason::REASON_CHANGE_OF_KEYS;
243+
CMutableTransaction tx2 = tx;
244+
SetTxPayload(tx2, pl);
245+
return tx2;
246+
}
247+
215248
static bool CheckTransactionSignature(const CMutableTransaction& tx)
216249
{
217250
for (unsigned int i = 0; i < tx.vin.size(); i++) {
@@ -583,7 +616,8 @@ BOOST_FIXTURE_TEST_CASE(dip3_protx, TestChain400Setup)
583616
}
584617

585618
// ProUpReg: change voting key, operator key and payout address
586-
{ const uint256& proTx = dmnHashes[InsecureRandRange(dmnHashes.size())]; // pick one at random
619+
{
620+
const uint256& proTx = dmnHashes[InsecureRandRange(dmnHashes.size())]; // pick one at random
587621
const CKey& new_operatorKey = GetRandomKey();
588622
const CKey& new_votingKey = GetRandomKey();
589623
const CScript& new_payee = GenerateRandomAddress();
@@ -686,6 +720,39 @@ BOOST_FIXTURE_TEST_CASE(dip3_protx, TestChain400Setup)
686720
BOOST_CHECK_EQUAL(chainActive.Height(), nHeight); // bad block not connected
687721
}
688722

723+
// ProUpRev: revoke masternode service
724+
{
725+
const uint256& proTx = dmnHashes[InsecureRandRange(dmnHashes.size())]; // pick one at random
726+
ProUpRevPL::RevocationReason reason = ProUpRevPL::RevocationReason::REASON_TERMINATION_OF_SERVICE;
727+
// try first with wrong operator key
728+
CValidationState state;
729+
auto tx = CreateProUpRevTx(utxos, proTx, reason, GetRandomKey(), coinbaseKey);
730+
BOOST_CHECK_MESSAGE(!CheckProUpRevTx(tx, chainTip, state), "ProUpReg verifies with wrong owner key");
731+
BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-protx-sig");
732+
// then use the proper key
733+
state = CValidationState();
734+
tx = CreateProUpRevTx(utxos, proTx, reason, operatorKeys.at(proTx), coinbaseKey);
735+
BOOST_CHECK_MESSAGE(CheckProUpRevTx(tx, chainTip, state), state.GetRejectReason());
736+
BOOST_CHECK_MESSAGE(CheckTransactionSignature(tx), "ProUpReg signature verification failed");
737+
// also verify that payloads are not malleable after they have been signed
738+
auto tx2 = MalleateProUpRevTx(tx);
739+
BOOST_CHECK_MESSAGE(!CheckSpecialTx(tx2, chainTip, state), "Malleated ProUpReg accepted");
740+
BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-protx-sig");
741+
742+
CreateAndProcessBlock({tx}, coinbaseKey);
743+
chainTip = chainActive.Tip();
744+
BOOST_CHECK_EQUAL(chainTip->nHeight, ++nHeight);
745+
746+
SyncWithValidationInterfaceQueue();
747+
auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx);
748+
BOOST_ASSERT(dmn != nullptr);
749+
BOOST_CHECK_MESSAGE(dmn->pdmnState->keyIDOperator == CKeyID(), "mn operator key not removed");
750+
BOOST_CHECK_MESSAGE(dmn->pdmnState->addr == CService(), "mn IP address not removed");
751+
BOOST_CHECK_MESSAGE(dmn->pdmnState->scriptOperatorPayout.empty(), "mn operator payout not removed");
752+
BOOST_CHECK_EQUAL(dmn->pdmnState->nRevocationReason, reason);
753+
BOOST_CHECK_EQUAL(dmn->pdmnState->nPoSeBanHeight, nHeight);
754+
}
755+
689756
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V6_0, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
690757
}
691758

0 commit comments

Comments
 (0)