-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Contract mock system #583
Contract mock system #583
Conversation
This is a work in progress PR. I'll be updating it from time to time, although I'm focusing on other issues for now. You're welcome to comment on it (see also #83), but bear in mind that this code is far from its final state, and I expect it be changed quite a lot. |
1ec8642
to
997ef38
Compare
This is still WIP, but the version with a simple callback for each contract method works (see test). |
dc6841b
to
b0dd70b
Compare
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 very promising!
ethcontract-mock/src/details.rs
Outdated
|
||
state.block += 1; | ||
|
||
let receipt = TransactionReceipt { |
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.
I'm not sure if it's a good idea to leave most values empty here. Maybe we should check how a "normal" tx receipt looks like and use default hash values instead of None values?
ethcontract-mock/src/parse.rs
Outdated
} | ||
|
||
// Unwraps `Result`, adds info with current arg index and rpc name. | ||
fn res<T, E: Display>(&self, res: Result<T, E>) -> T { |
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.
nit: maybe more descriptive name?
I'll add docs and tests later today. The code is ready for review! |
95f0add
to
3614c14
Compare
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.
Finally! Mocked contracts!
As a general comment this PR was very large and quite difficult to review. It would have been nice to have been split into smaller pieces that could be merged (even if they were effectively dead code for a few commits) just to make the review process easier.
/// [`method`]: `Instance::method` | ||
/// [`view_method`]: `Instance::view_method` | ||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] | ||
pub struct Signature<P, R>(pub H32, pub std::marker::PhantomData<(P, R)>); |
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.
Love it.
receipts: HashMap<H256, TransactionReceipt>, | ||
} | ||
|
||
impl MockTransport { |
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.
Wow! You implemented a mock transport that handles all the ethcontract
necessary RPC calls!
One thing that I worry about is that we may make use of additional RPC methods in ethcontract
and forget to add them here. I can't think of a good way to deal with this though.
ethcontract-mock/src/details/mod.rs
Outdated
// We could support signing if user adds accounts with their private | ||
// keys during mock setup. | ||
|
||
panic!("mock node can't sign transactions, use offline signing with private key"); |
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.
We can just sign with PrivateKey::ONE
in these cases.
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.
We have to sign with private key for the from
address, unfortunately. Otherwise transaction hash will be botched and something might break.
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 from
is None
we can still use PrivateKey::ONE
😄.
panic!("mock node does not support executing methods on earliest block"); | ||
} | ||
BlockNumber::Number(n) if n.as_u64() != state.block => { | ||
panic!("mock node does not support executing methods on non-last block"); |
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.
This is something we likely need for GPv2 services. However, seeing as the PR is already quite large, we can leave it for later.
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.
In hopes of avoiding this issue for as long as possible we allow specific block number if it's equal to the current top block number. But you're right, we'll have to support this eventually.
let mut state = self.state.lock().unwrap(); | ||
let expectation = state.expectation::<P, R>(address, signature, index, generation); | ||
expectation.returns = Returns::Default; | ||
} |
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.
Might also be worth adding a mine
function to increment the block number.
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.
Also something for another PR (as this one is already quite large).
); | ||
self | ||
} | ||
} |
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.
Very nice documentation.
/// [`expect`]: Contract::expect | ||
pub fn checkpoint(&self) { | ||
self.transport.checkpoint(); | ||
} |
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.
similar comment about a mine
method.
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.
Sorry about that, I should've made smaller PRs throughout the development process. |
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.
All of this looks really great although some of it is a bit beyond me to see how so many different things connect. Perhaps smaller incremental changes would have helped focus on some of the more abstract concepts. I will continue to read and review, but it is looking pretty good overall.
3614c14
to
f668b2a
Compare
1c79fd6
to
e59df9d
Compare
I want to merge and release this PR today. I'll merge it without squashing to preserve commit history. I've also made an interactive rebase to account for |
Fix #83.
Implement mock system for contracts. Currently mimicking mockall interface.
See the attached issue for more details and discussion.