-
Notifications
You must be signed in to change notification settings - Fork 1.7k
added a new RPC call trace_replayBlockTransactions #7366
Conversation
add execution proof
It looks like @tzapu hasn'signed our Contributor License Agreement, yet.
You can read and sign our full Contributor License Agreement at the following URL: https://cla.parity.io Once you've signed, plesae reply to this thread with Many thanks, Parity Technologies CLA Bot |
[clabot:check] |
It looks like @tzapu signed our Contributor License Agreement. 👍 Many thanks, Parity Technologies CLA Bot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
The RPC tests should go to rpc/src/v1/tests/mocked/traces.rs
, this will at least check the public API.
As for client tests it will be more tricky, have a look at ethcore/src/tests/helpers.rs
and generate_dummy_client_with_spec_accounts_and_data
to create a client, and later pick the last block and replay it.
ethcore/src/client/client.rs
Outdated
const EXECUTE_PROOF: &'static str = "Transaction replayed; qed"; | ||
for t in txs { | ||
let t = SignedTransaction::new(t).expect(PROOF); | ||
let x = self.do_virtual_call(&env_info, &mut state, &t, analytics).expect(EXECUTE_PROOF); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just do self.do_virtual_call(..)?
here. But you are right that the call should never error, so I'm fine with expect as well.
ethcore/src/client/test_client.rs
Outdated
@@ -429,6 +429,12 @@ impl BlockChainClient for TestBlockChainClient { | |||
self.execution_result.read().clone().unwrap() | |||
} | |||
|
|||
// TODO add test | |||
fn replay_block_transactions(&self, _block: BlockId, _analytics: CallAnalytics) -> Result<Vec<Executed>, CallError> { | |||
let res = Vec::with_capacity(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave this as unimplemented!()
ethcore/src/client/client.rs
Outdated
@@ -1318,6 +1318,25 @@ impl BlockChainClient for Client { | |||
self.do_virtual_call(&env_info, &mut state, &t, analytics) | |||
} | |||
|
|||
fn replay_block_transactions(&self, block: BlockId, analytics: CallAnalytics) -> Result<Vec<Executed>, CallError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To share the code with replay()
you could return a Result<Box<Iterator<Item = Executed>>, CallError>
here and then replay()
just becomes:
let index = <get-tx-index>;
Ok(self.replay_block(...)?.nth(index))
@tomusdrw thank you for taking at look at this i tried implementing the suggested changes, but my non existent rust knowledge got the best of me
with the new result, or if the rest of the changes are ok |
i think i may have sorted it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if i make the request for a not synced yet block i get This request is not supported because your node is running with state pruning. Run with --pruning=archive.
I think we should deal with it in a separate issue, it's currently common behaviour in all RPC methods.
ethcore/src/client/client.rs
Outdated
@@ -1293,7 +1293,7 @@ impl BlockChainClient for Client { | |||
trace!(target: "estimate_gas", "estimate_gas chopping {} .. {}", lower, upper); | |||
binary_chop(lower, upper, cond) | |||
} | |||
|
|||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove commented out code.
ethcore/src/client/client.rs
Outdated
let address = self.transaction_address(id).ok_or(CallError::TransactionNotFound)?; | ||
let block = BlockId::Hash(address.block_hash); | ||
|
||
Ok(self.replay_block_transactions(block, analytics)?.nth(address.index).unwrap()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of unwrap
use expect(<proof>)
. Here the proof will be something like: "The transaction address contains a valid index within block; qed".
ethcore/src/client/client.rs
Outdated
replays.push(x); | ||
} | ||
|
||
Ok(Box::new(replays.into_iter())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's almost fine - right now you are executing all transactions and putting the results into a vector, but Iterator
allows you to do it lazily (which will make replay
work faster).
It should look like this (instead of a loop you should use map
):
let txs = block.transactions();
Ok(Box::new(txs.into_iter()
.map(|tx| {
...
self.do_virtual_call(...).expect(EXECUTE_PROOF)
})))
ethcore/src/client/test_client.rs
Outdated
@@ -429,6 +429,11 @@ impl BlockChainClient for TestBlockChainClient { | |||
self.execution_result.read().clone().unwrap() | |||
} | |||
|
|||
// TODO add test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove.
Could you also prepare a mocked RPC test? |
can't workout lifetime issues yet
Fix lifetimes issue.
again, i would like to thank you for all the hand holding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
Just some minor comments regarding docs.
rpc/src/v1/traits/traces.rs
Outdated
@@ -56,5 +56,9 @@ build_rpc_trait! { | |||
/// Executes the transaction with the given hash and returns a number of possible traces for it. | |||
#[rpc(name = "trace_replayTransaction")] | |||
fn replay_transaction(&self, H256, TraceOptions) -> Result<TraceResults>; | |||
|
|||
/// Executes the transaction with the given hash and returns a number of possible traces for it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Executes all the transactions at the given block and returns a number of possible traces for each transaction.
ethcore/src/client/traits.rs
Outdated
@@ -196,6 +196,9 @@ pub trait BlockChainClient : Sync + Send { | |||
/// Replays a given transaction for inspection. | |||
fn replay(&self, t: TransactionId, analytics: CallAnalytics) -> Result<Executed, CallError>; | |||
|
|||
/// Replays a given transaction for inspection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replays all the transactions in a given block for inspection.
thanks guys, much appreciated, happy new year |
thanks guys, for everything |
Would it be possible to also add uncle rewards and miner rewards with this JSON RPC? |
in relation to #7365
as i mentioned this is my first go at rust so I could do with some pointers about error checking or tests, or whatever else is needed to make this mergeable
thank you guys for everything