Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc-schnorrmultisig-activation.py
Show First 20 Lines • Show All 209 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 valid before upgrade and invalid after. | # two of these, which are nonstandard 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, SCHNORR_LEGACY_MULTISIG_ERROR, | assert_raises_rpc_error(-26, SCHNORR_LEGACY_MULTISIG_ERROR, | ||||
node.sendrawtransaction, ToHex(schnorr0tx)) | node.sendrawtransaction, ToHex(schnorr0tx)) | ||||
# Since MULTISIG_SCHNORR is in mandatory flags, we are not accepting | |||||
# non-null-dummy ECDSA transactions before the upgrade. We get a | |||||
# post-upgrade error since the mempool is using post-upgrade flags. | |||||
assert_raises_rpc_error(-26, POSTUPGRADE_ECDSA_NULLDUMMY_ERROR, | |||||
node.sendrawtransaction, ToHex(ecdsa1tx)) | |||||
# The Schnorr multisig almost gets accepted here but it finally gets | |||||
# caught in the block flags check. Note that "BUG! PLEASE REPORT | |||||
# THIS!" will appear in the log, since AcceptToMemoryPoolWorker expects | |||||
# that scriptVerifyFlags is more strict than nextBlockScriptVerifyFlags. | |||||
# For strictly subtractive ('soft forking') flags, it is fine if they | |||||
# are always part of scriptVerifyFlags and only sometimes appear in | |||||
# nextBlockScriptVerifyFlags, but for additive flags this kind of | |||||
# strange situation can be created. | |||||
# In practice, only new nodes will ever be in a pre-upgrade state, | |||||
# and they will also be in initial block download mode and hence | |||||
# not request transactions from peers. So, this weird log message | |||||
# could only be triggered by unsolicited submission of a tx, and | |||||
# it would be benign since the node is behaving correctly by rejecting | |||||
# the transaction (as tested here). | |||||
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 (bannable)") | "Sending rejected transactions via net (bannable)") | ||||
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( | ||||
ecdsa1tx, POSTUPGRADE_ECDSA_NULLDUMMY_ERROR) | |||||
# If we are sent unsolicited post-upgrade transactions while before | |||||
# the upgrade block, the tx is to be rejected. | |||||
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( | ||||
self.build_block(tip, [schnorr0tx]), BADINPUTS_ERROR) | self.build_block(tip, [schnorr0tx]), BADINPUTS_ERROR) | ||||
self.check_for_ban_on_rejected_block( | self.check_for_ban_on_rejected_block( | ||||
self.build_block(tip, [schnorr1tx]), BADINPUTS_ERROR) | self.build_block(tip, [schnorr1tx]), BADINPUTS_ERROR) | ||||
Show All 29 Lines | def run_test(self): | ||||
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 non-null-dummy ECDSA 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]) | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
"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()), { | assert_equal(set(node.getrawmempool()), { | ||||
ecdsa0tx_2.hash, ecdsa1tx.hash}) | ecdsa0tx_2.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 |