diff --git a/src/components/abciapp/Cargo.toml b/src/components/abciapp/Cargo.toml index aa1499ebe..f2a4e393c 100644 --- a/src/components/abciapp/Cargo.toml +++ b/src/components/abciapp/Cargo.toml @@ -58,7 +58,8 @@ tempfile = "3.1.0" baseapp = { path = "../contracts/baseapp" } fc-rpc = { path = "../contracts/rpc" } fp-storage = { path = "../contracts/primitives/storage" } -fp-utils = { path = "../contracts/primitives/utils" } +fp-types = {path = "../contracts/primitives/types"} +fp-utils = {path = "../contracts/primitives/utils" } enterprise-web3 = { path = "../contracts/primitives/enterprise-web3", optional = true } @@ -75,5 +76,5 @@ vergen = "=3.1.0" [features] default = ["diskcache"] diskcache = ["ledger/diskcache"] -debug_env = ["ledger/debug_env", "config/debug_env"] +debug_env = ["ledger/debug_env", "config/debug_env", "baseapp/debug_env"] web3_service = ["enterprise-web3", "baseapp/web3_service"] \ No newline at end of file diff --git a/src/components/abciapp/src/abci/server/callback/mod.rs b/src/components/abciapp/src/abci/server/callback/mod.rs index 3d32493c2..fec71386e 100644 --- a/src/components/abciapp/src/abci/server/callback/mod.rs +++ b/src/components/abciapp/src/abci/server/callback/mod.rs @@ -29,6 +29,7 @@ use { staking::KEEP_HIST, store::api_cache, }, + module_evm::utils::{deposit_asset_event_topic_str, parse_deposit_asset_event}, parking_lot::{Mutex, RwLock}, protobuf::RepeatedField, ruc::*, @@ -374,30 +375,85 @@ pub fn deliver_tx( } let mut resp = s.account_base_app.write().deliver_tx(req); - if td_height > CFG.checkpoint.fix_prism_mint_pay && 0 == resp.code { - let mut la = s.la.write(); - let mut laa = la.get_committed_state().write(); - if let Some(tx) = staking::system_prism_mint_pay( - &mut laa, - &mut s.account_base_app.write(), - ) { - drop(laa); - if la.cache_transaction(tx).is_ok() { - return resp; + if td_height > CFG.checkpoint.prismxx_inital_height && 0 == resp.code { + let deposit_asset_topic = deposit_asset_event_topic_str(); + + for evt in resp.events.iter() { + if evt.field_type == *"ethereum_ContractLog" { + let mut bridge_contract_found = false; + let mut deposit_asset_foud = false; + + for pair in evt.attributes.iter() { + let key = String::from_utf8(pair.key.clone()) + .unwrap_or_default(); + if key == *"address" { + let addr = String::from_utf8(pair.value.clone()) + .unwrap_or_default(); + if addr + == CFG + .checkpoint + .prism_bridge_address + .to_lowercase() + { + bridge_contract_found = true + } + } + if key == *"topics" { + let topic = String::from_utf8(pair.value.clone()) + .unwrap_or_default(); + if topic == deposit_asset_topic { + deposit_asset_foud = true + } + } + if key == *"data" + && bridge_contract_found + && deposit_asset_foud + { + let data = String::from_utf8(pair.value.clone()) + .unwrap_or_default(); + + let data_vec = serde_json::from_str(&data).unwrap(); + + let deposit_asset = + parse_deposit_asset_event(data_vec); + + match deposit_asset { + Ok(deposit) => { + let mut la = s.la.write(); + let mut laa = + la.get_committed_state().write(); + if let Some(tx) = + staking::system_prism_mint_pay( + &mut laa, deposit, + ) + { + drop(laa); + if la.cache_transaction(tx).is_ok() { + return resp; + } + resp.code = 1; + s.account_base_app + .read() + .deliver_state + .state + .write() + .discard_session(); + s.account_base_app + .read() + .deliver_state + .db + .write() + .discard_session(); + } + } + Err(e) => { + resp.code = 1; + resp.log = e.to_string(); + } + } + } + } } - resp.code = 1; - s.account_base_app - .read() - .deliver_state - .state - .write() - .discard_session(); - s.account_base_app - .read() - .deliver_state - .db - .write() - .discard_session(); } } resp @@ -434,11 +490,7 @@ pub fn end_block( // mint coinbase, cache system transactions to ledger { let mut laa = la.get_committed_state().write(); - if let Some(tx) = staking::system_mint_pay( - td_height, - &mut laa, - &mut s.account_base_app.write(), - ) { + if let Some(tx) = staking::system_mint_pay(td_height, &mut laa) { drop(laa); // this unwrap should be safe la.cache_transaction(tx).unwrap(); diff --git a/src/components/abciapp/src/abci/staking/mod.rs b/src/components/abciapp/src/abci/staking/mod.rs index 929f7c37d..532e0e2b3 100644 --- a/src/components/abciapp/src/abci/staking/mod.rs +++ b/src/components/abciapp/src/abci/staking/mod.rs @@ -12,8 +12,8 @@ mod test; use { crate::abci::server::callback::TENDERMINT_BLOCK_HEIGHT, abci::{Evidence, Header, LastCommitInfo, PubKey, ValidatorUpdate}, - baseapp::BaseApp as AccountBaseApp, config::abci::global_cfg::CFG, + fp_types::actions::xhub::NonConfidentialOutput, lazy_static::lazy_static, ledger::{ data_model::{ @@ -285,120 +285,57 @@ fn system_governance(staking: &mut Staking, bz: &ByzantineInfo) -> Result<()> { /// Pay for freed 'Delegations' and 'FraDistributions'. pub fn system_prism_mint_pay( la: &mut LedgerState, - account_base_app: &mut AccountBaseApp, + mint: NonConfidentialOutput, ) -> Option { let mut mints = Vec::new(); - if let Some(account_mint) = account_base_app.consume_mint() { - for mint in account_mint { - if mint.asset != ASSET_TYPE_FRA { - let atc = AssetTypeCode { val: mint.asset }; - let at = if let Some(mut at) = la.get_asset_type(&atc) { - at.properties.issuer = IssuerPublicKey { - key: *BLACK_HOLE_PUBKEY_STAKING, - }; - if mint.max_supply != 0 { - at.properties.asset_rules.max_units = Some(mint.max_supply); - } - at.properties.asset_rules.decimals = mint.decimal; - at - } else { - let mut at = AssetType::default(); - at.properties.issuer = IssuerPublicKey { - key: *BLACK_HOLE_PUBKEY_STAKING, - }; + if mint.asset != ASSET_TYPE_FRA { + let atc = AssetTypeCode { val: mint.asset }; + let at = if let Some(mut at) = la.get_asset_type(&atc) { + at.properties.issuer = IssuerPublicKey { + key: *BLACK_HOLE_PUBKEY_STAKING, + }; + if mint.max_supply != 0 { + at.properties.asset_rules.max_units = Some(mint.max_supply); + } + at.properties.asset_rules.decimals = mint.decimal; + at + } else { + let mut at = AssetType::default(); + at.properties.issuer = IssuerPublicKey { + key: *BLACK_HOLE_PUBKEY_STAKING, + }; - if mint.max_supply != 0 { - at.properties.asset_rules.max_units = Some(mint.max_supply); - } - at.properties.asset_rules.decimals = mint.decimal; + if mint.max_supply != 0 { + at.properties.asset_rules.max_units = Some(mint.max_supply); + } + at.properties.asset_rules.decimals = mint.decimal; - at.properties.code = AssetTypeCode { val: mint.asset }; + at.properties.code = AssetTypeCode { val: mint.asset }; - at - }; + at + }; - la.insert_asset_type(atc, at); - } + la.insert_asset_type(atc, at); + } - let mint_entry = MintEntry::new( - MintKind::Other, - mint.target, - None, - mint.amount, - mint.asset, - ); + let mint_entry = + MintEntry::new(MintKind::Other, mint.target, None, mint.amount, mint.asset); - mints.push(mint_entry); - } - } + mints.push(mint_entry); - if mints.is_empty() { - None - } else { - let mint_ops = - Operation::MintFra(MintFraOps::new(la.get_staking().cur_height(), mints)); - Some(Transaction::from_operation_coinbase_mint( - mint_ops, - la.get_state_commitment().1, - )) - } + let mint_ops = + Operation::MintFra(MintFraOps::new(la.get_staking().cur_height(), mints)); + Some(Transaction::from_operation_coinbase_mint( + mint_ops, + la.get_state_commitment().1, + )) } /// Pay for freed 'Delegations' and 'FraDistributions'. -pub fn system_mint_pay( - td_height: i64, - la: &mut LedgerState, - account_base_app: &mut AccountBaseApp, -) -> Option { +pub fn system_mint_pay(td_height: i64, la: &mut LedgerState) -> Option { let mut mints = Vec::new(); - if td_height <= CFG.checkpoint.fix_prism_mint_pay { - if let Some(account_mint) = account_base_app.consume_mint() { - for mint in account_mint { - if mint.asset != ASSET_TYPE_FRA { - let atc = AssetTypeCode { val: mint.asset }; - let at = if let Some(mut at) = la.get_asset_type(&atc) { - at.properties.issuer = IssuerPublicKey { - key: *BLACK_HOLE_PUBKEY_STAKING, - }; - - if mint.max_supply != 0 { - at.properties.asset_rules.max_units = Some(mint.max_supply); - } - - at - } else { - let mut at = AssetType::default(); - at.properties.issuer = IssuerPublicKey { - key: *BLACK_HOLE_PUBKEY_STAKING, - }; - - if mint.max_supply != 0 { - at.properties.asset_rules.max_units = Some(mint.max_supply); - } - - at.properties.code = AssetTypeCode { val: mint.asset }; - - at - }; - - la.insert_asset_type(atc, at); - } - - let mint_entry = MintEntry::new( - MintKind::Other, - mint.target, - None, - mint.amount, - mint.asset, - ); - - mints.push(mint_entry); - } - } - } - let staking = la.get_staking(); let mut limit = staking.coinbase_balance() as i128; diff --git a/src/components/config/src/abci/mod.rs b/src/components/config/src/abci/mod.rs index b97a41c6b..12428ea4a 100644 --- a/src/components/config/src/abci/mod.rs +++ b/src/components/config/src/abci/mod.rs @@ -61,7 +61,6 @@ pub struct CheckPointConfig { pub unbond_block_cnt: u64, pub prismxx_inital_height: i64, pub enable_triple_masking_height: i64, - pub fix_prism_mint_pay: i64, pub fix_exec_code: i64, // https://github.com/FindoraNetwork/platform/pull/307 @@ -117,13 +116,14 @@ impl CheckPointConfig { enable_triple_masking_height: 0, fix_unpaid_delegation_height: 0, fix_undelegation_missing_reward_height: 0, - fix_prism_mint_pay: 0, fix_exec_code: 0, evm_checktx_nonce: 0, utxo_checktx_height: 0, utxo_asset_prefix_height: 0, nonce_bug_fix_height: 0, - prism_bridge_address: String::new(), + prism_bridge_address: + "0xfcfe4ff1006a7721cee870b56ee2b5c250aec13b" + .to_owned(), proper_gas_set_height: 0, fix_delegators_am_height: 0, validators_limit_v2_height: 0, @@ -145,7 +145,6 @@ impl CheckPointConfig { prismxx_inital_height: 30000000, enable_triple_masking_height: 30000000, fix_unpaid_delegation_height: 2261885, - fix_prism_mint_pay: 30000000, fix_exec_code: 30000000, evm_checktx_nonce: 30000000, utxo_checktx_height: 30000000, diff --git a/src/components/contracts/baseapp/Cargo.toml b/src/components/contracts/baseapp/Cargo.toml index cbc641ceb..74bc31e81 100644 --- a/src/components/contracts/baseapp/Cargo.toml +++ b/src/components/contracts/baseapp/Cargo.toml @@ -56,4 +56,5 @@ evm-precompile = {path = "../modules/evm/precompile"} [features] abci_mock = [] -web3_service = ["enterprise-web3", "module-account/web3_service", "module-ethereum/web3_service", "module-evm/web3_service"] \ No newline at end of file +web3_service = ["enterprise-web3", "module-account/web3_service", "module-ethereum/web3_service", "module-evm/web3_service"] +debug_env = [] diff --git a/src/components/contracts/baseapp/src/lib.rs b/src/components/contracts/baseapp/src/lib.rs index 02de696a1..05d003679 100644 --- a/src/components/contracts/baseapp/src/lib.rs +++ b/src/components/contracts/baseapp/src/lib.rs @@ -27,11 +27,11 @@ use fp_evm::BlockId; use fp_traits::{ account::{AccountAsset, FeeCalculator}, base::BaseProvider, - evm::{DecimalsMapping, EthereumAddressMapping, EthereumDecimalsMapping}, + evm::{EthereumAddressMapping, EthereumDecimalsMapping}, }; -use fp_types::{actions::xhub::NonConfidentialOutput, actions::Action, crypto::Address}; +use fp_types::{actions::Action, crypto::Address}; use lazy_static::lazy_static; -use ledger::data_model::{Transaction as FindoraTransaction, ASSET_TYPE_FRA}; +use ledger::data_model::Transaction as FindoraTransaction; use notify::*; use parking_lot::RwLock; use primitive_types::{H160, H256, U256}; @@ -350,36 +350,6 @@ impl BaseApp { self.modules .process_findora_tx(&self.deliver_state, tx, H256::from_slice(hash)) } - - pub fn consume_mint(&self) -> Option> { - let mut outputs = self.modules.evm_module.consume_mint(&self.deliver_state); - - for output in &outputs { - if output.asset == ASSET_TYPE_FRA { - let address = - Address::from(self.modules.evm_module.contracts.bridge_address); - if let Some(amount) = - EthereumDecimalsMapping::from_native_token(U256::from(output.amount)) - { - if let Err(e) = module_account::App::::burn( - &self.deliver_state, - &address, - amount, - ) { - tracing::error!("Error when burn account: {:?}", e); - } - } - } - } - - let outputs2 = module_xhub::App::::consume_mint(&self.deliver_state); - - if let Some(mut e) = outputs2 { - outputs.append(&mut e); - } - - Some(outputs) - } } impl BaseProvider for BaseApp { diff --git a/src/components/contracts/baseapp/src/modules.rs b/src/components/contracts/baseapp/src/modules.rs index c84a21925..f4982471c 100644 --- a/src/components/contracts/baseapp/src/modules.rs +++ b/src/components/contracts/baseapp/src/modules.rs @@ -22,6 +22,9 @@ use module_ethereum::storage::{TransactionIndex, DELIVER_PENDING_TRANSACTIONS}; use ruc::*; use serde::Serialize; +#[cfg(feature = "debug_env")] +use std::str::FromStr; + #[derive(Default, Clone)] pub struct ModuleManager { // Ordered module list @@ -72,6 +75,20 @@ impl ModuleManager { self.evm_module.begin_block(ctx, req); self.xhub_module.begin_block(ctx, req); self.template_module.begin_block(ctx, req); + + #[cfg(feature = "debug_env")] + if ctx.header.height == 1 { + //private key: 4d05b965f821ea900ddd995dfa1b6caa834eaaa1ebe100a9760baf9331aae567 + let test_address = + H160::from_str("0x72488bAa718F52B76118C79168E55c209056A2E6").unwrap(); + + // mint 1000 FRA + pnk!(module_account::App::::mint( + ctx, + &Address::from(test_address), + U256::from(1_0000_0000_0000_0000_u64).saturating_mul(1000_00.into()) + )); + } } pub fn end_block( diff --git a/src/components/contracts/modules/evm/contracts/PrismXXBridge.abi.json b/src/components/contracts/modules/evm/contracts/PrismXXBridge.abi.json index 3defb48db..3909b8043 100644 --- a/src/components/contracts/modules/evm/contracts/PrismXXBridge.abi.json +++ b/src/components/contracts/modules/evm/contracts/PrismXXBridge.abi.json @@ -1,14 +1,40 @@ [ { + "anonymous": false, "inputs": [ { - "internalType": "address", - "name": "_proxy_contract", - "type": "address" + "indexed": false, + "internalType": "bytes32", + "name": "asset", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "receiver", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "decimal", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "max_supply", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "constructor" + "name": "DepositAsset", + "type": "event" }, { "anonymous": false, @@ -134,6 +160,19 @@ "name": "DepositFRC721", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -277,115 +316,6 @@ "name": "WithdrawFRC721", "type": "event" }, - { - "inputs": [], - "name": "__self", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "_consumeMint", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "asset", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "receiver", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "decimal", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "max_supply", - "type": "uint256" - } - ], - "internalType": "struct PrismXXBridge.MintOp[]", - "name": "", - "type": "tuple[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_asset", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "_from", - "type": "bytes" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "_withdrawAsset", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "_withdrawFRA", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -468,46 +398,6 @@ "stateMutability": "pure", "type": "function" }, - { - "inputs": [], - "name": "consumeMint", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "asset", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "receiver", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "decimal", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "max_supply", - "type": "uint256" - } - ], - "internalType": "struct PrismXXBridge.MintOp[]", - "name": "", - "type": "tuple[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -597,59 +487,14 @@ }, { "inputs": [], - "name": "ledger_contract", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "ops", - "outputs": [ - { - "internalType": "bytes32", - "name": "asset", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "receiver", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "decimal", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "max_supply", - "type": "uint256" - } - ], - "stateMutability": "view", + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "owner", + "name": "ledger_contract", "outputs": [ { "internalType": "address", @@ -662,7 +507,7 @@ }, { "inputs": [], - "name": "proxy_contract", + "name": "owner", "outputs": [ { "internalType": "address", @@ -728,24 +573,19 @@ }, { "inputs": [ - { - "internalType": "bytes", - "name": "_from", - "type": "bytes" - }, { "internalType": "address payable", - "name": "_to", + "name": "to", "type": "address" }, { "internalType": "uint256", - "name": "_value", + "name": "value", "type": "uint256" }, { "internalType": "bytes", - "name": "_data", + "name": "data", "type": "bytes" } ], @@ -758,4 +598,4 @@ "stateMutability": "payable", "type": "receive" } -] +] \ No newline at end of file diff --git a/src/components/contracts/modules/evm/src/lib.rs b/src/components/contracts/modules/evm/src/lib.rs index 3839482c3..45e9d916f 100644 --- a/src/components/contracts/modules/evm/src/lib.rs +++ b/src/components/contracts/modules/evm/src/lib.rs @@ -12,7 +12,6 @@ pub mod system_contracts; pub mod utils; use abci::{RequestQuery, ResponseQuery}; -use config::abci::global_cfg::CFG; use ethabi::Token; use ethereum_types::{Bloom, BloomInput, H160, H256, U256}; use fp_core::{ @@ -37,7 +36,7 @@ use ethereum::{ }; use fp_types::{ - actions::{evm::Action, xhub::NonConfidentialOutput}, + actions::evm::Action, crypto::{Address, HA160}, }; use noah::xfr::sig::XfrPublicKey; @@ -46,7 +45,8 @@ use precompile::PrecompileSet; use ruc::*; use runtime::runner::ActionRunner; use std::marker::PhantomData; -use system_contracts::SystemContracts; +use std::str::FromStr; +use system_contracts::{SystemContracts, SYSTEM_ADDR}; pub use runtime::*; @@ -127,7 +127,7 @@ impl App { .encode_input(&[asset, from, to, value, lowlevel]) .c(d!())?; - let from = H160::zero(); + let from = H160::from_str(SYSTEM_ADDR).unwrap(); let gas_limit = 9999999; let value = U256::zero(); @@ -161,7 +161,7 @@ impl App { pub fn withdraw_fra( &self, ctx: &Context, - from: &XfrPublicKey, + _from: &XfrPublicKey, to: &H160, _value: U256, _lowlevel: Vec, @@ -170,23 +170,19 @@ impl App { ) -> Result<(TransactionV0, TransactionStatus, Receipt)> { let function = self.contracts.bridge.function("withdrawFRA").c(d!())?; - let from = Token::Bytes(from.noah_to_bytes()); - // let to = Token::Address(H160::from_slice(&bytes[4..24])); let to = Token::Address(*to); let value = Token::Uint(_value); let lowlevel = Token::Bytes(_lowlevel); - // println!("{:?}, {:?}, {:?}, {:?}", from, to, value, lowlevel); + //println!("{:?}, {:?}, {:?}, {:?}", from, to, value, lowlevel); - let input = function - .encode_input(&[from, to, value, lowlevel]) - .c(d!())?; + let input = function.encode_input(&[to, value, lowlevel]).c(d!())?; let gas_limit = 9999999; let value = U256::zero(); let gas_price = U256::one(); - let from = H160::zero(); + let from = H160::from_str(SYSTEM_ADDR).unwrap(); let (_, logs, used_gas) = ActionRunner::::execute_systemc_contract( ctx, @@ -214,22 +210,6 @@ impl App { )) } - pub fn consume_mint(&self, ctx: &Context) -> Vec { - let height = CFG.checkpoint.prismxx_inital_height; - - let mut pending_outputs = Vec::new(); - - if height < ctx.header.height { - if let Err(e) = - utils::fetch_mint::(ctx, &self.contracts, &mut pending_outputs) - { - tracing::error!("Collect mint ops error: {:?}", e); - } - } - - pending_outputs - } - fn logs_bloom(logs: &[ethereum::Log], bloom: &mut Bloom) { for log in logs { bloom.accrue(BloomInput::Raw(&log.address[..])); @@ -316,31 +296,7 @@ impl AppModule for App { } } - fn begin_block(&mut self, ctx: &mut Context, _req: &abci::RequestBeginBlock) { - let height = CFG.checkpoint.prismxx_inital_height; - - if ctx.header.height == height { - let bytecode_str = include_str!("../contracts/PrismXXProxy.bytecode"); - - if let Err(e) = - utils::deploy_contract::(ctx, &self.contracts, bytecode_str) - { - pd!(e); - return; - } - println!( - "Bridge contract address: {:?}", - self.contracts.bridge_address - ); - - if !ctx.state.write().cache_mut().good2_commit() { - ctx.state.write().discard_session(); - pd!(eg!("ctx state commit no good")); - } else { - ctx.state.write().commit_session(); - } - } - } + fn begin_block(&mut self, _ctx: &mut Context, _req: &abci::RequestBeginBlock) {} } impl Executable for App { diff --git a/src/components/contracts/modules/evm/src/system_contracts.rs b/src/components/contracts/modules/evm/src/system_contracts.rs index b910d3083..57c39cd99 100644 --- a/src/components/contracts/modules/evm/src/system_contracts.rs +++ b/src/components/contracts/modules/evm/src/system_contracts.rs @@ -2,49 +2,28 @@ use std::str::FromStr; use config::abci::global_cfg::CFG; use ethabi::Contract; -use ethereum_types::{H160, H256}; -use fp_utils::hashing::keccak_256; +use ethereum_types::H160; use ruc::*; use serde::{Deserialize, Serialize}; -use crate::utils; +pub static SYSTEM_ADDR: &str = "0x0000000000000000000000000000000000002000"; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct SystemContracts { pub bridge: Contract, pub bridge_address: H160, - pub owner: H160, - pub salt: H256, } impl SystemContracts { pub fn new() -> Result { let abi_str = include_str!("../contracts/PrismXXBridge.abi.json"); let bridge = Contract::load(abi_str.as_bytes()).c(d!())?; - - let owner = - H160::from_str("0x72488bAa718F52B76118C79168E55c209056A2E6").c(d!())?; - - let salt = H256::zero(); - - let bridge_address = if CFG.checkpoint.prism_bridge_address.is_empty() { - // Driect use this bytecode, beacuse we will remove on mainnet - let bytecode_str = include_str!("../contracts/PrismXXProxy.bytecode"); - - let bytecode = hex::decode(bytecode_str[2..].trim()).c(d!())?; - - let code_hash = keccak_256(&bytecode); - - utils::compute_create2(owner, salt, H256::from_slice(&code_hash)) - } else { - H160::from_str(&CFG.checkpoint.prism_bridge_address).c(d!())? - }; + let bridge_address = + H160::from_str(&CFG.checkpoint.prism_bridge_address).unwrap_or_default(); Ok(Self { bridge, bridge_address, - owner, - salt, }) } } diff --git a/src/components/contracts/modules/evm/src/utils.rs b/src/components/contracts/modules/evm/src/utils.rs index 526fde4a0..386826560 100644 --- a/src/components/contracts/modules/evm/src/utils.rs +++ b/src/components/contracts/modules/evm/src/utils.rs @@ -1,137 +1,104 @@ -use ethabi::Token; -use ethereum_types::{H160, H256, U256}; -use fp_core::context::Context; +use ethabi::{Event, EventParam, ParamType, RawLog}; use fp_traits::evm::{DecimalsMapping, EthereumDecimalsMapping}; use fp_types::actions::xhub::NonConfidentialOutput; use ledger::data_model::ASSET_TYPE_FRA; +use noah::xfr::structs::ASSET_TYPE_LENGTH; use noah::xfr::{sig::XfrPublicKey, structs::AssetType}; use noah_algebra::serialization::NoahFromToBytes; use ruc::*; -use sha3::{Digest, Keccak256}; -use crate::{runner::ActionRunner, system_contracts::SystemContracts, Config}; - -pub fn deploy_contract( - ctx: &Context, - contracts: &SystemContracts, - bytecode_str: &str, -) -> Result<()> { - // Deploy Bridge here. - let bytecode = hex::decode(bytecode_str[2..].trim()).c(d!())?; - - ActionRunner::::inital_system_contract( - ctx, - bytecode, - 9999999999, - contracts.owner, - contracts.salt, - )?; - - Ok(()) -} - -pub fn fetch_mint( - ctx: &Context, - contracts: &SystemContracts, - outputs: &mut Vec, -) -> Result<()> { - let function = contracts.bridge.function("consumeMint").c(d!())?; - let input = function.encode_input(&[]).c(d!())?; - - let source = H160::zero(); - let target = contracts.bridge_address; - - let (ret, _, _) = ActionRunner::::execute_systemc_contract( - ctx, - input, - source, - 99999999, - target, - U256::zero(), - ) - .c(d!())?; - - let result = function.decode_output(&ret).c(d!())?; - - for v1 in result { - if let Token::Array(tokens) = v1 { - for token in tokens { - if let Token::Tuple(tuple) = token { - let output = parse_truple_result(tuple)?; - - tracing::info!("Got issue output: {:?}", output); - - outputs.push(output); - } - } - } +pub fn deposit_asset_event() -> Event { + Event { + name: "DepositAsset".to_owned(), + inputs: vec![ + EventParam { + name: "asset".to_owned(), + kind: ParamType::FixedBytes(32), + indexed: false, + }, + EventParam { + name: "receiver".to_owned(), + kind: ParamType::Bytes, + indexed: false, + }, + EventParam { + name: "amount".to_owned(), + kind: ParamType::Uint(256), + indexed: false, + }, + EventParam { + name: "decimal".to_owned(), + kind: ParamType::Uint(8), + indexed: false, + }, + EventParam { + name: "max_supply".to_owned(), + kind: ParamType::Uint(256), + indexed: false, + }, + ], + anonymous: false, } - - Ok(()) } -fn parse_truple_result(tuple: Vec) -> Result { - let asset = if let Token::FixedBytes(bytes) = - tuple.get(0).ok_or(eg!("Asset Must be FixedBytes"))? - { - let mut inner = [0u8; 32]; - - inner.copy_from_slice(bytes); - - AssetType(inner) - } else { - return Err(eg!("Asset Must be FixedBytes")); - }; +pub fn deposit_asset_event_topic_str() -> String { + let topic = deposit_asset_event().signature(); + let temp = hex::encode(topic.as_bytes()); + "[0x".to_owned() + &*temp + &*"]".to_owned() +} - let target = if let Token::Bytes(bytes) = - tuple.get(1).ok_or(eg!("Target must be FixedBytes"))? - { - XfrPublicKey::noah_from_bytes(bytes)? - } else { - return Err(eg!("Asset Must be FixedBytes")); +pub fn parse_deposit_asset_event(data: Vec) -> Result { + let event = deposit_asset_event(); + let log = RawLog { + topics: vec![event.signature()], + data, }; - - let amount = - if let Token::Uint(i) = tuple.get(2).ok_or(eg!("No asset in index 2"))? { - i - } else { - return Err(eg!("Amount must be uint")); - }; - - let amount = if asset == ASSET_TYPE_FRA { - EthereumDecimalsMapping::convert_to_native_token(*amount).as_u64() + let result = event.parse_log(log).c(d!())?; + + let asset = result.params[0] + .value + .clone() + .into_fixed_bytes() + .unwrap_or_default(); + let mut temp = [0u8; ASSET_TYPE_LENGTH]; + temp.copy_from_slice(asset.as_slice()); + let asset_type = AssetType(temp); + + let receiver = result.params[1] + .value + .clone() + .into_bytes() + .unwrap_or_default(); + let target = XfrPublicKey::noah_from_bytes(receiver.as_slice()).unwrap_or_default(); + + let amount = result.params[2] + .value + .clone() + .into_uint() + .unwrap_or_default(); + + let amount = if asset_type == ASSET_TYPE_FRA { + EthereumDecimalsMapping::convert_to_native_token(amount).as_u64() } else { amount.as_u64() }; - let decimal = - if let Token::Uint(decimal) = tuple.get(3).ok_or(eg!("No asset in index 3"))? { - decimal.as_u64() as u8 - } else { - return Err(eg!("Decimal must be uint")); - }; - - let max_supply = - if let Token::Uint(num) = tuple.get(4).ok_or(eg!("No asset in index 4"))? { - num.as_u64() - } else { - return Err(eg!("Max supply must be uint")); - }; + let decimal = result.params[3] + .value + .clone() + .into_uint() + .unwrap_or_default(); + let max_supply = result.params[4] + .value + .clone() + .into_uint() + .unwrap_or_default(); Ok(NonConfidentialOutput { - asset, + asset: asset_type, amount, target, - decimal, - max_supply, + decimal: decimal.as_u64() as u8, + max_supply: max_supply.as_u64(), }) } - -pub fn compute_create2(caller: H160, salt: H256, code_hash: H256) -> H160 { - let mut hasher = Keccak256::new(); - hasher.update([0xff]); - hasher.update(&caller[..]); - hasher.update(&salt[..]); - hasher.update(&code_hash[..]); - H256::from_slice(hasher.finalize().as_slice()).into() -}