-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1c0f31f
commit 82519ca
Showing
9 changed files
with
818 additions
and
1 deletion.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"header": { | ||
"version": "V0", | ||
"prev_hash": "0xa5643d9a0983004a662c154d6b2ae2a9aa10566b21333467400c5dcb6558bb38", | ||
"proposer": "0x8af204ac5d7cb8815a6c53a50b72d01e729d3b22", | ||
"state_root": "0x3e7e13a5fdd338fc7254d52745136dde2bbeb82718713415be596dc635274bbe", | ||
"transactions_root": "0x93ac653e9457b39685218933d81145df1b4fd06a9b2e6be0217cad4a608ad6fb", | ||
"signed_txs_hash": "0x2077d36822b7bd8f570d99355c62c8c04d4bf8bcfcb3bfdd5c90be783b713983", | ||
"receipts_root": "0x08c61b0c680f18a1f33a8bce9b09d0fffee3a595cd5c95519fa21e80894d87e9", | ||
"log_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000", | ||
"timestamp": "0x6538e7e0", | ||
"number": "0xe7c3", | ||
"gas_used": "0x2a3d5", | ||
"gas_limit": "0x1c9c380", | ||
"extra_data": [], | ||
"base_fee_per_gas": "0x539", | ||
"proof": { | ||
"number": "0xe7c2", | ||
"round": "0x0", | ||
"block_hash": "0x734f6e28a7caf9df326c21d8c57b89034ed02f782a11d04d18284b7aa4de43f0", | ||
"signature": "0x933be0cd674477473bd68a55a53511a652fbcecfa4cafaa244d0b55ca3f6a7f296d50a2744337365fd6407d737cc389f054b70b3c82ee27a1669a43cc344ba7ad42a7cc663faa63190a739dc1c6a1a5d80d45f5903f42d118fc5e4d695cc4815", | ||
"bitmap": "0xb0" | ||
}, | ||
"call_system_script_count": "0x0", | ||
"chain_id": "0x41786f6e" | ||
}, | ||
"tx_hashes": [ | ||
"0x6917d8ef5fbac4fab865a872cd4ed2ca9fd0c514491d7b148530392fa9d656c8" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
{ | ||
"version": { | ||
"start": "0x0", | ||
"end": "0x3b9aca00" | ||
}, | ||
"epoch": "0x0", | ||
"verifier_list": [ | ||
{ | ||
"bls_pub_key": "0x98eef09a3927acb225191101a1d9aa85775fdcdc87b9ba36898f6c132b485d66aef91c0f51cda331be4f985c3be6761c", | ||
"pub_key": "0x0232c489c23b1207107e9a24648c1e4754a8c1c0b38db96df57a526201035058cb", | ||
"address": "0xf4cc1652dcec2e5de9ce6fb1b6f9fa9456e957f1", | ||
"propose_weight": "0x1", | ||
"vote_weight": "0x1" | ||
}, | ||
{ | ||
"bls_pub_key": "0xa26e3fe1cf51bd4822072c61bdc315ac32e3d3c2e2484bb92942666399e863b4bf56cf2926383cc706ffc15dfebc85c6", | ||
"pub_key": "0x031ddc35212b7fc7ff6685b17d91f77c972535aee5c7ae5684d3e72b986f08834b", | ||
"address": "0x8ab0cf264df99d83525e9e11c7e4db01558ae1b1", | ||
"propose_weight": "0x1", | ||
"vote_weight": "0x1" | ||
}, | ||
{ | ||
"bls_pub_key": "0x80310fa9df724b5603d283b472ed3bf85254a8a4ceda8a274b421f6cf2be1d9184267cdfe9a199d36ff14e57668a55d0", | ||
"pub_key": "0x02b77c74eb68af3d4d6cc7884ed6709f1a2a1af0f713382a4438ec2ea3a70d4d7f", | ||
"address": "0xf386573563c3a75dbbd269fce9782620826ddac2", | ||
"propose_weight": "0x1", | ||
"vote_weight": "0x1" | ||
}, | ||
{ | ||
"bls_pub_key": "0x897721e9016864141a8b982a48217f66ef318ce598aa31842cddaaebe3cd7feab17050022afa6c2123aba39938fe4142", | ||
"pub_key": "0x027ffd6a6a231561f2afe5878b1c743323b34263d16787130b1815fe35649b0bf5", | ||
"address": "0x8af204ac5d7cb8815a6c53a50b72d01e729d3b22", | ||
"propose_weight": "0x1", | ||
"vote_weight": "0x1" | ||
} | ||
], | ||
"propose_counter": [ | ||
{ | ||
"address": "0x0000000000000000000000000000000000000000", | ||
"count": "0x0" | ||
} | ||
], | ||
"consensus_config": { | ||
"gas_limit": "0xffffffff", | ||
"gas_price": "0x1", | ||
"interval": "0xbb8", | ||
"propose_ratio": "0xf", | ||
"prevote_ratio": "0xa", | ||
"precommit_ratio": "0xa", | ||
"brake_ratio": "0xa", | ||
"tx_num_limit": "0x4e20", | ||
"max_tx_size": "0x400" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
mod verify_proof; | ||
mod verify_trie_proof; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"number": "0xe7c3", | ||
"round": "0x0", | ||
"block_hash": "0x6e48fa2d2002453abd9b51e4ac0342abb1f027b8272d6e27ce79a630b3f26673", | ||
"signature": "0xb3e8e27db04baec18c04bc0b8ffe7fdbf2b5f7d6ef243c8be02bfd75defee32f1c0ff73a9fa67fee24630d2da5aa70f111ba41c0212be5d91b95f3bb84e5c0406b4742cca8c8f8362c07024fd8081d16875b01f43c6aa11c60b196af8c671a9b", | ||
"bitmap": "0x70" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#[cfg(test)] | ||
mod tests { | ||
use crate::hash::keccak_256; | ||
use crate::types::{AxonBlock, BlockVersion, Metadata, Proof, Proposal, ValidatorExtend}; | ||
use bytes::Bytes; | ||
use ethereum_types::{H160, H256, U256}; | ||
use rlp::Encodable; | ||
use serde::de::DeserializeOwned; | ||
|
||
fn read_json<T: DeserializeOwned>(path: &str) -> T { | ||
let json = std::fs::read_to_string(path).unwrap(); | ||
serde_json::from_str(&json).unwrap() | ||
} | ||
|
||
#[test] | ||
fn test_proposal() { | ||
let proposal = Proposal { | ||
version: BlockVersion::V0, | ||
prev_hash: H256::from([1u8; 32]), | ||
proposer: H160::from([2u8; 20]), | ||
prev_state_root: H256::from([3u8; 32]), | ||
transactions_root: H256::from([4u8; 32]), | ||
signed_txs_hash: H256::from([5u8; 32]), | ||
timestamp: 0, | ||
number: 100, | ||
gas_limit: U256::from(6), | ||
extra_data: Vec::new(), | ||
base_fee_per_gas: U256::from(7), | ||
proof: Proof { | ||
number: 0, | ||
round: 1, | ||
block_hash: H256::from([1u8; 32]), | ||
signature: Bytes::from("1234"), | ||
bitmap: Bytes::from("abcd"), | ||
}, | ||
chain_id: 1000 as u64, | ||
call_system_script_count: 1, | ||
tx_hashes: vec![], | ||
}; | ||
|
||
let rlp_bytes = proposal.rlp_bytes(); | ||
let hash = keccak_256(&rlp_bytes); | ||
let ref_hash = [ | ||
95u8, 14, 98, 221, 57, 150, 113, 31, 144, 120, 33, 170, 102, 71, 19, 108, 141, 247, 85, | ||
17, 193, 76, 201, 242, 128, 231, 44, 231, 204, 189, 67, 230, | ||
]; | ||
assert_eq!(hash, ref_hash); | ||
} | ||
|
||
#[test] | ||
fn test_verify_proof() { | ||
let block: AxonBlock = read_json("src/tests/block.json"); | ||
let proof: Proof = read_json("src/tests/proof.json"); | ||
let metadata: Metadata = read_json("src/tests/metadata.json"); | ||
let mut validators = metadata | ||
.verifier_list | ||
.iter() | ||
.map(|v| ValidatorExtend { | ||
bls_pub_key: v.bls_pub_key.clone(), | ||
pub_key: v.pub_key.clone(), | ||
address: v.address, | ||
propose_weight: v.propose_weight, | ||
vote_weight: v.vote_weight, | ||
}) | ||
.collect::<Vec<_>>(); | ||
|
||
let previous_state_root = | ||
hex::decode("9fc948be2cfb0127e979dc9c7e6d2f4a2890b54e0e81fd69c687303e6b25ddde") | ||
.unwrap(); | ||
|
||
let result = crate::verify_proof( | ||
block, | ||
H256::from_slice(&previous_state_root), | ||
&mut validators, | ||
proof, | ||
); | ||
|
||
assert!(result.is_ok()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
#[cfg(test)] | ||
mod tests { | ||
use crate::verify_trie_proof; | ||
use eth_light_client_in_ckb_prover::{encode_receipt, Receipts}; | ||
use ethereum_types::{Bloom, H256, U256}; | ||
use ethers_core::{ | ||
types::{Log, TransactionReceipt, U64}, | ||
utils::{keccak256, rlp}, | ||
}; | ||
|
||
#[test] | ||
fn test_receipt() { | ||
let mut tx_receipts = Vec::<TransactionReceipt>::new(); | ||
|
||
{ | ||
let mut receipt = TransactionReceipt::default(); | ||
receipt.transaction_hash = H256::from([0u8; 32]); | ||
receipt.transaction_index = 0.into(); | ||
receipt.cumulative_gas_used = U256::from(10); | ||
receipt.transaction_type = Some(U64::from(2)); | ||
receipt.status = Some(U64::from(1)); | ||
let logs = vec![Log::default()]; | ||
receipt.logs_bloom = logs_bloom(logs.iter()); | ||
receipt.logs = logs; | ||
|
||
let receipt_encode = encode_receipt(&receipt); | ||
let reference_encode: Vec<u8> = [ | ||
2u8, 249, 1, 30, 1, 10, 185, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 215, 148, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 128, | ||
] | ||
.to_vec(); | ||
|
||
assert_eq!(receipt_encode, reference_encode); | ||
tx_receipts.push(receipt); | ||
} | ||
|
||
let receipts: Receipts = tx_receipts.into(); | ||
let ref_root = [ | ||
197u8, 180, 204, 76, 181, 157, 142, 152, 246, 237, 148, 126, 24, 207, 94, 119, 119, | ||
205, 11, 16, 193, 17, 102, 157, 61, 7, 166, 133, 173, 208, 124, 6, | ||
]; | ||
assert_eq!(receipts.root().0, ref_root); | ||
} | ||
|
||
#[test] | ||
fn test_verify_trie_proof() { | ||
let mut tx_receipts = Vec::<TransactionReceipt>::new(); | ||
|
||
{ | ||
let mut receipt = TransactionReceipt::default(); | ||
receipt.transaction_hash = H256::from([0u8; 32]); | ||
receipt.transaction_index = 0.into(); | ||
receipt.gas_used = Some(U256::from(100)); | ||
receipt.transaction_type = Some(U64::from(0)); | ||
receipt.status = Some(U64::from(1)); | ||
tx_receipts.push(receipt); | ||
} | ||
|
||
{ | ||
let mut receipt = TransactionReceipt::default(); | ||
receipt.transaction_hash = H256::from([1u8; 32]); | ||
receipt.transaction_index = 1.into(); | ||
receipt.gas_used = Some(U256::from(100)); | ||
receipt.transaction_type = Some(U64::from(1)); | ||
receipt.status = Some(U64::from(1)); | ||
tx_receipts.push(receipt); | ||
} | ||
|
||
let receipts: Receipts = tx_receipts.into(); | ||
|
||
{ | ||
println!("proof of index 0"); | ||
let proof_index = 0 as u64; | ||
let receipt_proof = receipts.generate_proof(proof_index as usize); | ||
|
||
{ | ||
println!("test key 0"); | ||
let key = rlp::encode(&proof_index); | ||
let result = verify_trie_proof(receipts.root(), &key, receipt_proof.clone()); | ||
assert!(result.unwrap().is_some()); | ||
} | ||
|
||
{ | ||
println!("test key 1"); | ||
let key = rlp::encode(&(1 as u64)); | ||
let result = verify_trie_proof(receipts.root(), &key, receipt_proof.clone()); | ||
assert!(result.unwrap().is_none()); | ||
} | ||
|
||
{ | ||
println!("test key 2"); | ||
let key = rlp::encode(&(2 as u64)); | ||
let result = verify_trie_proof(receipts.root(), &key, receipt_proof.clone()); | ||
assert!(result.unwrap().is_none()); | ||
} | ||
|
||
{ | ||
println!("test illegal trie root"); | ||
let key = rlp::encode(&(200 as u64)); | ||
let result = verify_trie_proof(H256::from([4u8; 32]), &key, receipt_proof.clone()); | ||
assert!(result.is_err()); | ||
} | ||
} | ||
|
||
{ | ||
println!("proof of index 1, wrong"); | ||
let proof_index = 1 as u64; | ||
let receipt_proof = receipts.generate_proof(proof_index as usize); | ||
|
||
{ | ||
println!("test key 0"); | ||
let key = rlp::encode(&(0 as u64)); | ||
let result = verify_trie_proof(receipts.root(), &key, receipt_proof.clone()); | ||
assert!(result.unwrap().is_none()); | ||
} | ||
|
||
{ | ||
println!("test key 1"); | ||
let key = rlp::encode(&(1 as u64)); | ||
let result = verify_trie_proof(receipts.root(), &key, receipt_proof.clone()); | ||
assert!(result.unwrap().is_some()); | ||
} | ||
} | ||
} | ||
|
||
pub fn logs_bloom<'a, I>(logs: I) -> Bloom | ||
where | ||
I: Iterator<Item = &'a Log>, | ||
{ | ||
let mut bloom = Bloom::zero(); | ||
|
||
for log in logs { | ||
m3_2048(&mut bloom, log.address.as_bytes()); | ||
for topic in log.topics.iter() { | ||
m3_2048(&mut bloom, topic.as_bytes()); | ||
} | ||
} | ||
bloom | ||
} | ||
|
||
pub struct Hasher; | ||
|
||
impl Hasher { | ||
pub fn digest<B: AsRef<[u8]>>(bytes: B) -> H256 { | ||
if bytes.as_ref().is_empty() { | ||
return NIL_DATA; | ||
} | ||
|
||
H256(keccak256(bytes)) | ||
} | ||
} | ||
|
||
pub const NIL_DATA: H256 = H256([ | ||
0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, | ||
0xc0, 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, | ||
0xa4, 0x70, | ||
]); | ||
const BLOOM_BYTE_LENGTH: usize = 256; | ||
|
||
fn m3_2048(bloom: &mut Bloom, x: &[u8]) { | ||
let hash = Hasher::digest(x).0; | ||
for i in [0, 2, 4] { | ||
let bit = (hash[i + 1] as usize + ((hash[i] as usize) << 8)) & 0x7FF; | ||
bloom.0[BLOOM_BYTE_LENGTH - 1 - bit / 8] |= 1 << (bit % 8); | ||
} | ||
} | ||
} |