Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

What prevents a misconfigured / malicious validator to create a block with bad timestamp? #5978

Closed
xlc opened this issue May 12, 2020 · 7 comments
Labels
Z7-question Issue is a question. Closer should answer.

Comments

@xlc
Copy link
Contributor

xlc commented May 12, 2020

This is the only logic I can found to validate the timestamp in a block

assert!(
Self::now().is_zero() || now >= Self::now() + T::MinimumPeriod::get(),
"Timestamp must increment by at least <MinimumPeriod> between sequential blocks"
);

So what prevents a validator produce with a block with a future time?

And how does the next validator handle such case? If it is issuing block with the correct timestamp, it may be considered invalid?

@burdges
Copy link

burdges commented May 12, 2020

Block producers should build on the chain head with a timestamp they believe valid.

There is extensive design work on this in https://w3f-research.readthedocs.io/en/latest/polkadot/BABE/Babe.html#-4.-clock-adjustment--relative-time-algorithm- and w3f/polkadot-spec#168 although @hndnklnc only added the temporary adjustment section https://w3f-research.readthedocs.io/en/latest/polkadot/BABE/Babe.html#temporarily-clock-adjustment recently.

There was code that did not work properly, never got turned on, and got removed in #4993 dbeebe2#diff-20230c59d1bd7ffff93b396e87d05ad3

After @sorpaas refactoring #5655 any new attempt should be sharable with other consensus engines because it'll get used by both sassafras #4600 and secondary approval checks.

We should expose and feed this clock back into parachains via cumulus too.

@arkpar
Copy link
Member

arkpar commented May 12, 2020

Timestamp inhernet is checked here: https://github.com/paritytech/substrate/blob/master/frame/timestamp/src/lib.rs#L252

Additionally, BABE verifier checks the slot number here:

Err(Error::<Block>::TooFarInFuture(hash).into())

@bkchr bkchr added the Z7-question Issue is a question. Closer should answer. label May 12, 2020
@bkchr
Copy link
Member

bkchr commented May 12, 2020

Yeah, as @arkpar said that it is checked and it will fail if the the timestamp is too far in the future.

@bkchr bkchr closed this as completed May 12, 2020
@xlc
Copy link
Contributor Author

xlc commented May 13, 2020

Followup question, up to 30s drift is allowed

const MAX_TIMESTAMP_DRIFT_MILLIS: u64 = 30 * 1000;

Block producer use its local time to provide inherent data

let now = SystemTime::now();
now.duration_since(SystemTime::UNIX_EPOCH)

Does this means the following attack is possible?

  • Block time = 6s
  • At real time 1000, block producer A created a block with timestamp of 1020
    • This block is valid as the draft is less than 30s
  • At real time 1006, block producer B attempt to create a new block with timestamp of 1006
    • This block is invalid because it is less than (1020 + 3)
    • block producer B lost its block reward

@burdges
Copy link

burdges commented May 13, 2020

Is there a check that inherents have increasing timestamps somewhere?

@arkpar
Copy link
Member

arkpar commented May 13, 2020

At real time 1006, block producer B attempt to create a new block with timestamp of 1006
This block is invalid because it is less than (1020 + 3)

B sets new block timestamp to max(now, previous + MinimumPeriod). MinimumPeriod for kusama is 1. So the timestamp In this case will be set to 1021, which is valid.
https://github.com/paritytech/substrate/blob/master/frame/timestamp/src/lib.rs#L236

@arkpar
Copy link
Member

arkpar commented May 13, 2020

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Z7-question Issue is a question. Closer should answer.
Projects
None yet
Development

No branches or pull requests

4 participants