-
Notifications
You must be signed in to change notification settings - Fork 683
fix: evm_setTime
doesn't work correctly with miner.timestampIncrement
#3506
Conversation
I have decided to close #3265 in favour of this approach. I still think there's an opportunity to improve the implementation, and to add validation, but I will open that in a separate PR. |
@@ -596,6 +596,11 @@ export default class Blockchain extends Emittery<BlockchainTypedEvents> { | |||
onlyOneBlock: boolean = false | |||
) => { | |||
const nextBlock = this.#readyNextBlock(this.blocks.latest, timestamp); | |||
|
|||
// if block time is incremental, adjustments should only apply once, otherwise they accumulate with each block. | |||
if (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.
I wonder if this would make more sense to do in the #adjustedTime
function, right after we use it.
From:
#adjustedTime = (precedingTimestamp: Quantity) => {
const timeAdjustment = this.#timeAdjustment;
const timestampIncrement = this.#options.miner.timestampIncrement;
if (timestampIncrement === "clock") {
return Math.floor((Date.now() + timeAdjustment) / 1000);
} else {
return (
precedingTimestamp.toNumber() +
Math.floor(timeAdjustment / 1000) +
timestampIncrement.toNumber()
);
}
};
to:
#adjustedTime = (precedingTimestamp: Quantity) => {
let timeAdjustment = this.#timeAdjustment;
const timestampIncrement = this.#options.miner.timestampIncrement;
if (timestampIncrement === "clock") {
return Math.floor((Date.now() + timeAdjustment) / 1000);
} else {
const time =
precedingTimestamp.toNumber() +
Math.floor(timeAdjustment / 1000) +
timestampIncrement.toNumber();
timeAdjustment = 0;
return time;
}
};
Just so we're keeping all of this time logic in one area rather than randomly having it in this mine 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.
I didn't put it in there, because sometimes we call #adjustedTime
, but don't persist the block - for instance the pending
block changes that you've got in PR.
I agree that it's not super nice to have it thrown in the middle of here, but it needs to only happen if the block's being persisted for realsies.
I would like to tidy this up in a rewrite of the block-time stuff - those changes have been stressing me out, so I've put it on the backburner :P
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.
That makes sense! I'm very much looking forward to your time management refactor - there seems to be a lot of tech-debt wrapped up in how we manage time. But let's get these bugs fixed now if we can!
Co-authored-by: Micaiah Reid <[email protected]>
Is there a specific issue for what this PR fixes? If so, can you update the PR description to indicate that this PR fixes it before you squash and merge? If not, squash and merge away! I think this is the issue #3330. Also, don't forget to update the PR title! |
evm_setTime
doesn't work correctly with miner.timestampIncrement
evm_setTime
doesn't work correctly with miner.timestampIncrement
When using
miner.timestampIncrement
, callingevm_setTime
can result in unexpected values, and potentially with an error being thrown.This is because the
timeAdjustment
is applied to the previous blocktime, so this offset is applied for every block that is mined.With the following example, the initial block is mined correctly, as is the first block after setting the time, but subsequent blocks will have a descending block time, until the value becomes negative.
Fixes: #3330