Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc-schnorrmultisig-activation.py
Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
# the upgrade activation time, which we artificially set far into the future | # the upgrade activation time, which we artificially set far into the future | ||||
GRAVITON_START_TIME = 2000000000 | GRAVITON_START_TIME = 2000000000 | ||||
# If we don't do this, autoreplay protection will activate before graviton and | # If we don't do this, autoreplay protection will activate before graviton and | ||||
# all our sigs will mysteriously fail. | # all our sigs will mysteriously fail. | ||||
REPLAY_PROTECTION_START_TIME = GRAVITON_START_TIME * 2 | REPLAY_PROTECTION_START_TIME = GRAVITON_START_TIME * 2 | ||||
# Before the upgrade, Schnorr checkmultisig is rejected but forgiven if it | # Before the upgrade, Schnorr checkmultisig is rejected. | ||||
# would have been valid after the upgrade. | |||||
PREUPGRADE_SCHNORR_MULTISIG_ERROR = 'mandatory-script-verify-flag-failed (Signature cannot be 65 bytes in CHECKMULTISIG)' | PREUPGRADE_SCHNORR_MULTISIG_ERROR = 'mandatory-script-verify-flag-failed (Signature cannot be 65 bytes in CHECKMULTISIG)' | ||||
# Before the upgrade, ECDSA checkmultisig with non-null dummy are rejected with | |||||
# a non-mandatory error. | |||||
PREUPGRADE_ECDSA_NULLDUMMY_ERROR = 'non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)' | |||||
# After the upgrade, ECDSA checkmultisig with non-null dummy are invalid since | # After the upgrade, ECDSA checkmultisig with non-null dummy are invalid since | ||||
# the new mode refuses ECDSA, but still do not result in ban. | # the new mode refuses ECDSA. | ||||
POSTUPGRADE_ECDSA_NULLDUMMY_ERROR = 'mandatory-script-verify-flag-failed (Only Schnorr signatures allowed in this operation)' | POSTUPGRADE_ECDSA_NULLDUMMY_ERROR = 'mandatory-script-verify-flag-failed (Only Schnorr signatures allowed in this operation)' | ||||
# A mandatory (bannable) error occurs when people pass Schnorr signatures into | # A mandatory (bannable) error occurs when people pass Schnorr signatures into | ||||
# legacy OP_CHECKMULTISIG; this is the case on both sides of the upgrade. | # legacy OP_CHECKMULTISIG; this is the case on both sides of the upgrade. | ||||
SCHNORR_LEGACY_MULTISIG_ERROR = 'mandatory-script-verify-flag-failed (Signature cannot be 65 bytes in CHECKMULTISIG)' | SCHNORR_LEGACY_MULTISIG_ERROR = 'mandatory-script-verify-flag-failed (Signature cannot be 65 bytes in CHECKMULTISIG)' | ||||
# Blocks with invalid scripts give this error: | # Blocks with invalid scripts give this error: | ||||
BADINPUTS_ERROR = 'blk-bad-inputs' | BADINPUTS_ERROR = 'blk-bad-inputs' | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
txspend.rehash() | txspend.rehash() | ||||
return txspend | return txspend | ||||
# two of these transactions, which are valid both before and after upgrade. | # two of these transactions, which are valid both before and after upgrade. | ||||
ecdsa0tx = create_fund_and_spend_tx(OP_0, 'ecdsa') | ecdsa0tx = create_fund_and_spend_tx(OP_0, 'ecdsa') | ||||
ecdsa0tx_2 = create_fund_and_spend_tx(OP_0, 'ecdsa') | ecdsa0tx_2 = create_fund_and_spend_tx(OP_0, 'ecdsa') | ||||
# two of these, which are nonstandard before upgrade and invalid after. | # two of these, which are valid before upgrade and invalid after. | ||||
ecdsa1tx = create_fund_and_spend_tx(OP_1, 'ecdsa') | ecdsa1tx = create_fund_and_spend_tx(OP_1, 'ecdsa') | ||||
ecdsa1tx_2 = create_fund_and_spend_tx(OP_1, 'ecdsa') | ecdsa1tx_2 = create_fund_and_spend_tx(OP_1, 'ecdsa') | ||||
# this one is always invalid. | # this one is always invalid. | ||||
schnorr0tx = create_fund_and_spend_tx(OP_0, 'schnorr') | schnorr0tx = create_fund_and_spend_tx(OP_0, 'schnorr') | ||||
# this one is only going to be valid after the upgrade. | # this one is only going to be valid after the upgrade. | ||||
schnorr1tx = create_fund_and_spend_tx(OP_1, 'schnorr') | schnorr1tx = create_fund_and_spend_tx(OP_1, 'schnorr') | ||||
tip = self.build_block(tip, fundings) | tip = self.build_block(tip, fundings) | ||||
node.p2p.send_blocks_and_test([tip], node) | node.p2p.send_blocks_and_test([tip], node) | ||||
self.log.info("Start preupgrade tests") | self.log.info("Start preupgrade tests") | ||||
self.log.info("Sending rejected transactions via RPC") | self.log.info("Sending rejected transactions via RPC") | ||||
assert_raises_rpc_error(-26, PREUPGRADE_ECDSA_NULLDUMMY_ERROR, | |||||
node.sendrawtransaction, ToHex(ecdsa1tx)) | |||||
assert_raises_rpc_error(-26, SCHNORR_LEGACY_MULTISIG_ERROR, | assert_raises_rpc_error(-26, SCHNORR_LEGACY_MULTISIG_ERROR, | ||||
node.sendrawtransaction, ToHex(schnorr0tx)) | node.sendrawtransaction, ToHex(schnorr0tx)) | ||||
assert_raises_rpc_error(-26, PREUPGRADE_SCHNORR_MULTISIG_ERROR, | assert_raises_rpc_error(-26, PREUPGRADE_SCHNORR_MULTISIG_ERROR, | ||||
node.sendrawtransaction, ToHex(schnorr1tx)) | node.sendrawtransaction, ToHex(schnorr1tx)) | ||||
self.log.info( | self.log.info( | ||||
"Sending rejected transactions via net (banning depending on situation)") | "Sending rejected transactions via net (bannable)") | ||||
self.check_for_no_ban_on_rejected_tx( | |||||
ecdsa1tx, PREUPGRADE_ECDSA_NULLDUMMY_ERROR) | |||||
self.check_for_ban_on_rejected_tx( | self.check_for_ban_on_rejected_tx( | ||||
schnorr0tx, SCHNORR_LEGACY_MULTISIG_ERROR) | schnorr0tx, SCHNORR_LEGACY_MULTISIG_ERROR) | ||||
self.check_for_ban_on_rejected_tx( | self.check_for_ban_on_rejected_tx( | ||||
schnorr1tx, PREUPGRADE_SCHNORR_MULTISIG_ERROR) | schnorr1tx, PREUPGRADE_SCHNORR_MULTISIG_ERROR) | ||||
self.log.info( | self.log.info( | ||||
"Sending invalid transactions in blocks (and get banned!)") | "Sending invalid transactions in blocks (and get banned!)") | ||||
self.check_for_ban_on_rejected_block( | self.check_for_ban_on_rejected_block( | ||||
Show All 31 Lines | def run_test(self): | ||||
"Send a lecacy ECDSA multisig into mempool, we will check after upgrade to make sure it didn't get cleaned out unnecessarily.") | "Send a lecacy ECDSA multisig into mempool, we will check after upgrade to make sure it didn't get cleaned out unnecessarily.") | ||||
node.p2p.send_txs_and_test([ecdsa0tx_2], node) | node.p2p.send_txs_and_test([ecdsa0tx_2], node) | ||||
assert_equal(node.getrawmempool(), [ecdsa0tx_2.hash]) | assert_equal(node.getrawmempool(), [ecdsa0tx_2.hash]) | ||||
# save this tip for later | # save this tip for later | ||||
preupgrade_block = tip | preupgrade_block = tip | ||||
self.log.info( | self.log.info( | ||||
"Mine the activation block itself, including a legacy nulldummy violation at the last possible moment") | "Mine the activation block itself, including a non-null-dummy ECDSA at the last possible moment") | ||||
node.p2p.send_txs_and_test([ecdsa1tx], node) | |||||
tip = self.build_block(tip, [ecdsa1tx]) | tip = self.build_block(tip, [ecdsa1tx]) | ||||
node.p2p.send_blocks_and_test([tip], node) | node.p2p.send_blocks_and_test([tip], node) | ||||
self.log.info("We have activated!") | self.log.info("We have activated!") | ||||
assert_equal(node.getblockchaininfo()[ | assert_equal(node.getblockchaininfo()[ | ||||
'mediantime'], GRAVITON_START_TIME) | 'mediantime'], GRAVITON_START_TIME) | ||||
assert_equal(node.getrawmempool(), [ecdsa0tx_2.hash]) | assert_equal(node.getrawmempool(), [ecdsa0tx_2.hash]) | ||||
# save this tip for later | # save this tip for later | ||||
upgrade_block = tip | upgrade_block = tip | ||||
self.log.info( | self.log.info( | ||||
"Trying to mine a legacy nulldummy violation, but we are just barely too late") | "Trying to mine a non-null-dummy ECDSA, but we are just barely too late") | ||||
self.check_for_ban_on_rejected_block( | self.check_for_ban_on_rejected_block( | ||||
self.build_block(tip, [ecdsa1tx_2]), BADINPUTS_ERROR) | self.build_block(tip, [ecdsa1tx_2]), BADINPUTS_ERROR) | ||||
self.log.info( | self.log.info( | ||||
"If we try to submit it by mempool or RPC, the error code has changed and we are banned") | "If we try to submit it by mempool or RPC, it is rejected and we are banned") | ||||
assert_raises_rpc_error(-26, POSTUPGRADE_ECDSA_NULLDUMMY_ERROR, | assert_raises_rpc_error(-26, POSTUPGRADE_ECDSA_NULLDUMMY_ERROR, | ||||
node.sendrawtransaction, ToHex(ecdsa1tx_2)) | node.sendrawtransaction, ToHex(ecdsa1tx_2)) | ||||
self.check_for_ban_on_rejected_tx( | self.check_for_ban_on_rejected_tx( | ||||
ecdsa1tx_2, POSTUPGRADE_ECDSA_NULLDUMMY_ERROR) | ecdsa1tx_2, POSTUPGRADE_ECDSA_NULLDUMMY_ERROR) | ||||
self.log.info( | self.log.info( | ||||
"Submitting a new Schnorr-multisig via net, and mining it in a block") | "Submitting a new Schnorr-multisig via net, and mining it in a block") | ||||
node.p2p.send_txs_and_test([schnorr1tx], node) | node.p2p.send_txs_and_test([schnorr1tx], node) | ||||
Show All 24 Lines | def run_test(self): | ||||
self.log.info( | self.log.info( | ||||
"Invalidating the post-upgrade blocks returns the transactions to mempool") | "Invalidating the post-upgrade blocks returns the transactions to mempool") | ||||
node.invalidateblock(postupgrade_block.hash) | node.invalidateblock(postupgrade_block.hash) | ||||
assert_equal(set(node.getrawmempool()), { | assert_equal(set(node.getrawmempool()), { | ||||
ecdsa0tx_2.hash, schnorr1tx.hash}) | ecdsa0tx_2.hash, schnorr1tx.hash}) | ||||
self.log.info( | self.log.info( | ||||
"Invalidating the upgrade block evicts the transactions valid only after upgrade") | "Invalidating the upgrade block evicts the transactions valid only after upgrade") | ||||
node.invalidateblock(upgrade_block.hash) | node.invalidateblock(upgrade_block.hash) | ||||
assert_equal(set(node.getrawmempool()), {ecdsa0tx_2.hash}) | assert_equal(set(node.getrawmempool()), { | ||||
ecdsa0tx_2.hash, ecdsa1tx.hash}) | |||||
self.log.info("Return to our tip") | self.log.info("Return to our tip") | ||||
node.reconsiderblock(upgrade_block.hash) | node.reconsiderblock(upgrade_block.hash) | ||||
node.reconsiderblock(postupgrade_block.hash) | node.reconsiderblock(postupgrade_block.hash) | ||||
assert_equal(node.getbestblockhash(), tip.hash) | assert_equal(node.getbestblockhash(), tip.hash) | ||||
assert_equal(node.getrawmempool(), []) | assert_equal(node.getrawmempool(), []) | ||||
self.log.info( | self.log.info( | ||||
Show All 19 Lines |