From 7110aa47c594d08b27d411718b80afda77d7dd29 Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Tue, 17 Dec 2019 12:45:35 +0800 Subject: [PATCH 1/4] update: refactoring `redeem_ring`, `redeem_kton` --- srml/eth-backing/src/lib.rs | 193 ++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/srml/eth-backing/src/lib.rs b/srml/eth-backing/src/lib.rs index dfdbb8491..a61006dce 100644 --- a/srml/eth-backing/src/lib.rs +++ b/srml/eth-backing/src/lib.rs @@ -5,12 +5,11 @@ #![cfg_attr(not(feature = "std"), no_std)] //use codec::{Decode, Encode}; -use rstd::{borrow::ToOwned, result}; -use rstd::{marker::PhantomData, prelude::*}; // fmt::Debug, +use ethabi::{Event as EthEvent, EventParam as EthEventParam, ParamType, RawLog}; +use rstd::{borrow::ToOwned, convert::TryFrom, marker::PhantomData, result, vec::Vec}; // fmt::Debug +use sr_primitives::traits::{SaturatedConversion, Saturating}; use support::{decl_event, decl_module, decl_storage, ensure, traits::Currency, traits::OnUnbalanced}; // dispatch::Result, -use system::ensure_signed; - -use sr_primitives::traits::{SaturatedConversion, Saturating}; // Convert, +use system::ensure_signed; // Convert, //use sr_primitives::RuntimeDebug; //use primitives::crypto::UncheckedFrom; @@ -18,14 +17,12 @@ use sr_primitives::traits::{SaturatedConversion, Saturating}; // Convert, use darwinia_eth_relay::{EthReceiptProof, VerifyEthReceipts}; use darwinia_support::{LockableCurrency, OnDepositRedeem}; -use ethabi::{Event as EthEvent, EventParam as EthEventParam, ParamType, RawLog}; use sr_eth_primitives::{EthAddress, H256, U256}; // receipt::LogEntry, receipt::Receipt, //#[cfg(feature = "std")] //use sr_primitives::{Deserialize, Serialize}; -use rstd::vec::Vec; - +pub type Balance = u128; pub type Moment = u64; type RingBalanceOf = <::Ring as Currency<::AccountId>>::Balance; @@ -89,109 +86,42 @@ decl_module! { pub fn redeem_ring(origin, proof_record: EthReceiptProof) { let _relayer = ensure_signed(origin)?; - ensure!(!::exists((proof_record.header_hash, proof_record.index)), "Ring for this proof has already been redeemed."); - - let verified_receipt = T::EthRelay::verify_receipt(&proof_record)?; - - // event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); - // https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800 - let eth_event = EthEvent { - name: "RingBurndropTokens".to_owned(), - inputs: vec![ - EthEventParam {name: "token".to_owned(), kind: ParamType::Address, indexed: true,}, - EthEventParam {name: "owner".to_owned(), kind: ParamType::Address, indexed: true,}, - EthEventParam {name: "amount".to_owned(), kind: ParamType::Uint(256), indexed: false,}, - EthEventParam {name: "data".to_owned(), kind: ParamType::Bytes, indexed: false,} - ], - anonymous: false, - }; - - // H256::from(hex!("38045eaef0a21b74ff176350f18df02d9041a25d6694b5f63e9474b7b6cd6b94") - let log_entry = verified_receipt.logs.iter().find( - |&x| x.address == Self::ring_redeem_address() - && x.topics[0] == eth_event.signature() - ).expect("Log Entry Not Found"); - - let log = RawLog { - topics: [log_entry.topics[0],log_entry.topics[1],log_entry.topics[2]].to_vec(), - data: log_entry.data.clone() - }; - - let result = eth_event.parse_log(log).expect("Parse Eth Log Error"); - - // TODO: div 10**18 and mul 10**9 - let mut amount : U256 = result.params[2].value.clone().to_uint().expect("Param Convert to Int Failed."); - amount = amount / U256::from(1_000_000_000u64); - - let raw_sub_key : Vec = result.params[3].value.clone().to_bytes().expect("Param Convert to Bytes Failed."); + ensure!( + !RingProofVerified::exists((proof_record.header_hash, proof_record.index)), + "Ring For This Proof - ALREADY BEEN REDEEMED", + ); - let decoded_sub_key = hex::decode(&raw_sub_key[..]).expect("Address Hex decode Failed."); - let darwinia_account = T::DetermineAccountId::account_id_for(&decoded_sub_key[..])?; + let (darwinia_account, redeemed_amount) = Self::parse_proof(&proof_record, "RingBurndropTokens")?; + let redeemed_ring = >::saturated_from(redeemed_amount); + let redeemed_positive_imbalance_ring = T::Ring::deposit_into_existing(&darwinia_account, redeemed_ring)?; - let redeemed_amount = amount.as_u128().saturated_into(); + T::RingReward::on_unbalanced(redeemed_positive_imbalance_ring); + RingProofVerified::insert((proof_record.header_hash, proof_record.index), proof_record); >::mutate(|l| { - *l = l.saturating_sub(redeemed_amount); + *l = l.saturating_sub(redeemed_ring); }); - - ::insert((proof_record.header_hash, proof_record.index), proof_record); - - let redeemed_ring = T::Ring::deposit_into_existing(&darwinia_account, redeemed_amount).expect("Deposit into existing failed."); - - T::RingReward::on_unbalanced(redeemed_ring); } // event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); pub fn redeem_kton(origin, proof_record: EthReceiptProof) { let _relayer = ensure_signed(origin)?; - ensure!(!::exists((proof_record.header_hash, proof_record.index)), "Kton for this proof has already been redeemed."); + ensure!( + !KtonProofVerified::exists((proof_record.header_hash, proof_record.index)), + "Kton for this proof has already been redeemed.", + ); - let verified_receipt = T::EthRelay::verify_receipt(&proof_record)?; + let (darwinia_account, redeemed_amount) = Self::parse_proof(&proof_record, "KtonBurndropTokens")?; + let redeemed_kton = >::saturated_from(redeemed_amount); + let redeemed_positive_imbalance_kton = T::Kton::deposit_into_existing(&darwinia_account, redeemed_kton)?; - // event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); - // https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800 - let eth_event = EthEvent { - name: "KtonBurndropTokens".to_owned(), - inputs: vec![ - EthEventParam {name: "token".to_owned(), kind: ParamType::Address, indexed: true,}, - EthEventParam {name: "owner".to_owned(), kind: ParamType::Address, indexed: true,}, - EthEventParam {name: "amount".to_owned(), kind: ParamType::Uint(256), indexed: false,}, - EthEventParam {name: "data".to_owned(), kind: ParamType::Bytes, indexed: false,} - ], - anonymous: false, - }; - - let log_entry = verified_receipt.logs.iter().find( - |&x| x.address == Self::kton_redeem_address() - && x.topics[0] == eth_event.signature() - ).expect("Log Entry Not Found"); - - let log = RawLog { - topics: [log_entry.topics[0],log_entry.topics[1],log_entry.topics[2]].to_vec(), - data: log_entry.data.clone() - }; - - let result = eth_event.parse_log(log).expect("Parse Eth Log Error"); - // TODO: div 10**18 and mul 10**9 - let mut amount : U256 = result.params[2].value.clone().to_uint().expect("Param Convert to Int Failed."); - amount = amount / U256::from(1_000_000_000u64); - let raw_sub_key : Vec = result.params[3].value.clone().to_bytes().expect("Param Convert to Bytes Failed."); - - let decoded_sub_key = hex::decode(&raw_sub_key[..]).expect("Address Hex decode Failed."); - let darwinia_account = T::DetermineAccountId::account_id_for(&decoded_sub_key[..])?; - - let redeemed_amount = amount.as_u128().saturated_into(); + T::KtonReward::on_unbalanced(redeemed_positive_imbalance_kton); + KtonProofVerified::insert((proof_record.header_hash, proof_record.index), proof_record); >::mutate(|l| { - *l = l.saturating_sub(redeemed_amount); + *l = l.saturating_sub(redeemed_kton); }); - - ::insert((proof_record.header_hash, proof_record.index), proof_record); - - let redeemed_kton = T::Kton::deposit_into_existing(&darwinia_account, redeemed_amount).expect("Deposit into existing failed."); - - T::KtonReward::on_unbalanced(redeemed_kton); } // https://github.com/evolutionlandorg/bank @@ -266,6 +196,79 @@ decl_module! { } } +impl Module { + fn parse_proof(proof: &EthReceiptProof, event_name: &str) -> result::Result<(T::AccountId, Balance), &'static str> { + let verified_receipt = T::EthRelay::verify_receipt(proof)?; + + // event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); + // https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800 + // event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); + // TODO: address + let result = { + let eth_event = EthEvent { + name: event_name.to_owned(), + inputs: vec![ + EthEventParam { + name: "token".to_owned(), + kind: ParamType::Address, + indexed: true, + }, + EthEventParam { + name: "owner".to_owned(), + kind: ParamType::Address, + indexed: true, + }, + EthEventParam { + name: "amount".to_owned(), + kind: ParamType::Uint(256), + indexed: false, + }, + EthEventParam { + name: "data".to_owned(), + kind: ParamType::Bytes, + indexed: false, + }, + ], + anonymous: false, + }; + let log_entry = verified_receipt + .logs + .into_iter() + .find(|x| x.address == Self::ring_redeem_address() && x.topics[0] == eth_event.signature()) + .ok_or("Log Entry - NOT FOUND")?; + let log = RawLog { + topics: vec![log_entry.topics[0], log_entry.topics[1], log_entry.topics[2]], + data: log_entry.data.clone(), + }; + + eth_event.parse_log(log).map_err(|_| "Parse Eth Log - FAILED")? + }; + let redeemed_amount = { + // TODO: div 10**18 and mul 10**9 + let amount = result.params[2] + .value + .clone() + .to_uint() + .map(|x| x / U256::from(1_000_000_000u64)) + .ok_or("Convert to Int - FAILED")?; + + Balance::try_from(amount)? + }; + let darwinia_account = { + let raw_sub_key = result.params[3] + .value + .clone() + .to_bytes() + .ok_or("Convert to Bytes - FAILED")?; + let decoded_sub_key = hex::decode(&raw_sub_key).map_err(|_| "Decode Address - FAILED")?; + + T::DetermineAccountId::account_id_for(&decoded_sub_key)? + }; + + Ok((darwinia_account, redeemed_amount)) + } +} + pub trait AccountIdFor { // fn contract_address_for(code_hash: &CodeHash, data: &[u8], origin: &AccountId) -> AccountId; fn account_id_for(decoded_sub_key: &[u8]) -> result::Result; From 1352366f5e6f9bb4f6a6e54e7a7509a672ef288d Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Tue, 17 Dec 2019 12:46:10 +0800 Subject: [PATCH 2/4] fix: typo --- srml/eth-backing/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srml/eth-backing/src/lib.rs b/srml/eth-backing/src/lib.rs index a61006dce..b2e79ded1 100644 --- a/srml/eth-backing/src/lib.rs +++ b/srml/eth-backing/src/lib.rs @@ -109,7 +109,7 @@ decl_module! { ensure!( !KtonProofVerified::exists((proof_record.header_hash, proof_record.index)), - "Kton for this proof has already been redeemed.", + "Kton For This Proof - ALREADY BEEN REDEEMED", ); let (darwinia_account, redeemed_amount) = Self::parse_proof(&proof_record, "KtonBurndropTokens")?; From 3a5eac70bd86bae1166049e61c5b43ff47874861 Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Tue, 17 Dec 2019 12:48:21 +0800 Subject: [PATCH 3/4] update: format --- node/runtime/src/lib.rs | 8 ++++---- srml/eth-backing/Cargo.toml | 22 ++++++++++------------ srml/eth-backing/src/lib.rs | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index b1a5ca03f..cfabbe026 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -426,7 +426,7 @@ construct_runtime!( { // Basic stuff; balances is uncallable initially. RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, - System: system::{Module, Call, Storage, Config, Event}, + System: system::{Module, Call, Storage, Event, Config}, // Must be before session. Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, @@ -439,8 +439,8 @@ construct_runtime!( // Consensus support. Authorship: authorship::{Module, Call, Storage, Inherent}, - Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, + Grandpa: grandpa::{Module, Call, Storage, Event, Config}, + ImOnline: im_online::{default, ValidateUnsigned}, FinalityTracker: finality_tracker::{Module, Call, Inherent}, Offences: offences::{Module, Call, Storage, Event}, Session: session::{Module, Call, Storage, Event, Config}, @@ -451,7 +451,7 @@ construct_runtime!( Utility: utility::{Module, Call, Event}, EthRelay: eth_relay::{Module, Call, Storage, Event, Config}, - EthBacking: eth_backing::{Module, Call, Storage, Event, Config}, + EthBacking: eth_backing, } ); diff --git a/srml/eth-backing/Cargo.toml b/srml/eth-backing/Cargo.toml index 228b5bbbb..f21775067 100644 --- a/srml/eth-backing/Cargo.toml +++ b/srml/eth-backing/Cargo.toml @@ -8,28 +8,24 @@ edition = "2018" [dependencies] # crates.io -serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +hex = { version = "0.4", default-features = false } +serde = { version = "1.0.101", optional = true } # github.com rstd = { package = "sr-std", git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } support = { package = "srml-support", git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } system = { package = "srml-system", git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } timestamp = { package = "srml-timestamp", git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } +sr-primitives = { git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } +primitives = { package = "substrate-primitives", git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } +ethabi = { git = "https://github.com/darwinia-network/ethabi.git", branch = "with_no_std", default-features = false } # darwinia darwinia-support = { package = "darwinia-support", path = "../support", default-features = false } darwinia-eth-relay = { package = "darwinia-eth-relay", path = "../eth-relay", default-features = false } sr-eth-primitives = { path = "../../core/sr-eth-primitives", default-features = false } -sr-primitives = { git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } - -primitives = { package = "substrate-primitives", git = "https://github.com/darwinia-network/substrate.git", branch = "darwinia-develop", default-features = false } - -ethabi = { git = "https://github.com/darwinia-network/ethabi.git", branch = "with_no_std", default-features = false } - -hex = { version = "0.4", default-features = false} - [dev-dependencies] hex-literal = "0.2.1" @@ -37,15 +33,17 @@ hex-literal = "0.2.1" default = ["std"] std = [ "codec/std", + "hex/std", "serde/std", - "hex/std", + + "ethabi/std", "rstd/std", + "sr-primitives/std", "support/std", "system/std", "timestamp/std", + "darwinia-support/std", "darwinia-eth-relay/std", "sr-eth-primitives/std", - "ethabi/std", - "sr-primitives/std", ] diff --git a/srml/eth-backing/src/lib.rs b/srml/eth-backing/src/lib.rs index b2e79ded1..43872fb7b 100644 --- a/srml/eth-backing/src/lib.rs +++ b/srml/eth-backing/src/lib.rs @@ -6,7 +6,7 @@ //use codec::{Decode, Encode}; use ethabi::{Event as EthEvent, EventParam as EthEventParam, ParamType, RawLog}; -use rstd::{borrow::ToOwned, convert::TryFrom, marker::PhantomData, result, vec::Vec}; // fmt::Debug +use rstd::{borrow::ToOwned, convert::TryFrom, marker::PhantomData, result, vec, vec::Vec}; // fmt::Debug use sr_primitives::traits::{SaturatedConversion, Saturating}; use support::{decl_event, decl_module, decl_storage, ensure, traits::Currency, traits::OnUnbalanced}; // dispatch::Result, use system::ensure_signed; // Convert, From f2c53e733d484585c36744408a6cb6a0018eeb94 Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Tue, 17 Dec 2019 14:29:37 +0800 Subject: [PATCH 4/4] update: handle err --- srml/eth-backing/src/lib.rs | 158 +++++++++++++++++++++--------------- 1 file changed, 94 insertions(+), 64 deletions(-) diff --git a/srml/eth-backing/src/lib.rs b/srml/eth-backing/src/lib.rs index 43872fb7b..392156370 100644 --- a/srml/eth-backing/src/lib.rs +++ b/srml/eth-backing/src/lib.rs @@ -6,7 +6,7 @@ //use codec::{Decode, Encode}; use ethabi::{Event as EthEvent, EventParam as EthEventParam, ParamType, RawLog}; -use rstd::{borrow::ToOwned, convert::TryFrom, marker::PhantomData, result, vec, vec::Vec}; // fmt::Debug +use rstd::{borrow::ToOwned, convert::TryFrom, marker::PhantomData, result, vec}; // fmt::Debug use sr_primitives::traits::{SaturatedConversion, Saturating}; use support::{decl_event, decl_module, decl_storage, ensure, traits::Currency, traits::OnUnbalanced}; // dispatch::Result, use system::ensure_signed; // Convert, @@ -83,6 +83,8 @@ decl_module! { where origin: T::Origin { + // event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data) + // https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800 pub fn redeem_ring(origin, proof_record: EthReceiptProof) { let _relayer = ensure_signed(origin)?; @@ -91,7 +93,7 @@ decl_module! { "Ring For This Proof - ALREADY BEEN REDEEMED", ); - let (darwinia_account, redeemed_amount) = Self::parse_proof(&proof_record, "RingBurndropTokens")?; + let (darwinia_account, redeemed_amount) = Self::parse_token_redeem_proof(&proof_record, "RingBurndropTokens")?; let redeemed_ring = >::saturated_from(redeemed_amount); let redeemed_positive_imbalance_ring = T::Ring::deposit_into_existing(&darwinia_account, redeemed_ring)?; @@ -103,7 +105,7 @@ decl_module! { }); } - // event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); + // event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data) pub fn redeem_kton(origin, proof_record: EthReceiptProof) { let _relayer = ensure_signed(origin)?; @@ -112,7 +114,7 @@ decl_module! { "Kton For This Proof - ALREADY BEEN REDEEMED", ); - let (darwinia_account, redeemed_amount) = Self::parse_proof(&proof_record, "KtonBurndropTokens")?; + let (darwinia_account, redeemed_amount) = Self::parse_token_redeem_proof(&proof_record, "KtonBurndropTokens")?; let redeemed_kton = >::saturated_from(redeemed_amount); let redeemed_positive_imbalance_kton = T::Kton::deposit_into_existing(&darwinia_account, redeemed_kton)?; @@ -125,86 +127,114 @@ decl_module! { } // https://github.com/evolutionlandorg/bank - // event Burndrop(uint256 indexed _depositID, address _depositor, uint48 _months, uint48 _startAt, uint64 _unitInterest, uint128 _value, bytes _data); + // event Burndrop(uint256 indexed _depositID, address _depositor, uint48 _months, uint48 _startAt, uint64 _unitInterest, uint128 _value, bytes _data) // https://ropsten.etherscan.io/tx/0xfd2cac791bb0c0bee7c5711f17ef93401061d314f4eb84e1bc91f32b73134ca1 pub fn redeem_deposit(origin, proof_record: EthReceiptProof) { let _relayer = ensure_signed(origin)?; - ensure!(!::exists((proof_record.header_hash, proof_record.index)), "Deposit for this proof has already been redeemed."); - - let verified_receipt = T::EthRelay::verify_receipt(&proof_record)?; + ensure!( + !DepositProofVerified::exists((proof_record.header_hash, proof_record.index)), + "Deposit For This Proof - ALREADY BEEN REDEEMED", + ); - // event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); - // https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800 - let eth_event = EthEvent { - name: "Burndrop".to_owned(), - inputs: vec![ - EthEventParam {name: "_depositID".to_owned(), kind: ParamType::Uint(256), indexed: true,}, - EthEventParam {name: "_depositor".to_owned(), kind: ParamType::Address, indexed: false,}, - EthEventParam {name: "_months".to_owned(), kind: ParamType::Uint(48), indexed: false,}, - EthEventParam {name: "_startAt".to_owned(), kind: ParamType::Uint(48), indexed: false,}, - EthEventParam {name: "_unitInterest".to_owned(), kind: ParamType::Uint(64), indexed: false,}, - EthEventParam {name: "_value".to_owned(), kind: ParamType::Uint(128), indexed: false,}, - EthEventParam {name: "_data".to_owned(), kind: ParamType::Bytes, indexed: false,} - ], - anonymous: false, + let result = { + let verified_receipt = T::EthRelay::verify_receipt(&proof_record)?; + let eth_event = EthEvent { + name: "Burndrop".to_owned(), + inputs: vec![ + EthEventParam { name: "_depositID".to_owned(), kind: ParamType::Uint(256), indexed: true }, + EthEventParam { name: "_depositor".to_owned(), kind: ParamType::Address, indexed: false }, + EthEventParam { name: "_months".to_owned(), kind: ParamType::Uint(48), indexed: false }, + EthEventParam { name: "_startAt".to_owned(), kind: ParamType::Uint(48), indexed: false }, + EthEventParam { name: "_unitInterest".to_owned(), kind: ParamType::Uint(64), indexed: false }, + EthEventParam { name: "_value".to_owned(), kind: ParamType::Uint(128), indexed: false }, + EthEventParam { name: "_data".to_owned(), kind: ParamType::Bytes, indexed: false } + ], + anonymous: false, + }; + let log_entry = verified_receipt. + logs + .iter() + .find(|&x| x.address == Self::deposit_redeem_address() && x.topics[0] == eth_event.signature()) + .ok_or("Log Entry - NOT FOUND")?; + let log = RawLog { + topics: [log_entry.topics[0],log_entry.topics[1]].to_vec(), + data: log_entry.data.clone() + }; + + eth_event.parse_log(log).map_err(|_| "Parse Eth Log - FAILED")? }; - - let log_entry = verified_receipt.logs.iter().find( - |&x| x.address == Self::deposit_redeem_address() - && x.topics[0] == eth_event.signature() - ).expect("Log Entry Not Found"); - - let log = RawLog { - topics: [log_entry.topics[0],log_entry.topics[1]].to_vec(), - data: log_entry.data.clone() + let _deposit_id = result + .params[0] + .value + .clone() + .to_uint() + .ok_or("Convert to Int - FAILED")?; + let month = result + .params[2] + .value + .clone() + .to_uint() + .ok_or("Convert to Int - FAILED")?; + // TODO: Check the time unit in seconds or milliseconds + let start_at = result + .params[3] + .value + .clone() + .to_uint() + .ok_or("Convert to Int - FAILED")?; + let redeemed_amount = { + // TODO: div 10**18 and mul 10**9 + let amount = result.params[2] + .value + .clone() + .to_uint() + .map(|x| x / U256::from(1_000_000_000u64)) + .ok_or("Convert to Int - FAILED")?; + + Balance::try_from(amount)? }; + let darwinia_account = { + let raw_sub_key = result.params[3] + .value + .clone() + .to_bytes() + .ok_or("Convert to Bytes - FAILED")?; + let decoded_sub_key = hex::decode(&raw_sub_key).map_err(|_| "Decode Address - FAILED")?; + + T::DetermineAccountId::account_id_for(&decoded_sub_key)? + }; + let redeemed_ring = >::saturated_from(redeemed_amount); + let redeemed_positive_imbalance_ring = T::Ring::deposit_into_existing(&darwinia_account, redeemed_ring)?; - let result = eth_event.parse_log(log).expect("Parse Eth Log Error"); - - let _deposit_id : U256 = result.params[0].value.clone().to_uint().expect("Param Convert to Int Failed."); - let month : U256 = result.params[2].value.clone().to_uint().expect("Param Convert to Int Failed."); + T::RingReward::on_unbalanced(redeemed_positive_imbalance_ring); - // TODO: Check the time unit in seconds or milliseconds - let start_at : U256 = result.params[3].value.clone().to_uint().expect("Param Convert to Int Failed."); - // TODO: div 10**18 and mul 10**9 - let mut amount: U256 = result.params[5].value.clone().to_uint().expect("Param Convert to Int Failed."); - amount = amount / U256::from(1_000_000_000u64); - let raw_sub_key : Vec = result.params[6].value.clone().to_bytes().expect("Param Convert to Bytes Failed."); + // TODO: check deposit_id duplication - let decoded_sub_key = hex::decode(&raw_sub_key[..]).expect("Address Hex decode Failed."); - let darwinia_account = T::DetermineAccountId::account_id_for(&decoded_sub_key[..])?; + // TODO: Ignore Unit Interest for now - let redeemed_amount = amount.as_u128().saturated_into(); + T::OnDepositRedeem::on_deposit_redeem( + month.saturated_into(), + start_at.saturated_into(), + redeemed_amount, + &darwinia_account, + )?; + DepositProofVerified::insert((proof_record.header_hash, proof_record.index), proof_record); >::mutate(|l| { - *l = l.saturating_sub(redeemed_amount); + *l = l.saturating_sub(redeemed_ring); }); - - ::insert((proof_record.header_hash, proof_record.index), proof_record); - - let redeemed_kton = T::Ring::deposit_into_existing(&darwinia_account, redeemed_amount).expect("Deposit into existing failed."); - - T::RingReward::on_unbalanced(redeemed_kton); - - // TODO: check deposit_id duplication - - // TODO: Ignore Unit Interest for now - - T::OnDepositRedeem::on_deposit_redeem(month.saturated_into(), start_at.saturated_into(), amount.as_u128(), &darwinia_account)?; } } } impl Module { - fn parse_proof(proof: &EthReceiptProof, event_name: &str) -> result::Result<(T::AccountId, Balance), &'static str> { - let verified_receipt = T::EthRelay::verify_receipt(proof)?; - - // event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); - // https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800 - // event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data); - // TODO: address + fn parse_token_redeem_proof( + proof: &EthReceiptProof, + event_name: &str, + ) -> result::Result<(T::AccountId, Balance), &'static str> { let result = { + let verified_receipt = T::EthRelay::verify_receipt(proof)?; let eth_event = EthEvent { name: event_name.to_owned(), inputs: vec![