diff --git a/c/polyjuice.h b/c/polyjuice.h index f1d9be6e..17124708 100644 --- a/c/polyjuice.h +++ b/c/polyjuice.h @@ -1020,8 +1020,37 @@ int handle_transfer(gw_context_t* ctx, return 0; } +int load_eth_eoa_type_hash(gw_context_t* ctx, uint8_t eoa_type_hash[GW_KEY_BYTES]) { + mol_seg_t rollup_config_seg; + rollup_config_seg.ptr = ctx->rollup_config; + rollup_config_seg.size = ctx->rollup_config_size; + + mol_seg_t allowed_eoa_list_seg = + MolReader_RollupConfig_get_allowed_eoa_type_hashes(&rollup_config_seg); + uint32_t len = MolReader_AllowedTypeHashVec_length(&allowed_eoa_list_seg); + for (uint32_t i = 0; i < len; i++) { + mol_seg_res_t allowed_type_hash_res = + MolReader_AllowedTypeHashVec_get(&allowed_eoa_list_seg, i); + + if (!is_errno_ok(&allowed_type_hash_res)) { + return GW_FATAL_INVALID_DATA; + } + mol_seg_t type_seg = + MolReader_AllowedTypeHash_get_type_(&allowed_type_hash_res.seg); + if (*(uint8_t *)type_seg.ptr == GW_ALLOWED_EOA_ETH) { + mol_seg_t eth_lock_code_hash_seg = + MolReader_AllowedTypeHash_get_hash(&allowed_type_hash_res.seg); + memcpy(eoa_type_hash, eth_lock_code_hash_seg.ptr, 32); + return 0; + } + } + ckb_debug("Cannot find EoA type hash of ETH."); + return FATAL_POLYJUICE; + } + int handle_native_token_transfer(gw_context_t* ctx, uint32_t from_id, - uint256_t value, gw_reg_addr_t* from_addr) { + uint256_t value, gw_reg_addr_t* from_addr, + uint64_t* gas_used) { if (g_creator_account_id == UINT32_MAX) { ckb_debug("[handle_native_token_transfer] g_creator_account_id wasn't set."); return ERROR_NATIVE_TOKEN_TRANSFER; @@ -1066,7 +1095,48 @@ int handle_native_token_transfer(gw_context_t* ctx, uint32_t from_id, ckb_debug("[handle_native_token_transfer] to_address is a contract"); return ERROR_NATIVE_TOKEN_TRANSFER; } - } else if (ret != GW_ERROR_NOT_FOUND && ret != 0) { + } else if (ret == GW_ERROR_NOT_FOUND) { + ckb_debug("[handle_native_token_transfer] create new EoA account"); + //build eoa script + uint8_t eoa_type_hash[GW_KEY_BYTES] = {0}; + ret = load_eth_eoa_type_hash(ctx, eoa_type_hash); + if (ret != 0) { + return ret; + } + // EOA script args len: 32 + 20 + int eoa_script_args_len = 32 + 20; + uint8_t script_args[eoa_script_args_len]; + memcpy(script_args, g_rollup_script_hash, 32); + memcpy(script_args + 32, g_eoa_transfer_to_address.bytes, 20); + mol_seg_t new_script_seg; + ret = build_script(eoa_type_hash, g_script_hash_type, script_args, + eoa_script_args_len, &new_script_seg); + if (ret != 0) { + return ret; + } + uint32_t new_account_id; + ret = ctx->sys_create(ctx, new_script_seg.ptr, new_script_seg.size, + &new_account_id); + if (ret != 0) { + ckb_debug("[handle_native_token_transfer] create new account failed."); + return ret; + } + uint8_t account_script_hash[32] = {0}; + ret = ctx->sys_get_script_hash_by_account_id(ctx, new_account_id, + account_script_hash); + if (ret != 0) { + ckb_debug("[handle_native_token_transfer] failed to get created eth account script hash"); + return ret; + } + + ret = gw_register_eth_address(ctx, account_script_hash); + if (ret != 0) { + ckb_debug("[handle_native_token_transfer] failed to register eth address"); + return ret; + } + // charge gas for new account + *gas_used += NEW_ACCOUNT_GAS; + } else { return ret; } @@ -1484,14 +1554,16 @@ int run_polyjuice() { for (int i = 0; i < 32; i++) { value_ptr[i] = msg.value.bytes[31 - i]; } + + uint64_t gas_used = min_gas; gw_reg_addr_t from_addr = {0}; // handle error later int transfer_ret = handle_native_token_transfer(&context, context.transaction_context.from_id, - value, &from_addr); + value, &from_addr, &gas_used); ckb_debug("END handle_native_token_transfer"); // handle fee - uint256_t gas_fee = calculate_fee(g_gas_price, min_gas); - debug_print_int("[handle_native_token_transfer] gas_used", min_gas); + uint256_t gas_fee = calculate_fee(g_gas_price, gas_used); + debug_print_int("[handle_native_token_transfer] gas_used", gas_used); ret = sudt_pay_fee(&context, g_sudt_id, from_addr, gas_fee); // handle native token transfer error if (ret != 0) { diff --git a/c/polyjuice_globals.h b/c/polyjuice_globals.h index e97cbb4f..32b2322c 100644 --- a/c/polyjuice_globals.h +++ b/c/polyjuice_globals.h @@ -55,5 +55,7 @@ static evmc_address g_eoa_transfer_to_address = {0}; #define DATA_NONE_ZERO_TX_GAS 16 /* Gas per byte of data attached to a transaction */ #define DATA_ZERO_TX_GAS 4 +/* Gas of new account creation*/ +#define NEW_ACCOUNT_GAS 25000 #endif // POLYJUICE_GLOBALS_H diff --git a/polyjuice-tests/Cargo.lock b/polyjuice-tests/Cargo.lock index 466cc72a..9df33b80 100644 --- a/polyjuice-tests/Cargo.lock +++ b/polyjuice-tests/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "ahash" version = "0.7.6" @@ -113,21 +98,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.13.0" @@ -287,19 +257,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "serde", - "winapi", -] - [[package]] name = "ckb-channel" version = "0.104.0" @@ -576,16 +533,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" -[[package]] -name = "debugid" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ee87af31d84ef885378aebca32be3d682b0e0dc119d5b4860a2c5bb5046730" -dependencies = [ - "serde", - "uuid", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -888,12 +835,6 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] -[[package]] -name = "gimli" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" - [[package]] name = "glob" version = "0.3.0" @@ -924,7 +865,7 @@ dependencies = [ [[package]] name = "gw-ckb-hardfork" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "arc-swap", "ckb-types", @@ -934,7 +875,7 @@ dependencies = [ [[package]] name = "gw-common" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "cfg-if 0.1.10", "gw-hash", @@ -946,7 +887,7 @@ dependencies = [ [[package]] name = "gw-config" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "ckb-fixed-hash", "gw-jsonrpc-types", @@ -956,7 +897,7 @@ dependencies = [ [[package]] name = "gw-db" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "ckb-rocksdb", "gw-config", @@ -969,7 +910,7 @@ dependencies = [ [[package]] name = "gw-generator" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "anyhow", "arc-swap", @@ -988,7 +929,6 @@ dependencies = [ "log", "rlp", "secp256k1 0.20.3", - "sentry", "sha3", "thiserror", "tokio", @@ -997,14 +937,14 @@ dependencies = [ [[package]] name = "gw-hash" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "blake2b-ref 0.3.1", ] [[package]] name = "gw-jsonrpc-types" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "anyhow", "ckb-fixed-hash", @@ -1017,7 +957,7 @@ dependencies = [ [[package]] name = "gw-rpc-client" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "anyhow", "arc-swap", @@ -1050,7 +990,7 @@ dependencies = [ [[package]] name = "gw-store" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "anyhow", "arc-swap", @@ -1066,7 +1006,7 @@ dependencies = [ [[package]] name = "gw-traits" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "gw-common", "gw-db", @@ -1075,7 +1015,7 @@ dependencies = [ [[package]] name = "gw-types" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "cfg-if 0.1.10", "ckb-fixed-hash", @@ -1088,7 +1028,7 @@ dependencies = [ [[package]] name = "gw-utils" -version = "1.5.0-rc2" +version = "1.5.0" dependencies = [ "anyhow", "ckb-crypto", @@ -1162,17 +1102,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - [[package]] name = "http" version = "0.2.8" @@ -1425,12 +1354,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "matches" version = "0.1.9" @@ -1464,15 +1387,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" -dependencies = [ - "adler", -] - [[package]] name = "mio" version = "0.8.3" @@ -1524,25 +1438,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - [[package]] name = "num_cpus" version = "1.13.1" @@ -1599,15 +1494,6 @@ dependencies = [ "syn", ] -[[package]] -name = "object" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.12.0" @@ -1994,12 +1880,6 @@ dependencies = [ "ordered-multimap", ] -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -2113,81 +1993,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" -[[package]] -name = "sentry" -version = "0.23.0" -source = "git+https://github.com/getsentry/sentry-rust?rev=df694a49595d6890c510d80b85cfbb4b5ae6159a#df694a49595d6890c510d80b85cfbb4b5ae6159a" -dependencies = [ - "httpdate", - "reqwest", - "sentry-backtrace", - "sentry-contexts", - "sentry-core", - "sentry-panic", - "tokio", -] - -[[package]] -name = "sentry-backtrace" -version = "0.23.0" -source = "git+https://github.com/getsentry/sentry-rust?rev=df694a49595d6890c510d80b85cfbb4b5ae6159a#df694a49595d6890c510d80b85cfbb4b5ae6159a" -dependencies = [ - "backtrace", - "lazy_static", - "regex", - "sentry-core", -] - -[[package]] -name = "sentry-contexts" -version = "0.23.0" -source = "git+https://github.com/getsentry/sentry-rust?rev=df694a49595d6890c510d80b85cfbb4b5ae6159a#df694a49595d6890c510d80b85cfbb4b5ae6159a" -dependencies = [ - "hostname", - "libc", - "rustc_version", - "sentry-core", - "uname", -] - -[[package]] -name = "sentry-core" -version = "0.23.0" -source = "git+https://github.com/getsentry/sentry-rust?rev=df694a49595d6890c510d80b85cfbb4b5ae6159a#df694a49595d6890c510d80b85cfbb4b5ae6159a" -dependencies = [ - "chrono", - "lazy_static", - "rand 0.8.5", - "sentry-types", - "serde", - "serde_json", -] - -[[package]] -name = "sentry-panic" -version = "0.23.0" -source = "git+https://github.com/getsentry/sentry-rust?rev=df694a49595d6890c510d80b85cfbb4b5ae6159a#df694a49595d6890c510d80b85cfbb4b5ae6159a" -dependencies = [ - "sentry-backtrace", - "sentry-core", -] - -[[package]] -name = "sentry-types" -version = "0.23.0" -source = "git+https://github.com/getsentry/sentry-rust?rev=df694a49595d6890c510d80b85cfbb4b5ae6159a#df694a49595d6890c510d80b85cfbb4b5ae6159a" -dependencies = [ - "chrono", - "debugid", - "getrandom 0.2.6", - "hex", - "serde", - "serde_json", - "thiserror", - "url", - "uuid", -] - [[package]] name = "serde" version = "1.0.139" @@ -2506,15 +2311,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "uname" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" -dependencies = [ - "libc", -] - [[package]] name = "unicode-bidi" version = "0.3.8" @@ -2546,17 +2342,6 @@ dependencies = [ "idna", "matches", "percent-encoding", - "serde", -] - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom 0.2.6", - "serde", ] [[package]] diff --git a/polyjuice-tests/src/ctx.rs b/polyjuice-tests/src/ctx.rs index b63b7ae9..f12f3dcd 100644 --- a/polyjuice-tests/src/ctx.rs +++ b/polyjuice-tests/src/ctx.rs @@ -15,7 +15,7 @@ use gw_common::{ use gw_config::{BackendConfig, BackendSwitchConfig, BackendType}; use gw_db::schema::{COLUMN_INDEX, COLUMN_META, META_TIP_BLOCK_HASH_KEY}; use gw_generator::{ - account_lock_manage::{secp256k1::Secp256k1, AccountLockManage}, + account_lock_manage::{secp256k1::Secp256k1Eth, AccountLockManage}, backend_manage::BackendManage, dummy_state::DummyState, traits::StateExt, @@ -388,8 +388,10 @@ impl Context { BackendManage::from_config(vec![config.backends.clone()]).expect("default backend"); // NOTICE in this test we won't need SUM validator let mut account_lock_manage = AccountLockManage::default(); - account_lock_manage - .register_lock_algorithm(SECP_LOCK_CODE_HASH.into(), Box::new(Secp256k1::default())); + account_lock_manage.register_lock_algorithm( + SECP_LOCK_CODE_HASH.into(), + Box::new(Secp256k1Eth::default()), + ); let rollup_context = RollupContext { rollup_script_hash: ROLLUP_SCRIPT_HASH.into(), rollup_config: config.rollup, diff --git a/polyjuice-tests/src/helper.rs b/polyjuice-tests/src/helper.rs index 929e77f5..f704fddb 100644 --- a/polyjuice-tests/src/helper.rs +++ b/polyjuice-tests/src/helper.rs @@ -10,7 +10,7 @@ use gw_config::{BackendConfig, BackendSwitchConfig, BackendType}; use gw_db::schema::{COLUMN_INDEX, COLUMN_META, META_TIP_BLOCK_HASH_KEY}; use gw_generator::error::TransactionError; pub use gw_generator::{ - account_lock_manage::{secp256k1::Secp256k1, AccountLockManage}, + account_lock_manage::{secp256k1::Secp256k1Eth, AccountLockManage}, backend_manage::{Backend, BackendManage}, dummy_state::DummyState, traits::StateExt, @@ -467,8 +467,10 @@ pub fn setup() -> (Store, DummyState, Generator) { let backend_manage = BackendManage::from_config(configs).expect("default backend"); // NOTICE in this test we won't need SUM validator let mut account_lock_manage = AccountLockManage::default(); - account_lock_manage - .register_lock_algorithm(SECP_LOCK_CODE_HASH.into(), Box::new(Secp256k1::default())); + account_lock_manage.register_lock_algorithm( + SECP_LOCK_CODE_HASH.into(), + Box::new(Secp256k1Eth::default()), + ); let rollup_config = RollupConfig::new_builder() .chain_id(CHAIN_ID.pack()) .l2_sudt_validator_script_type_hash(SUDT_VALIDATOR_SCRIPT_TYPE_HASH.pack()) diff --git a/polyjuice-tests/src/test_cases/native_token_transfer.rs b/polyjuice-tests/src/test_cases/native_token_transfer.rs index 958cc606..b74a6036 100644 --- a/polyjuice-tests/src/test_cases/native_token_transfer.rs +++ b/polyjuice-tests/src/test_cases/native_token_transfer.rs @@ -66,10 +66,12 @@ fn native_token_transfer_unregistered_address_test() -> anyhow::Result<()> { let run_result = chain.execute_raw(raw_tx)?; assert_eq!(run_result.exit_code, 0); + let account_id = chain.get_account_id_by_eth_address(&to_addr)?; + assert_eq!(Some(6), account_id); let from_balance = chain.get_balance(&from_addr)?; let to_balance = chain.get_balance(&to_addr)?; println!("from balance: {}, to balance: {}", from_balance, to_balance); - assert_eq!(mint - 21000 - value, from_balance); + assert_eq!(mint - 21000 - 25000 - value, from_balance); assert_eq!(value, to_balance.as_u128()); Ok(()) @@ -219,7 +221,7 @@ fn native_token_transfer_unregistered_zero_address_test() -> anyhow::Result<()> let from_balance = chain.get_balance(&from_addr)?; let to_balance = chain.get_balance(&to_addr)?; println!("from balance: {}, to balance: {}", from_balance, to_balance); - assert_eq!(mint - 21000 - value, from_balance); + assert_eq!(mint - 21000 - 25000 - value, from_balance); assert_eq!(value, to_balance.as_u128()); Ok(()) diff --git a/polyjuice-tests/src/test_cases/recover_account.rs b/polyjuice-tests/src/test_cases/recover_account.rs index 830ff010..dec9cf4b 100644 --- a/polyjuice-tests/src/test_cases/recover_account.rs +++ b/polyjuice-tests/src/test_cases/recover_account.rs @@ -1,13 +1,18 @@ //! Test RecoverAccount //! See ./evm-contracts/RecoverAccount.sol +use std::convert::TryInto; + use crate::helper::{ self, deploy, new_block_info, new_contract_account_script, setup, simple_storage_get, PolyjuiceArgsBuilder, CREATOR_ACCOUNT_ID, FATAL_PRECOMPILED_CONTRACTS, L2TX_MAX_CYCLES, ROLLUP_SCRIPT_HASH, SECP_LOCK_CODE_HASH, }; use gw_common::state::State; -use gw_generator::traits::StateExt; +use gw_generator::{ + account_lock_manage::{secp256k1::Secp256k1Eth, LockAlgorithm}, + traits::StateExt, +}; use gw_store::chain_view::ChainView; use gw_store::traits::chain_store::ChainStore; use gw_types::{ @@ -58,9 +63,19 @@ fn test_recover_account() { let run_result = simple_storage_get(&store, &state, &generator, 0, from_id, new_account_id); println!("return bytes: {}", hex::encode(run_result.return_data)); - let lock_args_hex = "404f90829ec0e5821aeba9bce7d5e841ce9f7fa5"; let message_hex = "1cdeae55a5768fe14b628001c6247ae84c70310a7ddcfdc73ac68494251e46ec"; let signature_hex = "28aa0c394487edf2211f445c47fb5f4fb5e3023920f62124d309f5bdf70d95045a934f278cec717300a5417313d1cdc390e761e37c0964b940c0a6f07b7361ed01"; + let secp256k1 = Secp256k1Eth::default(); + let message = hex::decode(&message_hex).unwrap(); + let msg: [u8; 32] = message.try_into().unwrap(); + let signature = hex::decode(&signature_hex).unwrap(); + + let lock_args = secp256k1 + .recover(msg.into(), &signature) + .expect("get lock args"); + let lock_args_hex = hex::encode(&lock_args); + println!("lock args: {}", &lock_args_hex); + { // RecoverAccount.recover(message, signature, code_hash); let block_info = new_block_info(block_producer_id.clone(), 2, 0);