Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/test/proof_tests.cpp
Show First 20 Lines • Show All 883 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(deserialization) { | ||||
BOOST_CHECK(!Proof::useLegacy(gArgs)); | BOOST_CHECK(!Proof::useLegacy(gArgs)); | ||||
checkCases(regularFormatTestCases); | checkCases(regularFormatTestCases); | ||||
gArgs.ClearForcedArg("-legacyavaproof"); | gArgs.ClearForcedArg("-legacyavaproof"); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(verify) { | BOOST_AUTO_TEST_CASE(verify) { | ||||
gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "1"); | gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "1"); | ||||
CCoinsView coinsDummy; | |||||
CCoinsViewCache coins(&coinsDummy); | |||||
auto key = CKey::MakeCompressedKey(); | auto key = CKey::MakeCompressedKey(); | ||||
const CPubKey pubkey = key.GetPubKey(); | const CPubKey pubkey = key.GetPubKey(); | ||||
const Amount value = 12345 * COIN; | const Amount value = 12345 * COIN; | ||||
const uint32_t height = 10; | const uint32_t height = 10; | ||||
ChainstateManager &chainman = *Assert(m_node.chainman); | ChainstateManager &chainman = *Assert(m_node.chainman); | ||||
LOCK(cs_main); | |||||
CCoinsViewCache &coins = chainman.ActiveChainstate().CoinsTip(); | |||||
COutPoint pkh_outpoint(TxId(InsecureRand256()), InsecureRand32()); | COutPoint pkh_outpoint(TxId(InsecureRand256()), InsecureRand32()); | ||||
CTxOut pkh_output(value, GetScriptForRawPubKey(pubkey)); | CTxOut pkh_output(value, GetScriptForRawPubKey(pubkey)); | ||||
coins.AddCoin(pkh_outpoint, Coin(pkh_output, height, false), false); | coins.AddCoin(pkh_outpoint, Coin(pkh_output, height, false), false); | ||||
COutPoint nonstd_outpoint(TxId(InsecureRand256()), InsecureRand32()); | COutPoint nonstd_outpoint(TxId(InsecureRand256()), InsecureRand32()); | ||||
CTxOut nonstd_output(value, CScript() << OP_TRUE); | CTxOut nonstd_output(value, CScript() << OP_TRUE); | ||||
coins.AddCoin(nonstd_outpoint, Coin(nonstd_output, height, false), false); | coins.AddCoin(nonstd_outpoint, Coin(nonstd_output, height, false), false); | ||||
Show All 9 Lines | const auto runCheck = [&](const ProofValidationResult result, | ||||
const CKey &k) { | const CKey &k) { | ||||
// Generate a proof that match the UTXO. | // Generate a proof that match the UTXO. | ||||
ProofBuilder pb(0, 0, key); | ProofBuilder pb(0, 0, key); | ||||
BOOST_CHECK(pb.addUTXO(o, v, h, is_coinbase, k)); | BOOST_CHECK(pb.addUTXO(o, v, h, is_coinbase, k)); | ||||
ProofRef p = pb.build(); | ProofRef p = pb.build(); | ||||
ProofValidationState state; | ProofValidationState state; | ||||
BOOST_CHECK(p->verify(state)); | BOOST_CHECK(p->verify(state)); | ||||
BOOST_CHECK(p->verify(state, coins) == | LOCK(cs_main); | ||||
BOOST_CHECK(p->verify(state, chainman) == | |||||
(result == ProofValidationResult::NONE)); | (result == ProofValidationResult::NONE)); | ||||
BOOST_CHECK(state.GetResult() == result); | BOOST_CHECK(state.GetResult() == result); | ||||
}; | }; | ||||
// Valid proof | // Valid proof | ||||
runCheck(ProofValidationResult::NONE, pkh_outpoint, value, height, false, | runCheck(ProofValidationResult::NONE, pkh_outpoint, value, height, false, | ||||
key); | key); | ||||
Show All 31 Lines | // Mismatching key | ||||
value, height, false, CKey::MakeCompressedKey()); | value, height, false, CKey::MakeCompressedKey()); | ||||
} | } | ||||
// No stake | // No stake | ||||
{ | { | ||||
ProofRef p = ProofBuilder(0, 0, key).build(); | ProofRef p = ProofBuilder(0, 0, key).build(); | ||||
ProofValidationState state; | ProofValidationState state; | ||||
BOOST_CHECK(!p->verify(state, coins)); | BOOST_CHECK(!p->verify(state, chainman)); | ||||
BOOST_CHECK(state.GetResult() == ProofValidationResult::NO_STAKE); | BOOST_CHECK(state.GetResult() == ProofValidationResult::NO_STAKE); | ||||
} | } | ||||
// Dust thresold | // Dust thresold | ||||
{ | { | ||||
ProofBuilder pb(0, 0, key); | ProofBuilder pb(0, 0, key); | ||||
BOOST_CHECK( | BOOST_CHECK( | ||||
pb.addUTXO(pkh_outpoint, Amount::zero(), height, false, key)); | pb.addUTXO(pkh_outpoint, Amount::zero(), height, false, key)); | ||||
ProofRef p = pb.build(); | ProofRef p = pb.build(); | ||||
ProofValidationState state; | ProofValidationState state; | ||||
BOOST_CHECK(!p->verify(state, coins)); | BOOST_CHECK(!p->verify(state, chainman)); | ||||
BOOST_CHECK(state.GetResult() == ProofValidationResult::DUST_THRESHOLD); | BOOST_CHECK(state.GetResult() == ProofValidationResult::DUST_THRESHOLD); | ||||
} | } | ||||
{ | { | ||||
ProofBuilder pb(0, 0, key); | ProofBuilder pb(0, 0, key); | ||||
BOOST_CHECK(pb.addUTXO(pkh_outpoint, PROOF_DUST_THRESHOLD - 1 * SATOSHI, | BOOST_CHECK(pb.addUTXO(pkh_outpoint, PROOF_DUST_THRESHOLD - 1 * SATOSHI, | ||||
height, false, key)); | height, false, key)); | ||||
ProofRef p = pb.build(); | ProofRef p = pb.build(); | ||||
ProofValidationState state; | ProofValidationState state; | ||||
BOOST_CHECK(!p->verify(state, coins)); | BOOST_CHECK(!p->verify(state, chainman)); | ||||
BOOST_CHECK(state.GetResult() == ProofValidationResult::DUST_THRESHOLD); | BOOST_CHECK(state.GetResult() == ProofValidationResult::DUST_THRESHOLD); | ||||
} | } | ||||
// Duplicated input | // Duplicated input | ||||
{ | { | ||||
ProofBuilder pb(0, 0, key); | ProofBuilder pb(0, 0, key); | ||||
BOOST_CHECK(pb.addUTXO(pkh_outpoint, value, height, false, key)); | BOOST_CHECK(pb.addUTXO(pkh_outpoint, value, height, false, key)); | ||||
ProofRef p = TestProofBuilder::buildDuplicatedStakes(pb); | ProofRef p = TestProofBuilder::buildDuplicatedStakes(pb); | ||||
ProofValidationState state; | ProofValidationState state; | ||||
BOOST_CHECK(!p->verify(state, coins)); | BOOST_CHECK(!p->verify(state, chainman)); | ||||
BOOST_CHECK(state.GetResult() == | BOOST_CHECK(state.GetResult() == | ||||
ProofValidationResult::DUPLICATE_STAKE); | ProofValidationResult::DUPLICATE_STAKE); | ||||
} | } | ||||
// Wrong stake ordering | // Wrong stake ordering | ||||
{ | { | ||||
COutPoint other_pkh_outpoint(TxId(InsecureRand256()), InsecureRand32()); | COutPoint other_pkh_outpoint(TxId(InsecureRand256()), InsecureRand32()); | ||||
CTxOut other_pkh_output(value, GetScriptForRawPubKey(pubkey)); | CTxOut other_pkh_output(value, GetScriptForRawPubKey(pubkey)); | ||||
coins.AddCoin(other_pkh_outpoint, Coin(other_pkh_output, height, false), | coins.AddCoin(other_pkh_outpoint, Coin(other_pkh_output, height, false), | ||||
false); | false); | ||||
ProofBuilder pb(0, 0, key); | ProofBuilder pb(0, 0, key); | ||||
BOOST_CHECK(pb.addUTXO(pkh_outpoint, value, height, false, key)); | BOOST_CHECK(pb.addUTXO(pkh_outpoint, value, height, false, key)); | ||||
BOOST_CHECK(pb.addUTXO(other_pkh_outpoint, value, height, false, key)); | BOOST_CHECK(pb.addUTXO(other_pkh_outpoint, value, height, false, key)); | ||||
ProofRef p = TestProofBuilder::buildWithReversedOrderStakes(pb); | ProofRef p = TestProofBuilder::buildWithReversedOrderStakes(pb); | ||||
ProofValidationState state; | ProofValidationState state; | ||||
BOOST_CHECK(!p->verify(state, coins)); | BOOST_CHECK(!p->verify(state, chainman)); | ||||
BOOST_CHECK(state.GetResult() == | BOOST_CHECK(state.GetResult() == | ||||
ProofValidationResult::WRONG_STAKE_ORDERING); | ProofValidationResult::WRONG_STAKE_ORDERING); | ||||
} | } | ||||
// Immature stake | // Immature stake | ||||
{ | { | ||||
uint32_t chaintipHeight = chainman.ActiveHeight(); | uint32_t chaintipHeight = chainman.ActiveHeight(); | ||||
Show All 39 Lines | // Immature stake | ||||
std::get<1>(*it)); | std::get<1>(*it)); | ||||
runCheck(std::get<2>(*it), outpoint, value, stakeConfs, false, key); | runCheck(std::get<2>(*it), outpoint, value, stakeConfs, false, key); | ||||
} | } | ||||
gArgs.ClearForcedArg("-avaproofstakeutxoconfirmations"); | gArgs.ClearForcedArg("-avaproofstakeutxoconfirmations"); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(deterministic_proofid) { | BOOST_AUTO_TEST_CASE(deterministic_proofid) { | ||||
CCoinsView coinsDummy; | |||||
CCoinsViewCache coins(&coinsDummy); | |||||
auto key = CKey::MakeCompressedKey(); | auto key = CKey::MakeCompressedKey(); | ||||
const Amount value = 12345 * COIN; | const Amount value = 12345 * COIN; | ||||
const uint32_t height = 10; | const uint32_t height = 10; | ||||
std::vector<COutPoint> outpoints(10); | std::vector<COutPoint> outpoints(10); | ||||
for (size_t i = 0; i < 10; i++) { | for (size_t i = 0; i < 10; i++) { | ||||
outpoints[i] = COutPoint(TxId(InsecureRand256()), InsecureRand32()); | outpoints[i] = COutPoint(TxId(InsecureRand256()), InsecureRand32()); | ||||
Show All 38 Lines |