We have established that the timestamp on a parent block has to be before the timestamp of a child block in Can a child block have an earlier timestamp than the parent block?.

How are differences in the clock settings on different miners' computers taken into account?

up vote 15 down vote accepted

Ethereum nodes (regardless of mining) need to have an accurate time, otherwise they will not be able to connect to peers and to the network (http://www.ethdocs.org/en/latest/network/connecting-to-the-network.html#common-problems-with-connectivity).

Small differences in time are tolerated by nodes, but as one node's time gets further away from Coordinated UTC Time (per NTP), its number of peers will reduce and eventually it will have zero peers and be disconnected from the network.

A miner M wants to have a time consistent with the network, so that other miners will build upon the blocks that M mines.

Blocks must be within reasonable Unix time, otherwise miners are unlikely to build upon blocks with unreasonable timestamps. (Example)

EDIT: For clarity, in Ethereum, the only rule about timestamps is that the timestamp must be greater than the previous timestamp. There is no other rule: old docs such as the white paper and wiki may mention 15 minutes (900 seconds), and here are the corrections:

White paper:

Check that the timestamp of the block is greater than that of the referenced previous block and less than 15 minutes into the future

wiki:

Is block.timestamp <= now + 900 and is block.timestamp > parent.timestamp? (strictly greater)

Unfortunately, the outdated, wrong information has been picked up by others such as here and here.

The Yellow paper is the formal specification and see Block Header Validity (section 4.4.4, equation 48).

Here's the code I've found so far that deals with syncing time. It uses pool.ntp.org:123 as the time syncing source.

From Go Ethereum - p2p/discover/ntp.go, lines 48-65:

func checkClockDrift() {
    drift, err := sntpDrift(ntpChecks)
    if err != nil {
        return
    }
    if drift < -driftThreshold || drift > driftThreshold {
        warning := fmt.Sprintf("System clock seems off by %v, which can prevent network connectivity", drift)
        howtofix := fmt.Sprintf("Please enable network time synchronisation in system settings")
        separator := strings.Repeat("-", len(warning))

        glog.V(logger.Warn).Info(separator)
        glog.V(logger.Warn).Info(warning)
        glog.V(logger.Warn).Info(howtofix)
        glog.V(logger.Warn).Info(separator)
    } else {
        glog.V(logger.Debug).Infof("Sanity NTP check reported %v drift, all ok", drift)
    }
}

From Go Ethereum - p2p/discover/ntp.go, lines 73-127:

func sntpDrift(measurements int) (time.Duration, error) {
    // Resolve the address of the NTP server
    addr, err := net.ResolveUDPAddr("udp", ntpPool+":123")
    if err != nil {
        return 0, err
    }
    // Construct the time request (empty package with only 2 fields set):
    //   Bits 3-5: Protocol version, 3
    //   Bits 6-8: Mode of operation, client, 3
    request := make([]byte, 48)
    request[0] = 3<<3 | 3

    // Execute each of the measurements
    drifts := []time.Duration{}
    ...
    // Calculate average drif (drop two extremities to avoid outliers)
    sort.Sort(durationSlice(drifts))

    drift := time.Duration(0)
    for i := 1; i < len(drifts)-1; i++ {
        drift += drifts[i]
    }
    return drift / time.Duration(measurements), nil
}

Go Ethereum - p2p/discover/ntp.go, lines 33-36:

const (
    ntpPool   = "pool.ntp.org" // ntpPool is the NTP server to query for the current time
    ntpChecks = 3              // Number of measurements to do against the NTP server
)

And driftThreshold = 10 seconds from p2p/discover/udp.go, line 57

If the hardcoded pool.ntp.org does undergo a long and sustained DDoS or DNS cache poisoning, Ethereum nodes will eventually fail to sync. But it will take a long time for the mining computers to drift by more than 10 seconds. And the Ethereum developers would have a a new fix out by that time.

TL;DR: Blocks must be within reasonable Unix time or they will be rejected.

The yellow paper states:

timestamp: A scalar value equal to the reasonable output of Unix’s time() at this block’s inception; formally Hs.

The white paper says:

The basic block validation algorithm in Ethereum is as follows:

  • [...]
  • Check that the timestamp of the block is greater than that of the referenced previous block and less than 15 minutes into the future
  • 2
    Does this mean that if a miner with their computer time set say 1 hour in the future mines a block, all other miners will be unable to mine on top of that block? – The Officious BokkyPooBah Jun 12 '16 at 6:04
  • 1
    good question :-) ethereum.stackexchange.com/questions/5927/… – Roland Kofler Jun 12 '16 at 6:05
  • 1
    Is the <= 2 hour in the white paper referring to the bitcoin algorithm? – The Officious BokkyPooBah Jun 12 '16 at 6:27
  • 2
    fixed it, pheew! – Roland Kofler Jun 12 '16 at 6:34
  • 2
    1. I provided clarification on what "rejected" means since there's an element of game theory rather than outright rejection by the protocol. 2. "15 mins" part in the whitepaper is old and it may get removed from it. The yellowpaper is the definitive source for the protocol. – eth Jun 12 '16 at 7:31

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.