diff --git a/Cargo.lock b/Cargo.lock index cbd890a479..945bc67f67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ dependencies = [ [[package]] name = "accumulator" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs-ext", @@ -1110,7 +1110,7 @@ dependencies = [ [[package]] name = "bitcoin-move" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "axum 0.7.5", @@ -2705,7 +2705,7 @@ dependencies = [ [[package]] name = "data-verify" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -4073,7 +4073,7 @@ dependencies = [ [[package]] name = "framework-builder" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -4115,7 +4115,7 @@ dependencies = [ [[package]] name = "framework-release" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -4138,7 +4138,7 @@ dependencies = [ [[package]] name = "framework-types" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "clap 4.5.9", @@ -5998,7 +5998,7 @@ dependencies = [ [[package]] name = "metrics" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -6768,7 +6768,7 @@ dependencies = [ [[package]] name = "moveos" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "backtrace", @@ -6821,7 +6821,7 @@ dependencies = [ [[package]] name = "moveos-common" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -6833,7 +6833,7 @@ dependencies = [ [[package]] name = "moveos-compiler" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "move-binary-format", @@ -6847,7 +6847,7 @@ dependencies = [ [[package]] name = "moveos-config" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "clap 4.5.9", @@ -6864,7 +6864,7 @@ dependencies = [ [[package]] name = "moveos-object-runtime" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "better_any", @@ -6901,7 +6901,7 @@ dependencies = [ [[package]] name = "moveos-stdlib" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bech32 0.11.0", @@ -6951,7 +6951,7 @@ dependencies = [ [[package]] name = "moveos-store" -version = "0.6.0" +version = "0.6.1" dependencies = [ "accumulator", "anyhow", @@ -6982,7 +6982,7 @@ dependencies = [ [[package]] name = "moveos-types" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -7011,7 +7011,7 @@ dependencies = [ [[package]] name = "moveos-verifier" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -7038,7 +7038,7 @@ dependencies = [ [[package]] name = "moveos-wasm" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "ciborium", @@ -8692,7 +8692,7 @@ dependencies = [ [[package]] name = "raw-store" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9179,7 +9179,7 @@ dependencies = [ [[package]] name = "rooch" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9261,7 +9261,7 @@ dependencies = [ [[package]] name = "rooch-benchmarks" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9336,14 +9336,14 @@ dependencies = [ [[package]] name = "rooch-common" -version = "0.6.0" +version = "0.6.1" dependencies = [ "libc", ] [[package]] name = "rooch-config" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "clap 4.5.9", @@ -9369,7 +9369,7 @@ dependencies = [ [[package]] name = "rooch-da" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9390,7 +9390,7 @@ dependencies = [ [[package]] name = "rooch-db" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -9417,7 +9417,7 @@ dependencies = [ [[package]] name = "rooch-executor" -version = "0.6.0" +version = "0.6.1" dependencies = [ "accumulator", "anyhow", @@ -9459,7 +9459,7 @@ dependencies = [ [[package]] name = "rooch-faucet" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9492,7 +9492,7 @@ dependencies = [ [[package]] name = "rooch-framework" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -9529,7 +9529,7 @@ dependencies = [ [[package]] name = "rooch-framework-tests" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -9586,7 +9586,7 @@ dependencies = [ [[package]] name = "rooch-genesis" -version = "0.6.0" +version = "0.6.1" dependencies = [ "accumulator", "anyhow", @@ -9640,7 +9640,7 @@ dependencies = [ [[package]] name = "rooch-indexer" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9686,7 +9686,7 @@ dependencies = [ [[package]] name = "rooch-integration-test-runner" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -9731,7 +9731,7 @@ dependencies = [ [[package]] name = "rooch-key" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "argon2", @@ -9763,7 +9763,7 @@ dependencies = [ [[package]] name = "rooch-open-rpc" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -9780,7 +9780,7 @@ dependencies = [ [[package]] name = "rooch-open-rpc-macros" -version = "0.6.0" +version = "0.6.1" dependencies = [ "derive-syn-parse", "itertools 0.13.0", @@ -9792,7 +9792,7 @@ dependencies = [ [[package]] name = "rooch-open-rpc-spec" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -9813,7 +9813,7 @@ dependencies = [ [[package]] name = "rooch-open-rpc-spec-builder" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -9833,7 +9833,7 @@ dependencies = [ [[package]] name = "rooch-pipeline-processor" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9871,7 +9871,7 @@ dependencies = [ [[package]] name = "rooch-proposer" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9904,7 +9904,7 @@ dependencies = [ [[package]] name = "rooch-relayer" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9948,7 +9948,7 @@ dependencies = [ [[package]] name = "rooch-rpc-api" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "async-trait", @@ -9992,7 +9992,7 @@ dependencies = [ [[package]] name = "rooch-rpc-client" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -10022,7 +10022,7 @@ dependencies = [ [[package]] name = "rooch-rpc-server" -version = "0.6.0" +version = "0.6.1" dependencies = [ "accumulator", "anyhow", @@ -10086,7 +10086,7 @@ dependencies = [ [[package]] name = "rooch-sequencer" -version = "0.6.0" +version = "0.6.1" dependencies = [ "accumulator", "anyhow", @@ -10125,7 +10125,7 @@ dependencies = [ [[package]] name = "rooch-store" -version = "0.6.0" +version = "0.6.1" dependencies = [ "accumulator", "anyhow", @@ -10150,7 +10150,7 @@ dependencies = [ [[package]] name = "rooch-test-transaction-builder" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "bcs", @@ -10186,7 +10186,7 @@ dependencies = [ [[package]] name = "rooch-types" -version = "0.6.0" +version = "0.6.1" dependencies = [ "accumulator", "anyhow", @@ -11389,7 +11389,7 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "smt" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "backtrace", @@ -11903,7 +11903,7 @@ dependencies = [ [[package]] name = "testsuite" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "assert_cmd", @@ -12016,7 +12016,7 @@ dependencies = [ [[package]] name = "timeout-join-handler" -version = "0.6.0" +version = "0.6.1" dependencies = [ "anyhow", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 27eea36a54..c29a26082f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,7 +71,7 @@ license = "Apache-2.0" publish = false repository = "https://github.com/rooch-network/rooch" rust-version = "1.78.0" -version = "0.6.0" +version = "0.6.1" [workspace.dependencies] # Internal crate dependencies. diff --git a/crates/rooch-framework-tests/blocks/bitcoin/91842.blob b/crates/rooch-framework-tests/blocks/bitcoin/91842.blob new file mode 100644 index 0000000000..722349a907 Binary files /dev/null and b/crates/rooch-framework-tests/blocks/bitcoin/91842.blob differ diff --git a/crates/rooch-framework-tests/src/tests/bitcoin_test.rs b/crates/rooch-framework-tests/src/tests/bitcoin_test.rs index 3655d8e23c..563402e630 100644 --- a/crates/rooch-framework-tests/src/tests/bitcoin_test.rs +++ b/crates/rooch-framework-tests/src/tests/bitcoin_test.rs @@ -78,24 +78,24 @@ fn test_submit_block() { assert_eq!(now_milliseconds, duration.as_millis() as u64); } -fn test_block_process(height: u64, block: Block) { +fn test_block_process(blocks: Vec<(u64, Block)>) { let mut binding_test = binding_test::RustBindingTest::new().unwrap(); - let block_hash = block.header.block_hash(); - let move_block = rooch_types::bitcoin::types::Block::from(block.clone()); - - binding_test - .execute_l1_block_and_tx(L1BlockWithBody { - block: rooch_types::transaction::L1Block { - chain_id: RoochMultiChainID::Bitcoin.multichain_id(), - block_height: height, - block_hash: block_hash.to_byte_array().to_vec(), - }, - block_body: move_block.encode(), - }) - .unwrap(); - - check_utxo(block.txdata, &binding_test); + for (height, block) in blocks { + let block_hash = block.header.block_hash(); + let move_block = rooch_types::bitcoin::types::Block::from(block.clone()); + binding_test + .execute_l1_block_and_tx(L1BlockWithBody { + block: rooch_types::transaction::L1Block { + chain_id: RoochMultiChainID::Bitcoin.multichain_id(), + block_height: height, + block_hash: block_hash.to_byte_array().to_vec(), + }, + block_body: move_block.encode(), + }) + .unwrap(); + check_utxo(block.txdata, &binding_test); + } } fn check_utxo(txs: Vec, binding_test: &binding_test::RustBindingTest) { @@ -193,21 +193,25 @@ fn test_real_bocks() { return; } let cases = vec![ - (Network::Bitcoin, 91812u64), - (Network::Bitcoin, 818677u64), - (Network::Testnet, 2821527u64), + (Network::Bitcoin, vec![91812u64, 91842u64]), + (Network::Bitcoin, vec![818677u64]), + (Network::Testnet, vec![2821527u64]), ]; - for (network, height) in cases { + for (network, heights) in cases { info!( - "test_real_bocks: network: {:?}, height: {}", - network, height + "test_real_bocks: network: {:?}, height: {:?}", + network, heights ); - let block = load_block(network, height); - test_block_process(height, block); + let blocks = heights + .into_iter() + .map(|height| (height, load_block(network, height))) + .collect(); + test_block_process(blocks); } } // Download the bitcoin block via the following command: // curl -sSL "https://mempool.space/api/block/00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f/raw" > crates/rooch-framework-tests/blocks/bitcoin/91812.blob +// curl -sSL "https://mempool.space/api/block/00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec/raw" > crates/rooch-framework-tests/blocks/bitcoin/91842.blob // curl -sSL "https://mempool.space/api/block/000000000000000000020750f322f4e72e99c2f0b9738fb4f46607860bd18c13/raw" > crates/rooch-framework-tests/blocks/bitcoin/818677.blob // curl -sSL "https://mempool.space/testnet/api/block/0000000016412abe1778a347da773ff8bc087ad1a91ae5daad349bc268285c2d/raw" > crates/rooch-framework-tests/blocks/testnet/2821527.blob pub(crate) const STATIC_BLOCK_DIR: Dir = include_dir!("blocks"); diff --git a/crates/rooch-open-rpc-spec/schemas/openrpc.json b/crates/rooch-open-rpc-spec/schemas/openrpc.json index f12546fc47..a7b224612b 100644 --- a/crates/rooch-open-rpc-spec/schemas/openrpc.json +++ b/crates/rooch-open-rpc-spec/schemas/openrpc.json @@ -12,7 +12,7 @@ "name": "Apache-2.0", "url": "https://raw.githubusercontent.com/rooch-network/rooch/main/LICENSE" }, - "version": "0.6.0" + "version": "0.6.1" }, "methods": [ { diff --git a/crates/rooch-types/src/genesis_config.rs b/crates/rooch-types/src/genesis_config.rs index 224920f037..7e2b6417d2 100644 --- a/crates/rooch-types/src/genesis_config.rs +++ b/crates/rooch-types/src/genesis_config.rs @@ -172,6 +172,6 @@ pub static G_MAIN_CONFIG: Lazy = Lazy::new(|| { ), (ObjectState::new_module_store(), ModuleStore::type_layout()), ], - stdlib_version: StdlibVersion::Version(1), + stdlib_version: StdlibVersion::Version(2), } }); diff --git a/frameworks/bitcoin-move/doc/bitcoin.md b/frameworks/bitcoin-move/doc/bitcoin.md index fac1c5aed3..6556a3a1c1 100644 --- a/frameworks/bitcoin-move/doc/bitcoin.md +++ b/frameworks/bitcoin-move/doc/bitcoin.md @@ -6,6 +6,7 @@ - [Struct `TxProgressErrorLogEvent`](#0x4_bitcoin_TxProgressErrorLogEvent) +- [Struct `RepeatCoinbaseTxEvent`](#0x4_bitcoin_RepeatCoinbaseTxEvent) - [Resource `BitcoinBlockStore`](#0x4_bitcoin_BitcoinBlockStore) - [Constants](#@Constants_0) - [Function `genesis_init`](#0x4_bitcoin_genesis_init) @@ -56,6 +57,17 @@ + + +## Struct `RepeatCoinbaseTxEvent` + + + +
struct RepeatCoinbaseTxEvent has copy, drop
+
+ + + ## Resource `BitcoinBlockStore` @@ -81,6 +93,16 @@ + + +https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki + + +
const BIP_34_HEIGHT: u64 = 227835;
+
+ + + If the process block failed, we need to stop the system and fix the issue diff --git a/frameworks/bitcoin-move/sources/bitcoin.move b/frameworks/bitcoin-move/sources/bitcoin.move index c17d7f3ee9..b192fd4eb6 100644 --- a/frameworks/bitcoin-move/sources/bitcoin.move +++ b/frameworks/bitcoin-move/sources/bitcoin.move @@ -36,12 +36,20 @@ module bitcoin_move::bitcoin{ const ErrorReorgTooDeep:u64 = 3; const ORDINAL_GENESIS_HEIGHT:u64 = 767430; + /// https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki + const BIP_34_HEIGHT:u64 = 227835; struct TxProgressErrorLogEvent has copy, drop{ txid: address, message: String, } + struct RepeatCoinbaseTxEvent has copy, drop{ + txid: address, + vout: u32, + block_height: u64, + } + struct BitcoinBlockStore has key{ /// The genesis start block genesis_block: BlockHeightHash, @@ -109,11 +117,18 @@ module bitcoin_move::bitcoin{ } fun process_coinbase_tx(btc_block_store: &mut BitcoinBlockStore, tx: &Transaction, flotsams: vector, block_height: u64){ - process_coinbase_utxo(tx, flotsams, block_height); + let repeat_txid = process_coinbase_utxo(tx, flotsams, block_height); let txid = types::tx_id(tx); - table::add(&mut btc_block_store.txs, txid, *tx); - table::add(&mut btc_block_store.tx_to_height, txid, block_height); - table_vec::push_back(&mut btc_block_store.tx_ids, txid); + if (repeat_txid) { + table::upsert(&mut btc_block_store.txs, txid, *tx); + table::upsert(&mut btc_block_store.tx_to_height, txid, block_height); + //We append the repeat txid, the developer want to scan the txs, need to handle the repeat txid + table_vec::push_back(&mut btc_block_store.tx_ids, txid); + }else{ + table::add(&mut btc_block_store.txs, txid, *tx); + table::add(&mut btc_block_store.tx_to_height, txid, block_height); + table_vec::push_back(&mut btc_block_store.tx_ids, txid); + } } fun process_utxo(tx: &Transaction, block_height: u64): vector{ @@ -186,13 +201,13 @@ module bitcoin_move::bitcoin{ }; // create new utxo - handle_new_utxo(tx, &mut output_seals); + handle_new_utxo(tx, &mut output_seals, false, block_height); simple_multimap::drop(output_seals); flotsams } - fun process_coinbase_utxo(tx: &Transaction, flotsams: vector, block_height: u64){ + fun process_coinbase_utxo(tx: &Transaction, flotsams: vector, block_height: u64) : bool{ let output_seals = simple_multimap::new(); if(need_process_oridinals(block_height)) { let sat_points = ord::handle_coinbase_tx(tx, flotsams, block_height); @@ -200,8 +215,9 @@ module bitcoin_move::bitcoin{ }; // create new utxo - handle_new_utxo(tx, &mut output_seals); + let repeat_txid = handle_new_utxo(tx, &mut output_seals, true, block_height); simple_multimap::drop(output_seals); + repeat_txid } fun handle_sat_point(sat_points: vector, output_seals: &mut SimpleMultiMap) { @@ -220,15 +236,33 @@ module bitcoin_move::bitcoin{ // output_seals } - fun handle_new_utxo(tx: &Transaction, output_seals: &mut SimpleMultiMap) { + fun handle_new_utxo(tx: &Transaction, output_seals: &mut SimpleMultiMap, is_coinbase: bool, block_height: u64) :bool { let txid = types::tx_id(tx); let txoutput = types::tx_output(tx); let idx = 0; let txoutput_len = vector::length(txoutput); + let repeat_txid = false; while(idx < txoutput_len){ let txout = vector::borrow(txoutput, idx); let vout = (idx as u32); let value = types::txout_value(txout); + if (is_coinbase && ((block_height < BIP_34_HEIGHT && network::is_mainnet()) || !network::is_mainnet())) { + let outpoint = types::new_outpoint(txid, vout); + let utxo_id = utxo::derive_utxo_id(outpoint); + //Before BIP34, some coinbase txid may be reused, we need to remove the old utxo + //https://github.com/rooch-network/rooch/issues/2178 + if (object::exists_object(utxo_id)){ + let utxo = utxo::take(utxo_id); + let seals = utxo::remove(utxo); + simple_multimap::destroy_empty(seals); + event::emit(RepeatCoinbaseTxEvent{ + txid: txid, + vout: vout, + block_height: block_height, + }); + repeat_txid = true; + }; + }; let utxo_obj = utxo::new(txid, vout, value); let utxo = object::borrow_mut(&mut utxo_obj); let seal_index = (idx as u32); @@ -250,6 +284,7 @@ module bitcoin_move::bitcoin{ bind_bitcoin_address(owner_address, bitcoin_address_opt); idx = idx + 1; }; + repeat_txid } diff --git a/frameworks/framework-release/released/2/stdlib b/frameworks/framework-release/released/2/stdlib new file mode 100644 index 0000000000..c1efbe43c2 Binary files /dev/null and b/frameworks/framework-release/released/2/stdlib differ diff --git a/frameworks/moveos-stdlib/sources/object.move b/frameworks/moveos-stdlib/sources/object.move index 74fa7176ff..2f10818318 100644 --- a/frameworks/moveos-stdlib/sources/object.move +++ b/frameworks/moveos-stdlib/sources/object.move @@ -954,6 +954,22 @@ module moveos_std::object { let TestStruct2 { count: _ } = remove(child2); } + #[test] + fun test_child_object_with_same_id_remove_and_add_again(){ + let parent = new(TestParent {}); + let parent_id = id(&parent); + to_shared(parent); + let parent_ref = borrow_mut_object_shared(parent_id); + let id = 1u64; + let child1 = new_with_parent_and_id(parent_ref, id, TestStruct { count: 1 }); + let child_id1 = id(&child1); + let TestStruct { count: _ } = remove(child1); + let child2 = new_with_parent_and_id(parent_ref, id, TestStruct { count: 2 }); + let child_id2 = id(&child2); + assert!(child_id1 == child_id2, 1000); + let TestStruct { count: _ } = remove(child2); + } + #[test_only] fun field_key_derive_test(name: Name, expect_result: address){ let key = derive_field_key(name); diff --git a/moveos/moveos/src/moveos.rs b/moveos/moveos/src/moveos.rs index 2d412552c4..caee92b626 100644 --- a/moveos/moveos/src/moveos.rs +++ b/moveos/moveos/src/moveos.rs @@ -326,7 +326,8 @@ impl MoveOS { need_respawn ); } - if need_respawn { + // If it is a system call, we should not respawn the session. + if !is_system_call && need_respawn { let mut s = session.respawn(system_env); //Because the session is respawned, the pre_execute function should be called again. s.execute_function_call(self.system_pre_execute_functions.clone(), false) diff --git a/sdk/typescript/rooch-sdk/src/version.ts b/sdk/typescript/rooch-sdk/src/version.ts index a072b1d4ab..727fe83be0 100644 --- a/sdk/typescript/rooch-sdk/src/version.ts +++ b/sdk/typescript/rooch-sdk/src/version.ts @@ -3,5 +3,5 @@ // This file is generated by genversion.mjs. Do not edit it directly. -export const PACKAGE_VERSION = '0.2.1' -export const TARGETED_RPC_VERSION = '0.6.0' +export const PACKAGE_VERSION = '0.2.2' +export const TARGETED_RPC_VERSION = '0.6.1'