Skip to content

It's unreasonable to use time.Now() in distributed systems #19

@ghost

Description

Describe The Bug
It's unreasonable to use time.Now() in distributed systems. Now if the these nodes would have slightly different system clocks, we could easily end up with different function called like below. As a result, the state of each node may be inconsistent, and then Consensus failure? (I don't know)

Code Snippets

// x/distribution/keeper/keeper.go L#213
func (k Keeper) CanDistribution(ctx sdk.Context) (bool, time.Time) {
	if k.startNotDistriTimePoint.Nanosecond() <= 0 {
		return true, k.startNotDistriTimePoint
	}

	nt := time.Now()
	tEnd := k.startNotDistriTimePoint.Add(24 * 3600 * 1e9)
	if nt.Before(tEnd) && nt.After(k.startNotDistriTimePoint) {
		return false, k.startNotDistriTimePoint
	} else {
		k.SetStartNotDistributionTimePoint(ctx, time.Time{})
		ctx.Logger().Info("time CanDistribution",
			"time", k.startNotDistriTimePoint.Nanosecond())
	}

	return true, k.startNotDistriTimePoint
}
// x/distribution/abci.go L#26
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) {
        ...
        k.GetStartNotDistributionTimePoint(ctx)

	f, _ := k.CanDistribution(ctx)
	if ctx.BlockHeight() > 1 && f {
		previousProposer := k.GetPreviousProposerConsAddr(ctx)
		k.AllocateTokens(ctx, sumPreviousPrecommitPower, previousTotalPower, previousProposer, req.LastCommitInfo.GetVotes())
	}
        ...
}

Input/Output
None

To Reproduce
To reproduce the above situation requires very strict conditions, like multi-full-nodes, slightly different system clocks, and more than 1/3 of voters veto proposal. So I just based on code analysis and guessing that the above situation may be happened.

Expected Behavior
Every non-faulty machine sees the same transaction log and computes the same state.

Desktop

  • OS: [macOS Mojave 10.14.6]

**Additional Context **
It is more reasonable choice for you to call another function ctx.BlockHeader().Time, because of this variable is produced by Tendermint, rather than rlying on single node.

should be fixed like this nt := ctx.BlockHeader().Time

Contact Information

Email - zhouhaw@gmail.com

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions