Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251# BIP113 test transaction will be modified before each use to put in appropriate block time252bip113tx_v1 = self.create_self_transfer_from_utxo(bip113input)253bip113tx_v1.vin[0].nSequence = 0xFFFFFFFE254bip113tx_v1.version = 1255bip113tx_v2 = self.create_self_transfer_from_utxo(bip113input)256bip113tx_v2.vin[0].nSequence = 0xFFFFFFFE257bip113tx_v2.version = 2259# For BIP68 test all 16 relative sequence locktimes260bip68txs_v1 = self.create_bip68txs(bip68inputs, 1)261bip68txs_v2 = self.create_bip68txs(bip68inputs, 2)263# For BIP112 test:264# 16 relative sequence locktimes of 10 against 10 OP_CSV OP_DROP inputs265bip112txs_vary_nSequence_v1 = self.create_bip112txs(bip112basicinputs[0], False, 1)266bip112txs_vary_nSequence_v2 = self.create_bip112txs(bip112basicinputs[0], False, 2)267# 16 relative sequence locktimes of 9 against 10 OP_CSV OP_DROP inputs268bip112txs_vary_nSequence_9_v1 = self.create_bip112txs(bip112basicinputs[1], False, 1, -1)269bip112txs_vary_nSequence_9_v2 = self.create_bip112txs(bip112basicinputs[1], False, 2, -1)270# sequence lock time of 10 against 16 (relative_lock_time) OP_CSV OP_DROP inputs271bip112txs_vary_OP_CSV_v1 = self.create_bip112txs(bip112diverseinputs[0], True, 1)272bip112txs_vary_OP_CSV_v2 = self.create_bip112txs(bip112diverseinputs[0], True, 2)273# sequence lock time of 9 against 16 (relative_lock_time) OP_CSV OP_DROP inputs274bip112txs_vary_OP_CSV_9_v1 = self.create_bip112txs(bip112diverseinputs[1], True, 1, -1)275bip112txs_vary_OP_CSV_9_v2 = self.create_bip112txs(bip112diverseinputs[1], True, 2, -1)276# -1 OP_CSV OP_DROP input277bip112tx_special_v1 = self.create_bip112special(bip112specialinput, 1)278bip112tx_special_v2 = self.create_bip112special(bip112specialinput, 2)279# (empty stack) OP_CSV input280bip112tx_emptystack_v1 = self.create_bip112emptystack(bip112emptystackinput, 1)281bip112tx_emptystack_v2 = self.create_bip112emptystack(bip112emptystackinput, 2)283self.log.info("TESTING")285self.log.info("Pre-Soft Fork Tests. All txs should pass.")286self.log.info("Test version 1 txs")288success_txs = []289# BIP113 tx, -1 CSV tx and empty stack CSV tx should succeed290bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block291self.miniwallet.sign_tx(bip113tx_v1)292success_txs.append(bip113tx_v1)293success_txs.append(bip112tx_special_v1)294success_txs.append(bip112tx_emptystack_v1)295# add BIP 68 txs296success_txs.extend(all_rlt_txs(bip68txs_v1))297# add BIP 112 with seq=10 txs298success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1))299success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v1))300# try BIP 112 with seq=9 txs301success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1))302success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v1))303self.send_blocks([self.create_test_block(success_txs)])304self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())306self.log.info("Test version 2 txs")308success_txs = []309# BIP113 tx, -1 CSV tx and empty stack CSV tx should succeed310bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block311self.miniwallet.sign_tx(bip113tx_v2)312success_txs.append(bip113tx_v2)313success_txs.append(bip112tx_special_v2)314success_txs.append(bip112tx_emptystack_v2)315# add BIP 68 txs316success_txs.extend(all_rlt_txs(bip68txs_v2))317# add BIP 112 with seq=10 txs318success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v2))319success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v2))320# try BIP 112 with seq=9 txs321success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2))322success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v2))323self.send_blocks([self.create_test_block(success_txs)])324self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())326# 1 more version 4 block to get us to height 432 so the fork should now be active for the next block327assert not softfork_active(self.nodes[0], 'csv')328test_blocks = self.generate_blocks(1)329self.send_blocks(test_blocks)330assert softfork_active(self.nodes[0], 'csv')332self.log.info("Post-Soft Fork Tests.")334self.log.info("BIP 113 tests")335# BIP 113 tests should now fail regardless of version number if nLockTime isn't satisfied by new rules336bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block337self.miniwallet.sign_tx(bip113tx_v1)338bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block339self.miniwallet.sign_tx(bip113tx_v2)340for bip113tx in [bip113tx_v1, bip113tx_v2]:341self.send_blocks([self.create_test_block([bip113tx])], success=False, reject_reason='bad-txns-nonfinal')343# BIP 113 tests should now pass if the locktime is < MTP344bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block345self.miniwallet.sign_tx(bip113tx_v1)346bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block347self.miniwallet.sign_tx(bip113tx_v2)348for bip113tx in [bip113tx_v1, bip113tx_v2]:349self.send_blocks([self.create_test_block([bip113tx])])350self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())352# Next block height = 437 after 4 blocks of random version353test_blocks = self.generate_blocks(4)354self.send_blocks(test_blocks)356self.log.info("BIP 68 tests")357self.log.info("Test version 1 txs - all should still pass")359success_txs = []360success_txs.extend(all_rlt_txs(bip68txs_v1))361self.send_blocks([self.create_test_block(success_txs)])362self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())364self.log.info("Test version 2 txs")366# All txs with SEQUENCE_LOCKTIME_DISABLE_FLAG set pass367bip68success_txs = [tx['tx'] for tx in bip68txs_v2 if tx['sdf']]368self.send_blocks([self.create_test_block(bip68success_txs)])369self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())371# All txs without flag fail as we are at delta height = 8 < 10 and delta time = 8 * 600 < 10 * 512372bip68timetxs = [tx['tx'] for tx in bip68txs_v2 if not tx['sdf'] and tx['stf']]373for tx in bip68timetxs:374self.send_blocks([self.create_test_block([tx])], success=False, reject_reason='bad-txns-nonfinal')376bip68heighttxs = [tx['tx'] for tx in bip68txs_v2 if not tx['sdf'] and not tx['stf']]377for tx in bip68heighttxs:378self.send_blocks([self.create_test_block([tx])], success=False, reject_reason='bad-txns-nonfinal')380# Advance one block to 438381test_blocks = self.generate_blocks(1)382self.send_blocks(test_blocks)384# Height txs should fail and time txs should now pass 9 * 600 > 10 * 512385bip68success_txs.extend(bip68timetxs)386self.send_blocks([self.create_test_block(bip68success_txs)])387self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())388for tx in bip68heighttxs:389self.send_blocks([self.create_test_block([tx])], success=False, reject_reason='bad-txns-nonfinal')391# Advance one block to 439392test_blocks = self.generate_blocks(1)393self.send_blocks(test_blocks)395# All BIP 68 txs should pass396bip68success_txs.extend(bip68heighttxs)397self.send_blocks([self.create_test_block(bip68success_txs)])398self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())400self.log.info("BIP 112 tests")401self.log.info("Test version 1 txs")403# -1 OP_CSV tx and (empty stack) OP_CSV tx should fail404self.send_blocks([self.create_test_block([bip112tx_special_v1])], success=False,405reject_reason='block-script-verify-flag-failed (Negative locktime)')406self.send_blocks([self.create_test_block([bip112tx_emptystack_v1])], success=False,407reject_reason='block-script-verify-flag-failed (Operation not valid with the current stack size)')408# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 1 txs should still pass410success_txs = [tx['tx'] for tx in bip112txs_vary_OP_CSV_v1 if tx['sdf']]411success_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_9_v1 if tx['sdf']]412self.send_blocks([self.create_test_block(success_txs)])413self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())415# If SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV, version 1 txs should now fail416fail_txs = all_rlt_txs(bip112txs_vary_nSequence_v1)417fail_txs += all_rlt_txs(bip112txs_vary_nSequence_9_v1)418fail_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_v1 if not tx['sdf']]419fail_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_9_v1 if not tx['sdf']]420for tx in fail_txs:421self.send_blocks([self.create_test_block([tx])], success=False,422reject_reason='block-script-verify-flag-failed (Locktime requirement not satisfied)')424self.log.info("Test version 2 txs")426# -1 OP_CSV tx and (empty stack) OP_CSV tx should fail427self.send_blocks([self.create_test_block([bip112tx_special_v2])], success=False,428reject_reason='block-script-verify-flag-failed (Negative locktime)')429self.send_blocks([self.create_test_block([bip112tx_emptystack_v2])], success=False,430reject_reason='block-script-verify-flag-failed (Operation not valid with the current stack size)')432# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 2 txs should pass (all sequence locks are met)433success_txs = [tx['tx'] for tx in bip112txs_vary_OP_CSV_v2 if tx['sdf']]434success_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_9_v2 if tx['sdf']]436self.send_blocks([self.create_test_block(success_txs)])437self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())439# SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV for all remaining txs ##441# All txs with nSequence 9 should fail either due to earlier mismatch or failing the CSV check442fail_txs = all_rlt_txs(bip112txs_vary_nSequence_9_v2)443fail_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_9_v2 if not tx['sdf']]444for tx in fail_txs:445self.send_blocks([self.create_test_block([tx])], success=False,446reject_reason='block-script-verify-flag-failed (Locktime requirement not satisfied)')448# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in nSequence, tx should fail449fail_txs = [tx['tx'] for tx in bip112txs_vary_nSequence_v2 if tx['sdf']]450for tx in fail_txs:451self.send_blocks([self.create_test_block([tx])], success=False,452reject_reason='block-script-verify-flag-failed (Locktime requirement not satisfied)')454# If sequencelock types mismatch, tx should fail455fail_txs = [tx['tx'] for tx in bip112txs_vary_nSequence_v2 if not tx['sdf'] and tx['stf']]456fail_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_v2 if not tx['sdf'] and tx['stf']]457for tx in fail_txs:458self.send_blocks([self.create_test_block([tx])], success=False,459reject_reason='block-script-verify-flag-failed (Locktime requirement not satisfied)')461# Remaining txs should pass, just test masking works properly462success_txs = [tx['tx'] for tx in bip112txs_vary_nSequence_v2 if not tx['sdf'] and not tx['stf']]463success_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_v2 if not tx['sdf'] and not tx['stf']]464self.send_blocks([self.create_test_block(success_txs)])465self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())467# Additional test, of checking that comparison of two time types works properly468time_txs = []469for tx in [tx['tx'] for tx in bip112txs_vary_OP_CSV_v2 if not tx['sdf'] and tx['stf']]:470tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME | SEQ_TYPE_FLAG471self.miniwallet.sign_tx(tx)472time_txs.append(tx)474self.send_blocks([self.create_test_block(time_txs)])475self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())478if __name__ == '__main__':479BIP68_112_113Test(__file__).main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.