EIP-98: Optional transaction state root (#4296)
* EIP98: Optional receipt state root * Use if-else * Fixing tests
This commit is contained in:
parent
f5a4b55dae
commit
c012dfc3ef
@ -268,7 +268,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn check_receipts() {
|
fn check_receipts() {
|
||||||
let receipts = (0..5).map(|_| Receipt {
|
let receipts = (0..5).map(|_| Receipt {
|
||||||
state_root: H256::random(),
|
state_root: Some(H256::random()),
|
||||||
gas_used: 21_000u64.into(),
|
gas_used: 21_000u64.into(),
|
||||||
log_bloom: Default::default(),
|
log_bloom: Default::default(),
|
||||||
logs: Vec::new(),
|
logs: Vec::new(),
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
"networkID" : "0x1",
|
"networkID" : "0x1",
|
||||||
"chainID": "0x3d",
|
"chainID": "0x3d",
|
||||||
"forkBlock": "0x1d4c00",
|
"forkBlock": "0x1d4c00",
|
||||||
"forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f"
|
"forkCanonHash": "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x1"
|
"networkID" : "0x1",
|
||||||
|
"eip98Transition": "0x7fffffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x1"
|
"networkID" : "0x1",
|
||||||
|
"eip98Transition": "0x7fffffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID": "0x1",
|
"networkID": "0x1",
|
||||||
"subprotocolName": "exp"
|
"subprotocolName": "exp",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -146,7 +146,8 @@
|
|||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x1",
|
"networkID" : "0x1",
|
||||||
"forkBlock": "0x1d4c00",
|
"forkBlock": "0x1d4c00",
|
||||||
"forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb"
|
"forkCanonHash": "0x4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -142,7 +142,8 @@
|
|||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x1"
|
"networkID" : "0x1",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x1"
|
"networkID" : "0x1",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x1"
|
"networkID" : "0x1",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
"networkID" : "0x2",
|
"networkID" : "0x2",
|
||||||
"chainID": "0x3e",
|
"chainID": "0x3e",
|
||||||
"forkBlock": "0x1b34d8",
|
"forkBlock": "0x1b34d8",
|
||||||
"forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145"
|
"forkCanonHash": "0xf376243aeff1f256d970714c3de9fd78fa4e63cf63e32a51fe1169e375d98145",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"maximumExtraDataSize": "0x0400",
|
"maximumExtraDataSize": "0x0400",
|
||||||
"minGasLimit": "125000",
|
"minGasLimit": "125000",
|
||||||
"networkID" : "0x0"
|
"networkID" : "0x0",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -26,7 +26,8 @@
|
|||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
"networkID" : "0x3",
|
"networkID" : "0x3",
|
||||||
"forkBlock": 333922,
|
"forkBlock": 333922,
|
||||||
"forkCanonHash": "0x8737eb141d4f05db57af63fc8d3b4d4d8f9cddb0c4e1ab855de8c288fdc1924f"
|
"forkCanonHash": "0x8737eb141d4f05db57af63fc8d3b4d4d8f9cddb0c4e1ab855de8c288fdc1924f",
|
||||||
|
"eip98Transition": "0x7fffffffffffff"
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -375,6 +375,9 @@ impl<'x> OpenBlock<'x> {
|
|||||||
let unclosed_state = s.block.state.clone();
|
let unclosed_state = s.block.state.clone();
|
||||||
|
|
||||||
s.engine.on_close_block(&mut s.block);
|
s.engine.on_close_block(&mut s.block);
|
||||||
|
if let Err(e) = s.block.state.commit() {
|
||||||
|
warn!("Encountered error on state commit: {}", e);
|
||||||
|
}
|
||||||
s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes().to_vec())));
|
s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes().to_vec())));
|
||||||
let uncle_bytes = s.block.uncles.iter().fold(RlpStream::new_list(s.block.uncles.len()), |mut s, u| {s.append_raw(&u.rlp(Seal::With), 1); s} ).out();
|
let uncle_bytes = s.block.uncles.iter().fold(RlpStream::new_list(s.block.uncles.len()), |mut s, u| {s.append_raw(&u.rlp(Seal::With), 1); s} ).out();
|
||||||
s.block.header.set_uncles_hash(uncle_bytes.sha3());
|
s.block.header.set_uncles_hash(uncle_bytes.sha3());
|
||||||
@ -396,6 +399,10 @@ impl<'x> OpenBlock<'x> {
|
|||||||
let mut s = self;
|
let mut s = self;
|
||||||
|
|
||||||
s.engine.on_close_block(&mut s.block);
|
s.engine.on_close_block(&mut s.block);
|
||||||
|
|
||||||
|
if let Err(e) = s.block.state.commit() {
|
||||||
|
warn!("Encountered error on state commit: {}", e);
|
||||||
|
}
|
||||||
if s.block.header.transactions_root().is_zero() || s.block.header.transactions_root() == &SHA3_NULL_RLP {
|
if s.block.header.transactions_root().is_zero() || s.block.header.transactions_root() == &SHA3_NULL_RLP {
|
||||||
s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes().to_vec())));
|
s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes().to_vec())));
|
||||||
}
|
}
|
||||||
|
@ -1896,7 +1896,7 @@ mod tests {
|
|||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = new_chain(&genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
insert_block(&db, &bc, &b1, vec![Receipt {
|
insert_block(&db, &bc, &b1, vec![Receipt {
|
||||||
state_root: H256::default(),
|
state_root: Some(H256::default()),
|
||||||
gas_used: 10_000.into(),
|
gas_used: 10_000.into(),
|
||||||
log_bloom: Default::default(),
|
log_bloom: Default::default(),
|
||||||
logs: vec![
|
logs: vec![
|
||||||
@ -1905,7 +1905,7 @@ mod tests {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
Receipt {
|
Receipt {
|
||||||
state_root: H256::default(),
|
state_root: Some(H256::default()),
|
||||||
gas_used: 10_000.into(),
|
gas_used: 10_000.into(),
|
||||||
log_bloom: Default::default(),
|
log_bloom: Default::default(),
|
||||||
logs: vec![
|
logs: vec![
|
||||||
@ -1914,7 +1914,7 @@ mod tests {
|
|||||||
}]);
|
}]);
|
||||||
insert_block(&db, &bc, &b2, vec![
|
insert_block(&db, &bc, &b2, vec![
|
||||||
Receipt {
|
Receipt {
|
||||||
state_root: H256::default(),
|
state_root: Some(H256::default()),
|
||||||
gas_used: 10_000.into(),
|
gas_used: 10_000.into(),
|
||||||
log_bloom: Default::default(),
|
log_bloom: Default::default(),
|
||||||
logs: vec![
|
logs: vec![
|
||||||
|
@ -1713,7 +1713,7 @@ mod tests {
|
|||||||
|
|
||||||
let block_number = 1;
|
let block_number = 1;
|
||||||
let block_hash = 5.into();
|
let block_hash = 5.into();
|
||||||
let state_root = 99.into();
|
let state_root = Some(99.into());
|
||||||
let gas_used = 10.into();
|
let gas_used = 10.into();
|
||||||
let raw_tx = Transaction {
|
let raw_tx = Transaction {
|
||||||
nonce: 0.into(),
|
nonce: 0.into(),
|
||||||
|
@ -591,7 +591,7 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
// starts with 'f' ?
|
// starts with 'f' ?
|
||||||
if *hash > H256::from("f000000000000000000000000000000000000000000000000000000000000000") {
|
if *hash > H256::from("f000000000000000000000000000000000000000000000000000000000000000") {
|
||||||
let receipt = BlockReceipts::new(vec![Receipt::new(
|
let receipt = BlockReceipts::new(vec![Receipt::new(
|
||||||
H256::zero(),
|
Some(H256::zero()),
|
||||||
U256::zero(),
|
U256::zero(),
|
||||||
vec![])]);
|
vec![])]);
|
||||||
let mut rlp = RlpStream::new();
|
let mut rlp = RlpStream::new();
|
||||||
|
@ -53,6 +53,8 @@ pub struct CommonParams {
|
|||||||
pub min_gas_limit: U256,
|
pub min_gas_limit: U256,
|
||||||
/// Fork block to check.
|
/// Fork block to check.
|
||||||
pub fork_block: Option<(BlockNumber, H256)>,
|
pub fork_block: Option<(BlockNumber, H256)>,
|
||||||
|
/// Number of first block where EIP-98 rules begin.
|
||||||
|
pub eip98_transition: BlockNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethjson::spec::Params> for CommonParams {
|
impl From<ethjson::spec::Params> for CommonParams {
|
||||||
@ -65,6 +67,7 @@ impl From<ethjson::spec::Params> for CommonParams {
|
|||||||
subprotocol_name: p.subprotocol_name.unwrap_or_else(|| "eth".to_owned()),
|
subprotocol_name: p.subprotocol_name.unwrap_or_else(|| "eth".to_owned()),
|
||||||
min_gas_limit: p.min_gas_limit.into(),
|
min_gas_limit: p.min_gas_limit.into(),
|
||||||
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
|
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
|
||||||
|
eip98_transition: p.eip98_transition.map_or(0, Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -519,8 +519,13 @@ impl State {
|
|||||||
|
|
||||||
// TODO uncomment once to_pod() works correctly.
|
// TODO uncomment once to_pod() works correctly.
|
||||||
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
||||||
self.commit()?;
|
let state_root = if env_info.number < engine.params().eip98_transition {
|
||||||
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
self.commit()?;
|
||||||
|
Some(self.root().clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let receipt = Receipt::new(state_root, e.cumulative_gas_used, e.logs);
|
||||||
trace!(target: "state", "Transaction receipt: {:?}", receipt);
|
trace!(target: "state", "Transaction receipt: {:?}", receipt);
|
||||||
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ use log_entry::{LogEntry, LocalizedLogEntry};
|
|||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub struct Receipt {
|
pub struct Receipt {
|
||||||
/// The state root after executing the transaction.
|
/// The state root after executing the transaction. Optional since EIP98
|
||||||
pub state_root: H256,
|
pub state_root: Option<H256>,
|
||||||
/// The total gas used in the block following execution of the transaction.
|
/// The total gas used in the block following execution of the transaction.
|
||||||
pub gas_used: U256,
|
pub gas_used: U256,
|
||||||
/// The OR-wide combination of all logs' blooms for this transaction.
|
/// The OR-wide combination of all logs' blooms for this transaction.
|
||||||
@ -40,7 +40,7 @@ pub struct Receipt {
|
|||||||
|
|
||||||
impl Receipt {
|
impl Receipt {
|
||||||
/// Create a new receipt.
|
/// Create a new receipt.
|
||||||
pub fn new(state_root: H256, gas_used: U256, logs: Vec<LogEntry>) -> Receipt {
|
pub fn new(state_root: Option<H256>, gas_used: U256, logs: Vec<LogEntry>) -> Receipt {
|
||||||
Receipt {
|
Receipt {
|
||||||
state_root: state_root,
|
state_root: state_root,
|
||||||
gas_used: gas_used,
|
gas_used: gas_used,
|
||||||
@ -52,8 +52,12 @@ impl Receipt {
|
|||||||
|
|
||||||
impl Encodable for Receipt {
|
impl Encodable for Receipt {
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
s.begin_list(4);
|
if let Some(ref root) = self.state_root {
|
||||||
s.append(&self.state_root);
|
s.begin_list(4);
|
||||||
|
s.append(root);
|
||||||
|
} else {
|
||||||
|
s.begin_list(3);
|
||||||
|
}
|
||||||
s.append(&self.gas_used);
|
s.append(&self.gas_used);
|
||||||
s.append(&self.log_bloom);
|
s.append(&self.log_bloom);
|
||||||
s.append(&self.logs);
|
s.append(&self.logs);
|
||||||
@ -63,13 +67,21 @@ impl Encodable for Receipt {
|
|||||||
impl Decodable for Receipt {
|
impl Decodable for Receipt {
|
||||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||||
let d = decoder.as_rlp();
|
let d = decoder.as_rlp();
|
||||||
let receipt = Receipt {
|
if d.item_count() == 3 {
|
||||||
state_root: d.val_at(0)?,
|
Ok(Receipt {
|
||||||
gas_used: d.val_at(1)?,
|
state_root: None,
|
||||||
log_bloom: d.val_at(2)?,
|
gas_used: d.val_at(0)?,
|
||||||
logs: d.val_at(3)?,
|
log_bloom: d.val_at(1)?,
|
||||||
};
|
logs: d.val_at(2)?,
|
||||||
Ok(receipt)
|
})
|
||||||
|
} else {
|
||||||
|
Ok(Receipt {
|
||||||
|
state_root: d.val_at(0)?,
|
||||||
|
gas_used: d.val_at(1)?,
|
||||||
|
log_bloom: d.val_at(2)?,
|
||||||
|
logs: d.val_at(3)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +110,7 @@ pub struct RichReceipt {
|
|||||||
/// Logs bloom
|
/// Logs bloom
|
||||||
pub log_bloom: LogBloom,
|
pub log_bloom: LogBloom,
|
||||||
/// State root
|
/// State root
|
||||||
pub state_root: H256,
|
pub state_root: Option<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receipt with additional info.
|
/// Receipt with additional info.
|
||||||
@ -124,14 +136,29 @@ pub struct LocalizedReceipt {
|
|||||||
/// Logs bloom
|
/// Logs bloom
|
||||||
pub log_bloom: LogBloom,
|
pub log_bloom: LogBloom,
|
||||||
/// State root
|
/// State root
|
||||||
pub state_root: H256,
|
pub state_root: Option<H256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic() {
|
fn test_no_state_root() {
|
||||||
let expected = ::rustc_serialize::hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
let expected = ::rustc_serialize::hex::FromHex::from_hex("f9014183040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||||
let r = Receipt::new(
|
let r = Receipt::new(
|
||||||
"2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into(),
|
None,
|
||||||
|
0x40cae.into(),
|
||||||
|
vec![LogEntry {
|
||||||
|
address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
|
||||||
|
topics: vec![],
|
||||||
|
data: vec![0u8; 32]
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
assert_eq!(&encode(&r)[..], &expected[..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_basic() {
|
||||||
|
let expected = ::rustc_serialize::hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||||
|
let r = Receipt::new(
|
||||||
|
Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()),
|
||||||
0x40cae.into(),
|
0x40cae.into(),
|
||||||
vec![LogEntry {
|
vec![LogEntry {
|
||||||
address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
|
address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
|
||||||
|
@ -49,6 +49,10 @@ pub struct Params {
|
|||||||
/// Expected fork block hash.
|
/// Expected fork block hash.
|
||||||
#[serde(rename="forkCanonHash")]
|
#[serde(rename="forkCanonHash")]
|
||||||
pub fork_hash: Option<H256>,
|
pub fork_hash: Option<H256>,
|
||||||
|
|
||||||
|
/// See `CommonParams` docs.
|
||||||
|
#[serde(rename="eip98Transition")]
|
||||||
|
pub eip98_transition: Option<Uint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -969,7 +969,7 @@ fn rpc_eth_transaction_receipt() {
|
|||||||
log_index: 1,
|
log_index: 1,
|
||||||
}],
|
}],
|
||||||
log_bloom: 0.into(),
|
log_bloom: 0.into(),
|
||||||
state_root: 0.into(),
|
state_root: Some(0.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let hash = H256::from_str("b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").unwrap();
|
let hash = H256::from_str("b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").unwrap();
|
||||||
|
@ -45,7 +45,7 @@ pub struct Receipt {
|
|||||||
pub logs: Vec<Log>,
|
pub logs: Vec<Log>,
|
||||||
/// State Root
|
/// State Root
|
||||||
#[serde(rename="root")]
|
#[serde(rename="root")]
|
||||||
pub state_root: H256,
|
pub state_root: Option<H256>,
|
||||||
/// Logs bloom
|
/// Logs bloom
|
||||||
#[serde(rename="logsBloom")]
|
#[serde(rename="logsBloom")]
|
||||||
pub logs_bloom: H2048,
|
pub logs_bloom: H2048,
|
||||||
@ -62,7 +62,7 @@ impl From<LocalizedReceipt> for Receipt {
|
|||||||
gas_used: Some(r.gas_used.into()),
|
gas_used: Some(r.gas_used.into()),
|
||||||
contract_address: r.contract_address.map(Into::into),
|
contract_address: r.contract_address.map(Into::into),
|
||||||
logs: r.logs.into_iter().map(Into::into).collect(),
|
logs: r.logs.into_iter().map(Into::into).collect(),
|
||||||
state_root: r.state_root.into(),
|
state_root: r.state_root.map(Into::into),
|
||||||
logs_bloom: r.log_bloom.into(),
|
logs_bloom: r.log_bloom.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ impl From<RichReceipt> for Receipt {
|
|||||||
gas_used: Some(r.gas_used.into()),
|
gas_used: Some(r.gas_used.into()),
|
||||||
contract_address: r.contract_address.map(Into::into),
|
contract_address: r.contract_address.map(Into::into),
|
||||||
logs: r.logs.into_iter().map(Into::into).collect(),
|
logs: r.logs.into_iter().map(Into::into).collect(),
|
||||||
state_root: r.state_root.into(),
|
state_root: r.state_root.map(Into::into),
|
||||||
logs_bloom: r.log_bloom.into(),
|
logs_bloom: r.log_bloom.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ impl From<EthReceipt> for Receipt {
|
|||||||
gas_used: None,
|
gas_used: None,
|
||||||
contract_address: None,
|
contract_address: None,
|
||||||
logs: r.logs.into_iter().map(Into::into).collect(),
|
logs: r.logs.into_iter().map(Into::into).collect(),
|
||||||
state_root: r.state_root.into(),
|
state_root: r.state_root.map(Into::into),
|
||||||
logs_bloom: r.log_bloom.into(),
|
logs_bloom: r.log_bloom.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ mod tests {
|
|||||||
log_type: "mined".into(),
|
log_type: "mined".into(),
|
||||||
}],
|
}],
|
||||||
logs_bloom: 15.into(),
|
logs_bloom: 15.into(),
|
||||||
state_root: 10.into(),
|
state_root: Some(10.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let serialized = serde_json::to_string(&receipt).unwrap();
|
let serialized = serde_json::to_string(&receipt).unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user