-
Notifications
You must be signed in to change notification settings - Fork 679
fix: calling evm_mine
with a timestamp
argument should reflect the change of time in subsequent blocks
#3531
Conversation
… ensure that subsequent blocks reflect the change in time.
|
||
assert( | ||
+unspecifiedBlock >= timeArgumentSeconds && | ||
+unspecifiedBlock <= timeArgumentSeconds + 1000, |
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 CI is running slowly, could this break? I don't know what the solution is, and I don't feel it's worth holding up this PR for, but just wanted to throw it out there in case you have a solution on-hand.
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 could do. Because we are specifying a timestamp in seconds, it would need to take an entire second to mine and fetch 2 blocks.
I feel like I'm building a lot of pressure on the time refactor - but it'll let us inject a now
provider, which allow us to be much more resilient to slow build agents.
🤞
…alue. Name arguments in api.ts for readibility
|
||
if ( | ||
timestamp !== undefined && | ||
this.#options.miner.timestampIncrement === "clock" |
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.
There are two time-related blocks of code in this function that both check this.#options.miner.timestampIncrement === "clock"
. Can these two blocks be joined together? If not, can you cache this.#options.miner.timestampIncrement === "clock"
in a variable so we don't do it twice?
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.
Good call!
@@ -141,6 +141,83 @@ describe("provider", () => { | |||
await provider.disconnect(); | |||
}); | |||
|
|||
describe("uses timestamp adjustment in subsequent blocks after calling `evm_mine` with a `timestamp` argument", () => { |
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.
Our describe
s are usually simple words or phrases like "api", "eth_chainId", "server". This is worded more like an it
.
Can you rephrase the describe
and it
s here to be more inline with our other tests?
We use describe
to define structure to our tests, so maybe a bunch of these tests in this file should already be under describe("timestampIncrement", ...)
(don't need to make a change like this in this same PR, of course), and then you could have another describe
under that one like describe("
evm_minewith
timestamp", ...)
(just an example -- I didn't think it through very much).
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 just flattened that describe down, and was more explicit in the test names. lmk what you think.
params: ["latest", false] | ||
}); | ||
|
||
return [specifiedBlock.timestamp, unspecifiedBlock.timestamp]; |
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 you coerce these to numbers here it'd make the tests slightly simpler.
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 intentionally didn't do this, thinking that we should be asserting the exact returned value. Otherwise, there's a potential issue that could slip through where the return type isn't what's expected, but coerces to what's expected.
Thinking about it in light of your comment, I think that we should be ensuring the above, but maybe in a specific test for that.
I've updated my tests to what you've suggested, keen to hear your thoughts on that.
|
||
it("should work with a numeric `timestampIncrement`", async () => { | ||
const provider = await getProvider({ | ||
miner: { timestampIncrement } |
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.
Since this timestampIncrement
is only used in this function is there a reason to define it in the describe
?
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.
Approved! (with one half-hearted suggestion/thought)
@@ -357,10 +357,10 @@ export default class Blockchain extends Emittery<BlockchainTypedEvents> { | |||
|
|||
//#region automatic mining | |||
const nullResolved = Promise.resolve(null); | |||
const mineAll = (maxTransactions: Capacity, onlyOneBlock = false) => | |||
const mineAll = (maxTransactions: Capacity, onlyOneBlock?: boolean) => |
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.
A decent alternative would be to change mineAll
to (maxTransactions: Capacity, onlyOneBlock: boolean) =>
and then all use of mineAll
would need to pass the values it needs, basically just:
txPool.on("drain", () => mineAll(Capacity.Single, false));
This might make this code a bit clearer. Or not. I don't think I care either way.
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 left it as is because we set a default on the mine
function, and don't feel that requiring it for mineAll
, but not for mine
feels nice - we might as well leverage the default that we have specified.
Previously, calling
evm_mine
with atimestamp
argument would result in a block with the specified timestamp, but subsequent blocks would have a timestamp that didn't reflect this change in time. This only occurred whenminer.timestampIncrement
is unspecified orclock
.Will output something like:
Where
secondTimestamp
is the current time in seconds, but should be0x2
.With this change, blocks mined after providing a
timestamp
parameter toevm_mine
, will have timestamps that reflect the change in time.Fixes: #3265