From ef5f84070b6a9fa0289f87e5f987271d8c72a4b4 Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Tue, 26 Mar 2019 16:46:33 +0800 Subject: [PATCH 1/2] feat: segregated witness --- core/src/block.rs | 12 ++ core/src/header.rs | 15 ++ core/src/transaction.rs | 214 ++++++++++++++++++--------- protocol/src/builder.rs | 32 +++- protocol/src/convert.rs | 20 +++ protocol/src/lib.rs | 4 +- protocol/src/protocol.fbs | 7 +- protocol/src/protocol_generated.rs | 116 ++++++++++++++- rpc/src/module/pool.rs | 2 +- script/src/verify.rs | 103 ++++++++----- script/testdata/verify | Bin 1166000 -> 1209736 bytes script/testdata/verify.c | 14 +- shared/src/tx_pool/types.rs | 2 +- sync/src/relayer/mod.rs | 4 +- test/src/specs/mining.rs | 2 +- util/jsonrpc-types/src/blockchain.rs | 32 +++- verification/src/block_verifier.rs | 14 ++ verification/src/error.rs | 2 + 18 files changed, 459 insertions(+), 136 deletions(-) diff --git a/core/src/block.rs b/core/src/block.rs index 52cf42a454..615f79c923 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -142,6 +142,17 @@ impl BlockBuilder { .collect::>(), ); + // The witness hash of cellbase transaction is assumed to be zero 0x0000....0000 + let mut witnesses = vec![H256::zero()]; + witnesses.extend( + self.inner + .commit_transactions() + .iter() + .skip(1) + .map(|tx| tx.witness_hash()), + ); + let witnesses_root = merkle_root(&witnesses[..]); + let txs_proposal = merkle_root( &self .inner @@ -156,6 +167,7 @@ impl BlockBuilder { self.inner.header = header_builder .txs_commit(txs_commit) .txs_proposal(txs_proposal) + .witnesses_root(witnesses_root) .uncles_hash(uncles_hash) .uncles_count(self.inner.uncles.len() as u32) .build(); diff --git a/core/src/header.rs b/core/src/header.rs index 5ed65fe046..3e9148732d 100644 --- a/core/src/header.rs +++ b/core/src/header.rs @@ -53,6 +53,8 @@ pub struct RawHeader { txs_commit: H256, /// Transactions proposal merkle root. txs_proposal: H256, + /// Witness hash commitment. + witnesses_root: H256, /// Block difficulty. difficulty: U256, /// Hash of the cellbase @@ -112,6 +114,10 @@ impl fmt::Debug for Header { "txs_proposal", &format_args!("{:#x}", self.raw.txs_proposal), ) + .field( + "witnesses_root", + &format_args!("{:#x}", self.raw.witnesses_root), + ) .field("difficulty", &format_args!("{:#x}", self.raw.difficulty)) .field("cellbase_id", &format_args!("{:#x}", self.raw.cellbase_id)) .field("uncles_hash", &format_args!("{:#x}", self.raw.uncles_hash)) @@ -174,6 +180,10 @@ impl Header { &self.raw.txs_proposal } + pub fn witnesses_root(&self) -> &H256 { + &self.raw.witnesses_root + } + pub fn cellbase_id(&self) -> &H256 { &self.raw.cellbase_id } @@ -268,6 +278,11 @@ impl HeaderBuilder { self } + pub fn witnesses_root(mut self, hash: H256) -> Self { + self.inner.raw.witnesses_root = hash; + self + } + pub fn cellbase_id(mut self, hash: H256) -> Self { self.inner.raw.cellbase_id = hash; self diff --git a/core/src/transaction.rs b/core/src/transaction.rs index 67820cf676..6fe703a35a 100644 --- a/core/src/transaction.rs +++ b/core/src/transaction.rs @@ -141,91 +141,35 @@ impl CellOutput { } } +pub type Witness = Vec>; + #[derive(Clone, Serialize, Deserialize, Eq, Debug, Default, OccupiedCapacity)] pub struct Transaction { version: Version, deps: Vec, inputs: Vec, outputs: Vec, + //Segregated Witness to provide protection from transaction malleability. + witnesses: Vec, +} + +#[derive(Serialize)] +struct RawTransaction<'a> { + version: Version, + deps: &'a [OutPoint], + inputs: &'a [CellInput], + outputs: &'a [CellOutput], } impl Hash for Transaction { fn hash(&self, state: &mut H) { - state.write(self.hash().as_fixed_bytes()) + state.write(self.witness_hash().as_fixed_bytes()) } } impl PartialEq for Transaction { fn eq(&self, other: &Transaction) -> bool { - self.hash() == other.hash() - } -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct IndexTransaction { - pub index: usize, - pub transaction: Transaction, -} - -#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Default, Hash)] -pub struct ProposalShortId([u8; 10]); - -impl Deref for ProposalShortId { - type Target = [u8; 10]; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl fmt::Debug for ProposalShortId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "ProposalShortId(0x{})", - hex_string(&self.0).expect("hex proposal short id") - ) - } -} - -impl DerefMut for ProposalShortId { - fn deref_mut(&mut self) -> &mut [u8; 10] { - &mut self.0 - } -} - -impl ProposalShortId { - pub fn new(inner: [u8; 10]) -> Self { - ProposalShortId(inner) - } - - pub fn from_slice(slice: &[u8]) -> Option { - if slice.len() == 10usize { - let mut id = [0u8; 10]; - id.copy_from_slice(slice); - Some(ProposalShortId(id)) - } else { - None - } - } - - pub fn from_h256(h: &H256) -> Self { - let v = h.to_vec(); - let mut inner = [0u8; 10]; - inner.copy_from_slice(&v[..10]); - ProposalShortId(inner) - } - - pub fn hash(&self) -> H256 { - blake2b_256(serialize(self).expect("ProposalShortId serialize should not fail")).into() - } - - pub fn zero() -> Self { - ProposalShortId([0; 10]) - } - - pub fn into_inner(self) -> [u8; 10] { - self.0 + self.witness_hash() == other.witness_hash() } } @@ -246,11 +190,25 @@ impl Transaction { &self.outputs } + pub fn witnesses(&self) -> &[Witness] { + &self.witnesses + } + pub fn is_cellbase(&self) -> bool { self.inputs.len() == 1 && self.inputs[0].previous_output.is_null() } pub fn hash(&self) -> H256 { + let raw = RawTransaction { + version: self.version, + deps: &self.deps, + inputs: &self.inputs, + outputs: &self.outputs, + }; + blake2b_256(serialize(&raw).expect("Transaction serialize should not fail")).into() + } + + pub fn witness_hash(&self) -> H256 { blake2b_256(serialize(&self).expect("Transaction serialize should not fail")).into() } @@ -284,8 +242,9 @@ impl Transaction { self.inputs.is_empty() || self.outputs.is_empty() } + // proposal_short_id pub fn proposal_short_id(&self) -> ProposalShortId { - ProposalShortId::from_h256(&self.hash()) + ProposalShortId::from_tx_hash(&self.hash()) } pub fn get_output(&self, i: usize) -> Option { @@ -364,7 +323,120 @@ impl TransactionBuilder { self } + pub fn witness(mut self, witness: Witness) -> Self { + self.inner.witnesses.push(witness); + self + } + + pub fn witnesses(mut self, witness: Vec) -> Self { + self.inner.witnesses.extend(witness); + self + } + + pub fn witnesses_clear(mut self) -> Self { + self.inner.witnesses.clear(); + self + } + pub fn build(self) -> Transaction { self.inner } } + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct IndexTransaction { + pub index: usize, + pub transaction: Transaction, +} + +#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Default, Hash)] +pub struct ProposalShortId([u8; 10]); + +impl Deref for ProposalShortId { + type Target = [u8; 10]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl fmt::Debug for ProposalShortId { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "ProposalShortId(0x{})", + hex_string(&self.0).expect("hex proposal short id") + ) + } +} + +impl DerefMut for ProposalShortId { + fn deref_mut(&mut self) -> &mut [u8; 10] { + &mut self.0 + } +} + +impl ProposalShortId { + pub fn new(inner: [u8; 10]) -> Self { + ProposalShortId(inner) + } + + pub fn from_slice(slice: &[u8]) -> Option { + if slice.len() == 10usize { + let mut id = [0u8; 10]; + id.copy_from_slice(slice); + Some(ProposalShortId(id)) + } else { + None + } + } + + pub fn from_tx_hash(h: &H256) -> Self { + let v = h.to_vec(); + let mut inner = [0u8; 10]; + inner.copy_from_slice(&v[..10]); + ProposalShortId(inner) + } + + pub fn hash(&self) -> H256 { + blake2b_256(serialize(self).expect("ProposalShortId serialize should not fail")).into() + } + + pub fn zero() -> Self { + ProposalShortId([0; 10]) + } + + pub fn into_inner(self) -> [u8; 10] { + self.0 + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_tx_hash() { + let tx = TransactionBuilder::default() + .output(CellOutput::new( + 5000, + vec![1, 2, 3], + Script::default(), + None, + )) + .input(CellInput::new(OutPoint::new(H256::zero(), 0), vec![])) + .witness(vec![vec![7, 8, 9]]) + .build(); + + assert_eq!( + tx.hash(), + H256::from_hex_str("7e1e256d6882809b7dfb55d002e54c5b4fbdbbbe8ce906aa6eae1b429de4d3d8") + .unwrap() + ); + assert_eq!( + tx.witness_hash(), + H256::from_hex_str("93d363096f3901651b718d093751aa78ce7b56274850841a3e4134fe14ffb120") + .unwrap() + ); + } +} diff --git a/protocol/src/builder.rs b/protocol/src/builder.rs index 64c11b93ca..c3b7ff6b0e 100644 --- a/protocol/src/builder.rs +++ b/protocol/src/builder.rs @@ -10,7 +10,8 @@ use crate::protocol_generated::ckb::protocol::{ Script as FbsScript, ScriptBuilder, SyncMessage, SyncMessageBuilder, SyncPayload, Time as FbsTime, TimeBuilder, TimeMessage, TimeMessageBuilder, Transaction as FbsTransaction, TransactionBuilder, UncleBlock as FbsUncleBlock, UncleBlockBuilder, - ValidTransaction as FbsValidTransaction, ValidTransactionBuilder, H256 as FbsH256, + ValidTransaction as FbsValidTransaction, ValidTransactionBuilder, Witness as FbsWitness, + WitnessBuilder, H256 as FbsH256, }; use crate::{short_transaction_id, short_transaction_id_keys}; use ckb_core::block::Block; @@ -47,6 +48,7 @@ impl<'a> FbsHeader<'a> { let parent_hash = header.parent_hash().into(); let txs_commit = header.txs_commit().into(); let txs_proposal = header.txs_proposal().into(); + let witnesses_root = header.witnesses_root().into(); let difficulty = FbsBytes::build(fbb, &uint_to_bytes(header.difficulty())); let proof = FbsBytes::build(fbb, &header.proof()); let cellbase_id = header.cellbase_id().into(); @@ -58,6 +60,7 @@ impl<'a> FbsHeader<'a> { builder.add_number(header.number()); builder.add_txs_commit(&txs_commit); builder.add_txs_proposal(&txs_proposal); + builder.add_witnesses_root(&witnesses_root); builder.add_difficulty(difficulty); builder.add_nonce(header.nonce()); builder.add_proof(proof); @@ -94,11 +97,19 @@ impl<'a> FbsTransaction<'a> { .collect::>(); let outputs = fbb.create_vector(&vec); + let vec = transaction + .witnesses() + .iter() + .map(|witness| FbsWitness::build(fbb, witness)) + .collect::>(); + let witnesses = fbb.create_vector(&vec); + let mut builder = TransactionBuilder::new(fbb); builder.add_version(transaction.version()); builder.add_deps(deps); builder.add_inputs(inputs); builder.add_outputs(outputs); + builder.add_witnesses(witnesses); builder.finish() } } @@ -171,6 +182,23 @@ impl<'a> FbsScript<'a> { } } +impl<'a> FbsWitness<'a> { + pub fn build<'b>( + fbb: &mut FlatBufferBuilder<'b>, + witness: &[Vec], + ) -> WIPOffset> { + let data = witness + .iter() + .map(|item| FbsBytes::build(fbb, item)) + .collect::>(); + + let data = fbb.create_vector(&data); + let mut builder = WitnessBuilder::new(fbb); + builder.add_data(data); + builder.finish() + } +} + impl<'a> FbsCellOutput<'a> { pub fn build<'b>( fbb: &mut FlatBufferBuilder<'b>, @@ -447,7 +475,7 @@ impl<'a> CompactBlock<'a> { } else { short_ids.push(FbsBytes::build( fbb, - &short_transaction_id(key0, key1, &transaction.hash()), + &short_transaction_id(key0, key1, &transaction.witness_hash()), )); } } diff --git a/protocol/src/convert.rs b/protocol/src/convert.rs index 762dc36bd0..1f27475dc0 100644 --- a/protocol/src/convert.rs +++ b/protocol/src/convert.rs @@ -153,6 +153,7 @@ impl<'a> TryFrom> for ckb_core::header::Header { let parent_hash = cast!(header.parent_hash())?; let txs_commit = cast!(header.txs_commit())?; let txs_proposal = cast!(header.txs_proposal())?; + let witnesses_root = cast!(header.witnesses_root())?; let cellbase_id = cast!(header.cellbase_id())?; let uncles_hash = cast!(header.uncles_hash())?; @@ -163,6 +164,7 @@ impl<'a> TryFrom> for ckb_core::header::Header { .number(header.number()) .txs_commit(TryInto::try_into(txs_commit)?) .txs_proposal(TryInto::try_into(txs_proposal)?) + .witnesses_root(TryInto::try_into(witnesses_root)?) .difficulty(U256::from_little_endian(cast!(header .difficulty() .and_then(|d| d.seq()))?)?) @@ -197,11 +199,17 @@ impl<'a> TryFrom> for ckb_core::transaction::Trans .map(TryInto::try_into) .collect(); + let witnesses: Result, FailureError> = + FlatbuffersVectorIterator::new(cast!(transaction.witnesses())?) + .map(TryInto::try_into) + .collect(); + Ok(ckb_core::transaction::TransactionBuilder::default() .version(transaction.version()) .deps(deps?) .inputs(inputs?) .outputs(outputs?) + .witnesses(witnesses?) .build()) } } @@ -218,6 +226,18 @@ impl<'a> TryFrom> } } +impl<'a> TryFrom> for ckb_core::transaction::Witness { + type Error = FailureError; + + fn try_from(wit: ckb_protocol::Witness<'a>) -> Result { + let data: Option>> = FlatbuffersVectorIterator::new(cast!(wit.data())?) + .map(|item| item.seq().map(|s| s.to_vec())) + .collect(); + + Ok(cast!(data)?) + } +} + impl<'a> TryFrom> for ckb_core::transaction::OutPoint { type Error = FailureError; diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 76babd8d12..09511ab75e 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -67,9 +67,9 @@ pub fn short_transaction_id_keys(header_nonce: u64, random_nonce: u64) -> (u64, (key0, key1) } -pub fn short_transaction_id(key0: u64, key1: u64, transaction_hash: &H256) -> ShortTransactionID { +pub fn short_transaction_id(key0: u64, key1: u64, witness_hash: &H256) -> ShortTransactionID { let mut hasher = SipHasher::new_with_keys(key0, key1); - hasher.write(transaction_hash.as_bytes()); + hasher.write(witness_hash.as_bytes()); let siphash_transaction_hash = hasher.finish(); let siphash_transaction_hash_bytes = siphash_transaction_hash.to_le_bytes(); diff --git a/protocol/src/protocol.fbs b/protocol/src/protocol.fbs index 475b0ad1e9..2e11202660 100644 --- a/protocol/src/protocol.fbs +++ b/protocol/src/protocol.fbs @@ -40,6 +40,7 @@ table Header { number: uint64; txs_commit: H256; txs_proposal: H256; + witnesses_root: H256; difficulty: Bytes; nonce: uint64; proof: Bytes; @@ -66,6 +67,11 @@ table Transaction { deps: [OutPoint]; inputs: [CellInput]; outputs: [CellOutput]; + witnesses: [Witness]; +} + +table Witness { + data: [Bytes]; } table OutPoint { @@ -224,4 +230,3 @@ table TimeMessage { table Time { timestamp: uint64; } - diff --git a/protocol/src/protocol_generated.rs b/protocol/src/protocol_generated.rs index 226a4f90d7..cec97603e4 100644 --- a/protocol/src/protocol_generated.rs +++ b/protocol/src/protocol_generated.rs @@ -1,6 +1,10 @@ // automatically generated by the FlatBuffers compiler, do not modify +#![allow(dead_code)] +#![allow(unused_imports)] +extern crate flatbuffers; + pub mod ckb { #![allow(dead_code)] #![allow(unused_imports)] @@ -1023,6 +1027,7 @@ impl<'a> Header<'a> { if let Some(x) = args.cellbase_id { builder.add_cellbase_id(x); } if let Some(x) = args.proof { builder.add_proof(x); } if let Some(x) = args.difficulty { builder.add_difficulty(x); } + if let Some(x) = args.witnesses_root { builder.add_witnesses_root(x); } if let Some(x) = args.txs_proposal { builder.add_txs_proposal(x); } if let Some(x) = args.txs_commit { builder.add_txs_commit(x); } if let Some(x) = args.parent_hash { builder.add_parent_hash(x); } @@ -1036,12 +1041,13 @@ impl<'a> Header<'a> { pub const VT_NUMBER: flatbuffers::VOffsetT = 10; pub const VT_TXS_COMMIT: flatbuffers::VOffsetT = 12; pub const VT_TXS_PROPOSAL: flatbuffers::VOffsetT = 14; - pub const VT_DIFFICULTY: flatbuffers::VOffsetT = 16; - pub const VT_NONCE: flatbuffers::VOffsetT = 18; - pub const VT_PROOF: flatbuffers::VOffsetT = 20; - pub const VT_CELLBASE_ID: flatbuffers::VOffsetT = 22; - pub const VT_UNCLES_HASH: flatbuffers::VOffsetT = 24; - pub const VT_UNCLES_COUNT: flatbuffers::VOffsetT = 26; + pub const VT_WITNESSES_ROOT: flatbuffers::VOffsetT = 16; + pub const VT_DIFFICULTY: flatbuffers::VOffsetT = 18; + pub const VT_NONCE: flatbuffers::VOffsetT = 20; + pub const VT_PROOF: flatbuffers::VOffsetT = 22; + pub const VT_CELLBASE_ID: flatbuffers::VOffsetT = 24; + pub const VT_UNCLES_HASH: flatbuffers::VOffsetT = 26; + pub const VT_UNCLES_COUNT: flatbuffers::VOffsetT = 28; #[inline] pub fn version(&self) -> u32 { @@ -1068,6 +1074,10 @@ impl<'a> Header<'a> { self._tab.get::(Header::VT_TXS_PROPOSAL, None) } #[inline] + pub fn witnesses_root(&self) -> Option<&'a H256> { + self._tab.get::(Header::VT_WITNESSES_ROOT, None) + } + #[inline] pub fn difficulty(&self) -> Option> { self._tab.get::>>(Header::VT_DIFFICULTY, None) } @@ -1100,6 +1110,7 @@ pub struct HeaderArgs<'a> { pub number: u64, pub txs_commit: Option<&'a H256>, pub txs_proposal: Option<&'a H256>, + pub witnesses_root: Option<&'a H256>, pub difficulty: Option>>, pub nonce: u64, pub proof: Option>>, @@ -1117,6 +1128,7 @@ impl<'a> Default for HeaderArgs<'a> { number: 0, txs_commit: None, txs_proposal: None, + witnesses_root: None, difficulty: None, nonce: 0, proof: None, @@ -1156,6 +1168,10 @@ impl<'a: 'b, 'b> HeaderBuilder<'a, 'b> { self.fbb_.push_slot_always::<&H256>(Header::VT_TXS_PROPOSAL, txs_proposal); } #[inline] + pub fn add_witnesses_root(&mut self, witnesses_root: &'b H256) { + self.fbb_.push_slot_always::<&H256>(Header::VT_WITNESSES_ROOT, witnesses_root); + } + #[inline] pub fn add_difficulty(&mut self, difficulty: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(Header::VT_DIFFICULTY, difficulty); } @@ -1435,6 +1451,7 @@ impl<'a> Transaction<'a> { _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args TransactionArgs<'args>) -> flatbuffers::WIPOffset> { let mut builder = TransactionBuilder::new(_fbb); + if let Some(x) = args.witnesses { builder.add_witnesses(x); } if let Some(x) = args.outputs { builder.add_outputs(x); } if let Some(x) = args.inputs { builder.add_inputs(x); } if let Some(x) = args.deps { builder.add_deps(x); } @@ -1446,6 +1463,7 @@ impl<'a> Transaction<'a> { pub const VT_DEPS: flatbuffers::VOffsetT = 6; pub const VT_INPUTS: flatbuffers::VOffsetT = 8; pub const VT_OUTPUTS: flatbuffers::VOffsetT = 10; + pub const VT_WITNESSES: flatbuffers::VOffsetT = 12; #[inline] pub fn version(&self) -> u32 { @@ -1463,6 +1481,10 @@ impl<'a> Transaction<'a> { pub fn outputs(&self) -> Option>>> { self._tab.get::>>>>(Transaction::VT_OUTPUTS, None) } + #[inline] + pub fn witnesses(&self) -> Option>>> { + self._tab.get::>>>>(Transaction::VT_WITNESSES, None) + } } pub struct TransactionArgs<'a> { @@ -1470,6 +1492,7 @@ pub struct TransactionArgs<'a> { pub deps: Option>>>>, pub inputs: Option>>>>, pub outputs: Option>>>>, + pub witnesses: Option>>>>, } impl<'a> Default for TransactionArgs<'a> { #[inline] @@ -1479,6 +1502,7 @@ impl<'a> Default for TransactionArgs<'a> { deps: None, inputs: None, outputs: None, + witnesses: None, } } } @@ -1504,6 +1528,10 @@ impl<'a: 'b, 'b> TransactionBuilder<'a, 'b> { self.fbb_.push_slot_always::>(Transaction::VT_OUTPUTS, outputs); } #[inline] + pub fn add_witnesses(&mut self, witnesses: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(Transaction::VT_WITNESSES, witnesses); + } + #[inline] pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TransactionBuilder<'a, 'b> { let start = _fbb.start_table(); TransactionBuilder { @@ -1518,6 +1546,82 @@ impl<'a: 'b, 'b> TransactionBuilder<'a, 'b> { } } +pub enum WitnessOffset {} +#[derive(Copy, Clone, Debug, PartialEq)] + +pub struct Witness<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for Witness<'a> { + type Inner = Witness<'a>; + #[inline] + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table { buf: buf, loc: loc }, + } + } +} + +impl<'a> Witness<'a> { + #[inline] + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + Witness { + _tab: table, + } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args WitnessArgs<'args>) -> flatbuffers::WIPOffset> { + let mut builder = WitnessBuilder::new(_fbb); + if let Some(x) = args.data { builder.add_data(x); } + builder.finish() + } + + pub const VT_DATA: flatbuffers::VOffsetT = 4; + + #[inline] + pub fn data(&self) -> Option>>> { + self._tab.get::>>>>(Witness::VT_DATA, None) + } +} + +pub struct WitnessArgs<'a> { + pub data: Option>>>>, +} +impl<'a> Default for WitnessArgs<'a> { + #[inline] + fn default() -> Self { + WitnessArgs { + data: None, + } + } +} +pub struct WitnessBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b> WitnessBuilder<'a, 'b> { + #[inline] + pub fn add_data(&mut self, data: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(Witness::VT_DATA, data); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> WitnessBuilder<'a, 'b> { + let start = _fbb.start_table(); + WitnessBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + pub enum OutPointOffset {} #[derive(Copy, Clone, Debug, PartialEq)] diff --git a/rpc/src/module/pool.rs b/rpc/src/module/pool.rs index a101d4dddc..288837afca 100644 --- a/rpc/src/module/pool.rs +++ b/rpc/src/module/pool.rs @@ -75,7 +75,7 @@ impl PoolRpc for PoolRpcImpl { } fn get_pool_transaction(&self, hash: H256) -> Result> { - let id = ProposalShortId::from_h256(&hash); + let id = ProposalShortId::from_tx_hash(&hash); Ok(self .shared .chain_state() diff --git a/script/src/verify.rs b/script/src/verify.rs index 2c94a9999d..067eeff61f 100644 --- a/script/src/verify.rs +++ b/script/src/verify.rs @@ -23,6 +23,7 @@ pub struct TransactionScriptsVerifier<'a> { tx_builder: FlatBufferBuilder<'a>, input_cells: Vec<&'a CellOutput>, dep_cells: Vec<&'a CellOutput>, + witnesses: FnvHashMap]>, hash: H256, } @@ -46,11 +47,18 @@ impl<'a> TransactionScriptsVerifier<'a> { .collect(); let inputs = rtx.transaction.inputs().iter().collect(); let outputs = rtx.transaction.outputs().iter().collect(); + let witnesses: FnvHashMap]> = rtx + .transaction + .witnesses() + .iter() + .enumerate() + .map(|(idx, wit)| (idx as u32, &wit[..])) + .collect(); - let mut binary_index: FnvHashMap = FnvHashMap::default(); - for dep_cell in &dep_cells { - binary_index.insert(dep_cell.data_hash(), &dep_cell.data); - } + let binary_index: FnvHashMap = dep_cells + .iter() + .map(|dep_cell| (dep_cell.data_hash(), &dep_cell.data[..])) + .collect(); let mut tx_builder = FlatBufferBuilder::new(); let tx_offset = build_tx(&mut tx_builder, &rtx.transaction); @@ -63,6 +71,7 @@ impl<'a> TransactionScriptsVerifier<'a> { outputs, input_cells, dep_cells, + witnesses, hash: rtx.transaction.hash().clone(), } } @@ -106,6 +115,7 @@ impl<'a> TransactionScriptsVerifier<'a> { script: &Script, prefix: &str, current_cell: &'a CellOutput, + witness: Option<&&'a [Vec]>, current_input: Option<&'a CellInput>, max_cycles: Cycle, ) -> Result { @@ -118,6 +128,9 @@ impl<'a> TransactionScriptsVerifier<'a> { if let Some(ref input) = current_input { args.extend_from_slice(&input.args.as_slice()); } + if let Some(witness) = witness { + args.extend_from_slice(&witness); + } let core_machine = DefaultCoreMachine::>::new_with_max_cycles(max_cycles); @@ -145,9 +158,11 @@ impl<'a> TransactionScriptsVerifier<'a> { pub fn verify(&self, max_cycles: Cycle) -> Result { let mut cycles = 0; - for (i, input) in self.inputs.iter().enumerate() { + for (i, (input, input_cell)) in self.inputs.iter().zip(self.input_cells.iter()).enumerate() + { let prefix = format!("Transaction {}, input {}", self.hash, i); - let cycle = self.verify_script(&self.input_cells[i].lock, &prefix, self.input_cells[i], Some(input), max_cycles - cycles).map_err(|e| { + let witness = self.witnesses.get(&(i as u32)); + let cycle = self.verify_script(&input_cell.lock, &prefix, input_cell, witness, Some(input), max_cycles - cycles).map_err(|e| { info!(target: "script", "Error validating input {} of transaction {}: {:?}", i, self.hash, e); e })?; @@ -162,7 +177,7 @@ impl<'a> TransactionScriptsVerifier<'a> { for (i, output) in self.outputs.iter().enumerate() { if let Some(ref type_) = output.type_ { let prefix = format!("Transaction {}, output {}", self.hash, i); - let cycle = self.verify_script(type_, &prefix, output, None, max_cycles - cycles).map_err(|e| { + let cycle = self.verify_script(type_, &prefix, output, None, None, max_cycles - cycles).map_err(|e| { info!(target: "script", "Error validating output {} of transaction {}: {:?}", i, self.hash, e); e })?; @@ -224,7 +239,8 @@ mod tests { let gen = Generator::new(); let privkey = gen.random_privkey(); - let mut args = vec![b"foo".to_vec(), b"bar".to_vec()]; + let args = vec![b"foo".to_vec(), b"bar".to_vec()]; + let mut witness_data = vec![]; let mut bytes = vec![]; for argument in &args { @@ -237,12 +253,12 @@ mod tests { let signature_der = signature.serialize_der(); let mut hex_signature = vec![0; signature_der.len() * 2]; hex_encode(&signature_der, &mut hex_signature).expect("hex signature"); - args.insert(0, hex_signature); + witness_data.insert(0, hex_signature); - let privkey = privkey.pubkey().unwrap().serialize(); - let mut hex_privkey = vec![0; privkey.len() * 2]; - hex_encode(&privkey, &mut hex_privkey).expect("hex privkey"); - args.insert(0, hex_privkey); + let pubkey = privkey.pubkey().unwrap().serialize(); + let mut hex_pubkey = vec![0; pubkey.len() * 2]; + hex_encode(&pubkey, &mut hex_pubkey).expect("hex pubkey"); + witness_data.insert(0, hex_pubkey); let binary_hash: H256 = (&blake2b_256(&buffer)).into(); let dep_out_point = OutPoint::new(H256::from_trimmed_hex_str("123").unwrap(), 8); @@ -254,6 +270,7 @@ mod tests { let transaction = TransactionBuilder::default() .input(input.clone()) .dep(dep_out_point) + .witness(witness_data) .build(); let dummy_cell = CellOutput::new(100, vec![], script, None); @@ -277,7 +294,8 @@ mod tests { let gen = Generator::new(); let privkey = gen.random_privkey(); - let mut args = vec![b"foo".to_vec(), b"bar".to_vec()]; + let args = vec![b"foo".to_vec(), b"bar".to_vec()]; + let mut witness_data = vec![]; let mut bytes = vec![]; for argument in &args { @@ -290,12 +308,12 @@ mod tests { let signature_der = signature.serialize_der(); let mut hex_signature = vec![0; signature_der.len() * 2]; hex_encode(&signature_der, &mut hex_signature).expect("hex privkey"); - args.insert(0, hex_signature); + witness_data.insert(0, hex_signature); - let privkey = privkey.pubkey().unwrap().serialize(); - let mut hex_privkey = vec![0; privkey.len() * 2]; - hex_encode(&privkey, &mut hex_privkey).expect("hex privkey"); - args.insert(0, hex_privkey); + let pubkey = privkey.pubkey().unwrap().serialize(); + let mut hex_pubkey = vec![0; pubkey.len() * 2]; + hex_encode(&pubkey, &mut hex_pubkey).expect("hex pubkey"); + witness_data.insert(0, hex_pubkey); let binary_hash: H256 = (&blake2b_256(&buffer)).into(); let dep_out_point = OutPoint::new(H256::from_trimmed_hex_str("123").unwrap(), 8); @@ -307,6 +325,7 @@ mod tests { let transaction = TransactionBuilder::default() .input(input.clone()) .dep(dep_out_point) + .witness(witness_data) .build(); let dummy_cell = CellOutput::new(100, vec![], script, None); @@ -331,6 +350,7 @@ mod tests { let gen = Generator::new(); let privkey = gen.random_privkey(); let mut args = vec![b"foo".to_vec(), b"bar".to_vec()]; + let mut witness_data = vec![]; let mut bytes = vec![]; for argument in &args { @@ -343,14 +363,14 @@ mod tests { let signature_der = signature.serialize_der(); let mut hex_signature = vec![0; signature_der.len() * 2]; hex_encode(&signature_der, &mut hex_signature).expect("hex privkey"); - args.insert(0, hex_signature); + witness_data.insert(0, hex_signature); // This line makes the verification invalid args.push(b"extrastring".to_vec()); - let privkey = privkey.pubkey().unwrap().serialize(); - let mut hex_privkey = vec![0; privkey.len() * 2]; - hex_encode(&privkey, &mut hex_privkey).expect("hex privkey"); - args.insert(0, hex_privkey); + let pubkey = privkey.pubkey().unwrap().serialize(); + let mut hex_pubkey = vec![0; pubkey.len() * 2]; + hex_encode(&pubkey, &mut hex_pubkey).expect("hex pubkey"); + witness_data.insert(0, hex_pubkey); let binary_hash: H256 = (&blake2b_256(&buffer)).into(); let dep_out_point = OutPoint::new(H256::from_trimmed_hex_str("123").unwrap(), 8); @@ -362,6 +382,7 @@ mod tests { let transaction = TransactionBuilder::default() .input(input.clone()) .dep(dep_out_point) + .witness(witness_data) .build(); let dummy_cell = CellOutput::new(100, vec![], script, None); @@ -385,7 +406,8 @@ mod tests { let gen = Generator::new(); let privkey = gen.random_privkey(); - let mut args = vec![b"foo".to_vec(), b"bar".to_vec()]; + let args = vec![b"foo".to_vec(), b"bar".to_vec()]; + let mut witness_data = vec![]; let mut bytes = vec![]; for argument in &args { @@ -397,14 +419,14 @@ mod tests { let signature_der = signature.serialize_der(); let mut hex_signature = vec![0; signature_der.len() * 2]; hex_encode(&signature_der, &mut hex_signature).expect("hex privkey"); - args.insert(0, hex_signature); + witness_data.insert(0, hex_signature); let dep_out_point = OutPoint::new(H256::from_trimmed_hex_str("123").unwrap(), 8); - let privkey = privkey.pubkey().unwrap().serialize(); - let mut hex_privkey = vec![0; privkey.len() * 2]; - hex_encode(&privkey, &mut hex_privkey).expect("hex privkey"); - args.insert(0, hex_privkey); + let pubkey = privkey.pubkey().unwrap().serialize(); + let mut hex_pubkey = vec![0; pubkey.len() * 2]; + hex_encode(&pubkey, &mut hex_pubkey).expect("hex pubkey"); + witness_data.insert(0, hex_pubkey); let binary_hash: H256 = (&blake2b_256(&buffer)).into(); let script = Script::new(0, args, binary_hash); @@ -413,6 +435,7 @@ mod tests { let transaction = TransactionBuilder::default() .input(input.clone()) .dep(dep_out_point) + .witness(witness_data) .build(); let dummy_cell = CellOutput::new(100, vec![], script, None); @@ -446,15 +469,15 @@ mod tests { let hash2 = sha3_256(hash1); let signature = privkey.sign_recoverable(&hash2.into()).unwrap(); + let pubkey = privkey.pubkey().unwrap().serialize(); + let mut hex_pubkey = vec![0; pubkey.len() * 2]; + hex_encode(&pubkey, &mut hex_pubkey).expect("hex pubkey"); + args.push(hex_pubkey); + let signature_der = signature.serialize_der(); let mut hex_signature = vec![0; signature_der.len() * 2]; hex_encode(&signature_der, &mut hex_signature).expect("hex privkey"); - args.insert(0, hex_signature); - - let privkey = privkey.pubkey().unwrap().serialize(); - let mut hex_privkey = vec![0; privkey.len() * 2]; - hex_encode(&privkey, &mut hex_privkey).expect("hex privkey"); - args.insert(0, hex_privkey); + args.push(hex_signature); let input = CellInput::new(OutPoint::null(), vec![]); let dummy_cell = CellOutput::new(100, vec![], Script::always_success(), None); @@ -512,10 +535,10 @@ mod tests { // This line makes the verification invalid args.push(b"extrastring".to_vec()); - let privkey = privkey.pubkey().unwrap().serialize(); - let mut hex_privkey = vec![0; privkey.len() * 2]; - hex_encode(&privkey, &mut hex_privkey).expect("hex privkey"); - args.insert(0, hex_privkey); + let pubkey = privkey.pubkey().unwrap().serialize(); + let mut hex_pubkey = vec![0; pubkey.len() * 2]; + hex_encode(&pubkey, &mut hex_pubkey).expect("hex pubkey"); + args.insert(0, hex_pubkey); let input = CellInput::new(OutPoint::null(), vec![]); let dummy_cell = CellOutput::new(100, vec![], Script::always_success(), None); diff --git a/script/testdata/verify b/script/testdata/verify index b25897b88372a8e1a907ed5e229d34b7d142663a..64158a768626230847fd68618d537a7948d7a3fa 100755 GIT binary patch delta 84763 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 OUEL(>*zn~{`2Pp&F<}t^ delta 40555 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 Fe*w`66t4gP diff --git a/script/testdata/verify.c b/script/testdata/verify.c index 176ef8dd66..9c3a1a4402 100644 --- a/script/testdata/verify.c +++ b/script/testdata/verify.c @@ -63,13 +63,13 @@ int hex_to_bin(char* buf, size_t buf_len, const char* hex) /* * Arguments are listed in the following order: * 0. Program name, ignored here, only preserved for compatibility reason - * 1. Pubkey in hex format, a maximum of 130 bytes will be processed - * 2. Signature in hex format, a maximum of 512 bytes will be processed - * 3. Current script hash in hex format, which is 128 bytes. While this program + * 1. Current script hash in hex format, which is 128 bytes. While this program * cannot verify the hash directly, this ensures the script is include in * signature calculation - * 4. Other additional parameters that might be included. Notice only ASCII + * 2. Other additional parameters that might be included. Notice only ASCII * characters are included, so binary should be passed as binary format. + * 3. Pubkey in hex format, a maximum of 130 bytes will be processed + * 4. Signature in hex format, a maximum of 512 bytes will be processed * * This program will run double sha256 on all arguments excluding pubkey and * signature(also for simplicity, we are running sha256 on ASCII chars directly, @@ -95,7 +95,7 @@ int main(int argc, char* argv[]) return 4; } - len = hex_to_bin(buf, 65, argv[1]); + len = hex_to_bin(buf, 65, argv[argc - 2]); CHECK_LEN(len); secp256k1_pubkey pubkey; @@ -104,7 +104,7 @@ int main(int argc, char* argv[]) return 1; } - len = hex_to_bin(buf, 256, argv[2]); + len = hex_to_bin(buf, 256, argv[argc - 1]); CHECK_LEN(len); secp256k1_ecdsa_signature signature; secp256k1_ecdsa_signature_parse_der(&context, &signature, buf, len); @@ -115,7 +115,7 @@ int main(int argc, char* argv[]) sha3_ctx_t sha3_ctx; unsigned char hash[SHA3_BLOCK_SIZE]; sha3_init(&sha3_ctx, SHA3_BLOCK_SIZE); - for (int i = 3; i < argc; i++) { + for (int i = 1; i < argc -2; i++) { sha3_update(&sha3_ctx, argv[i], strlen(argv[i])); } sha3_final(hash, &sha3_ctx); diff --git a/shared/src/tx_pool/types.rs b/shared/src/tx_pool/types.rs index b1e49ad50c..d6ff0b313a 100644 --- a/shared/src/tx_pool/types.rs +++ b/shared/src/tx_pool/types.rs @@ -252,7 +252,7 @@ impl StagingPool { pub fn get_output(&self, o: &OutPoint) -> Option { self.vertices - .get(&ProposalShortId::from_h256(&o.hash)) + .get(&ProposalShortId::from_tx_hash(&o.hash)) .and_then(|x| x.transaction.get_output(o.index as usize)) } diff --git a/sync/src/relayer/mod.rs b/sync/src/relayer/mod.rs index 6f283e01b3..7797c45231 100644 --- a/sync/src/relayer/mod.rs +++ b/sync/src/relayer/mod.rs @@ -190,7 +190,7 @@ where let mut txs_map: FnvHashMap = transactions .into_iter() .map(|tx| { - let short_id = short_transaction_id(key0, key1, &tx.hash()); + let short_id = short_transaction_id(key0, key1, &tx.witness_hash()); (short_id, tx) }) .collect(); @@ -198,7 +198,7 @@ where { let tx_pool = chain_state.tx_pool(); let iter = tx_pool.staging_txs_iter().filter_map(|entry| { - let short_id = short_transaction_id(key0, key1, &entry.transaction.hash()); + let short_id = short_transaction_id(key0, key1, &entry.transaction.witness_hash()); if compact_block.short_ids.contains(&short_id) { Some((short_id, entry.transaction.clone())) } else { diff --git a/test/src/specs/mining.rs b/test/src/specs/mining.rs index 6aa40f27f7..58c801e6bd 100644 --- a/test/src/specs/mining.rs +++ b/test/src/specs/mining.rs @@ -38,7 +38,7 @@ impl Spec for MiningBasic { assert!(block1 .proposal_transactions() .iter() - .any(|id| ProposalShortId::from_h256(&transaction_hash).eq(id))); + .any(|id| ProposalShortId::from_tx_hash(&transaction_hash).eq(id))); info!("Generated tx should be included in next + n block's commit txs, current n = 2"); assert!(block3 diff --git a/util/jsonrpc-types/src/blockchain.rs b/util/jsonrpc-types/src/blockchain.rs index 2900335bff..057e685a1f 100644 --- a/util/jsonrpc-types/src/blockchain.rs +++ b/util/jsonrpc-types/src/blockchain.rs @@ -5,7 +5,7 @@ use ckb_core::header::{Header as CoreHeader, HeaderBuilder, Seal as CoreSeal}; use ckb_core::script::Script as CoreScript; use ckb_core::transaction::{ CellInput as CoreCellInput, CellOutput as CoreCellOutput, OutPoint as CoreOutPoint, - Transaction as CoreTransaction, TransactionBuilder, + Transaction as CoreTransaction, TransactionBuilder, Witness as CoreWitness, }; use ckb_core::uncle::UncleBlock as CoreUncleBlock; use ckb_core::{BlockNumber, Capacity}; @@ -133,12 +133,32 @@ impl From for CoreCellInput { } } +#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] +pub struct Witness { + data: Vec, +} + +impl<'a> From<&'a CoreWitness> for Witness { + fn from(core: &CoreWitness) -> Witness { + Witness { + data: core.iter().cloned().map(Bytes::new).collect(), + } + } +} + +impl From for CoreWitness { + fn from(json: Witness) -> CoreWitness { + json.data.into_iter().map(|item| item.into_vec()).collect() + } +} + #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] pub struct Transaction { pub version: u32, pub deps: Vec, pub inputs: Vec, pub outputs: Vec, + pub witnesses: Vec, #[serde(skip_deserializing)] pub hash: H256, } @@ -152,6 +172,7 @@ impl<'a> From<&'a CoreTransaction> for Transaction { deps: core.deps().iter().cloned().map(Into::into).collect(), inputs: core.inputs().iter().cloned().map(Into::into).collect(), outputs: core.outputs().iter().cloned().map(Into::into).collect(), + witnesses: core.witnesses().iter().map(Into::into).collect(), hash, } } @@ -164,6 +185,7 @@ impl From for CoreTransaction { deps, inputs, outputs, + witnesses, .. } = json; @@ -172,6 +194,7 @@ impl From for CoreTransaction { .deps(deps.into_iter().map(Into::into).collect()) .inputs(inputs.into_iter().map(Into::into).collect()) .outputs(outputs.into_iter().map(Into::into).collect()) + .witnesses(witnesses.into_iter().map(Into::into).collect()) .build() } } @@ -207,6 +230,7 @@ pub struct Header { pub number: BlockNumber, pub txs_commit: H256, pub txs_proposal: H256, + pub witnesses_root: H256, pub difficulty: U256, pub cellbase_id: H256, pub uncles_hash: H256, @@ -225,6 +249,7 @@ impl<'a> From<&'a CoreHeader> for Header { number: core.number(), txs_commit: core.txs_commit().clone(), txs_proposal: core.txs_proposal().clone(), + witnesses_root: core.witnesses_root().clone(), difficulty: core.difficulty().clone(), cellbase_id: core.cellbase_id().clone(), uncles_hash: core.uncles_hash().clone(), @@ -244,6 +269,7 @@ impl From
for CoreHeader { number, txs_commit, txs_proposal, + witnesses_root, difficulty, cellbase_id, uncles_hash, @@ -259,6 +285,7 @@ impl From
for CoreHeader { .number(number) .txs_commit(txs_commit) .txs_proposal(txs_proposal) + .witnesses_root(witnesses_root) .difficulty(difficulty) .cellbase_id(cellbase_id) .uncles_hash(uncles_hash) @@ -369,7 +396,8 @@ mod tests { TransactionBuilder::default() .deps(vec![CoreOutPoint::default()]) .inputs(vec![mock_cell_input(arg.clone())]) - .outputs(vec![mock_cell_output(data, arg)]) + .outputs(vec![mock_cell_output(data, arg.clone())]) + .witness(vec![arg]) .build() } diff --git a/verification/src/block_verifier.rs b/verification/src/block_verifier.rs index 287254767f..a0c62d7847 100644 --- a/verification/src/block_verifier.rs +++ b/verification/src/block_verifier.rs @@ -153,6 +153,20 @@ impl MerkleRootVerifier { return Err(Error::CommitTransactionsRoot); } + // The witness hash of cellbase transaction is assumed to be zero 0x0000....0000 + let mut witnesses = vec![H256::zero()]; + witnesses.extend( + block + .commit_transactions() + .iter() + .skip(1) + .map(|tx| tx.witness_hash()), + ); + + if block.header().witnesses_root() != &merkle_root(&witnesses[..]) { + return Err(Error::WitnessesMerkleRoot); + } + let proposals = block .proposal_transactions() .iter() diff --git a/verification/src/error.rs b/verification/src/error.rs index 5e4644f861..9b0d7b3589 100644 --- a/verification/src/error.rs +++ b/verification/src/error.rs @@ -35,6 +35,8 @@ pub enum Error { ProposalTransactionsRoot, /// The merkle tree hash of committed transactions does not match the one in header. CommitTransactionsRoot, + /// The merkle tree witness hash of committed transactions does not match the one in header. + WitnessesMerkleRoot, /// The parent of the block is unknown. UnknownParent(H256), /// Uncles does not meet the consensus requirements. From c39a7621714d6464af2458686df6c24d3deb4885 Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Mon, 8 Apr 2019 11:30:56 +0800 Subject: [PATCH 2/2] refactor: merkle_root build --- core/src/block.rs | 66 ++++++++++++++++-------------- verification/src/block_verifier.rs | 28 ++----------- 2 files changed, 39 insertions(+), 55 deletions(-) diff --git a/core/src/block.rs b/core/src/block.rs index 615f79c923..15d0c2b735 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -64,6 +64,38 @@ impl Block { ids.into_iter().collect() } + + pub fn cal_witnesses_root(&self) -> H256 { + // The witness hash of cellbase transaction is assumed to be zero 0x0000....0000 + let mut witnesses = vec![H256::zero()]; + witnesses.extend( + self.commit_transactions() + .iter() + .skip(1) + .map(|tx| tx.witness_hash()), + ); + merkle_root(&witnesses[..]) + } + + pub fn cal_txs_commit_root(&self) -> H256 { + merkle_root( + &self + .commit_transactions + .iter() + .map(|t| t.hash()) + .collect::>(), + ) + } + + pub fn cal_txs_proposal_root(&self) -> H256 { + merkle_root( + &self + .proposal_transactions + .iter() + .map(|t| t.hash()) + .collect::>(), + ) + } } impl ::std::hash::Hash for Block { @@ -133,36 +165,10 @@ impl BlockBuilder { } pub fn with_header_builder(mut self, header_builder: HeaderBuilder) -> Block { - let txs_commit = merkle_root( - &self - .inner - .commit_transactions - .iter() - .map(|t| t.hash()) - .collect::>(), - ); - - // The witness hash of cellbase transaction is assumed to be zero 0x0000....0000 - let mut witnesses = vec![H256::zero()]; - witnesses.extend( - self.inner - .commit_transactions() - .iter() - .skip(1) - .map(|tx| tx.witness_hash()), - ); - let witnesses_root = merkle_root(&witnesses[..]); - - let txs_proposal = merkle_root( - &self - .inner - .proposal_transactions - .iter() - .map(|t| t.hash()) - .collect::>(), - ); - - let uncles_hash = uncles_hash(&self.inner.uncles); + let txs_commit = self.inner.cal_txs_commit_root(); + let witnesses_root = self.inner.cal_witnesses_root(); + let txs_proposal = self.inner.cal_txs_proposal_root(); + let uncles_hash = self.inner.cal_uncles_hash(); self.inner.header = header_builder .txs_commit(txs_commit) diff --git a/verification/src/block_verifier.rs b/verification/src/block_verifier.rs index a0c62d7847..c75dbe53d6 100644 --- a/verification/src/block_verifier.rs +++ b/verification/src/block_verifier.rs @@ -143,37 +143,15 @@ impl MerkleRootVerifier { } pub fn verify(&self, block: &Block) -> Result<(), Error> { - let commits = block - .commit_transactions() - .iter() - .map(|tx| tx.hash()) - .collect::>(); - - if block.header().txs_commit() != &merkle_root(&commits[..]) { + if block.header().txs_commit() != &block.cal_txs_commit_root() { return Err(Error::CommitTransactionsRoot); } - // The witness hash of cellbase transaction is assumed to be zero 0x0000....0000 - let mut witnesses = vec![H256::zero()]; - witnesses.extend( - block - .commit_transactions() - .iter() - .skip(1) - .map(|tx| tx.witness_hash()), - ); - - if block.header().witnesses_root() != &merkle_root(&witnesses[..]) { + if block.header().witnesses_root() != &block.cal_witnesses_root() { return Err(Error::WitnessesMerkleRoot); } - let proposals = block - .proposal_transactions() - .iter() - .map(|id| id.hash()) - .collect::>(); - - if block.header().txs_proposal() != &merkle_root(&proposals[..]) { + if block.header().txs_proposal() != &block.cal_txs_proposal_root() { return Err(Error::ProposalTransactionsRoot); }