[DEV-206] allow block timestamp to be equal to past median time (#89)

* [DEV-206] allow block timestamp to be equal to past median time

* [DEV-206] make more specific error messages

* [DEV-206] make independent nodes in TestPastMedianTime
This commit is contained in:
Ori Newman 2018-10-14 15:33:36 +03:00 committed by Svarog
parent b0aaa79ad0
commit 695c0e5a68
2 changed files with 66 additions and 4 deletions

View File

@ -642,10 +642,10 @@ func (dag *BlockDAG) checkBlockHeaderContext(header *wire.BlockHeader, bluestPar
return ruleError(ErrUnexpectedDifficulty, str)
}
// Ensure the timestamp for the block header is after the
// Ensure the timestamp for the block header is not before the
// median time of the last several blocks (medianTimeBlocks).
medianTime := bluestParent.CalcPastMedianTime()
if !header.Timestamp.After(medianTime) {
if header.Timestamp.Before(medianTime) {
str := "block timestamp of %v is not after expected %v"
str = fmt.Sprintf(str, header.Timestamp, medianTime)
return ruleError(ErrTimeTooOld, str)

View File

@ -501,9 +501,71 @@ func TestCheckSerializedHeight(t *testing.T) {
}
}
func TestPastMedianTime(t *testing.T) {
dag := newTestDAG(&dagconfig.MainNetParams)
tip := dag.genesis
blockVersion := int32(0x10000000)
blockTime := tip.Header().Timestamp
for i := 0; i < 100; i++ {
blockTime = blockTime.Add(time.Second)
tip = newTestNode(setFromSlice(tip),
blockVersion,
0,
blockTime,
dagconfig.MainNetParams.K)
}
// Checks that a block is valid if it has timestamp equals to past median time
height := tip.height + 1
node := newTestNode(setFromSlice(tip),
blockVersion,
0,
tip.CalcPastMedianTime(),
dagconfig.MainNetParams.K)
header := node.Header()
err := dag.checkBlockHeaderContext(&header, node.parents.bluest(), height, BFNone)
if err != nil {
t.Errorf("TestPastMedianTime: unexpected error from checkBlockHeaderContext: %v"+
"(a block with timestamp equals to past median time should be valid)", err)
}
// Checks that a block is valid if its timestamp is after past median time
height = tip.height + 1
node = newTestNode(setFromSlice(tip),
blockVersion,
0,
tip.CalcPastMedianTime().Add(time.Second),
dagconfig.MainNetParams.K)
header = node.Header()
err = dag.checkBlockHeaderContext(&header, node.parents.bluest(), height, BFNone)
if err != nil {
t.Errorf("TestPastMedianTime: unexpected error from checkBlockHeaderContext: %v"+
"(a block with timestamp bigger than past median time should be valid)", err)
}
// Checks that a block is invalid if its timestamp is before past median time
height = tip.height + 1
node = newTestNode(setFromSlice(tip),
blockVersion,
0,
tip.CalcPastMedianTime().Add(-time.Second),
dagconfig.MainNetParams.K)
header = node.Header()
err = dag.checkBlockHeaderContext(&header, node.parents.bluest(), height, BFNone)
if err == nil {
t.Errorf("TestPastMedianTime: unexpected success: block should be invalid if its timestamp is before past median time")
}
}
func TestValidateParents(t *testing.T) {
blockDAG := newTestDAG(&dagconfig.MainNetParams)
genesisNode := blockDAG.genesis
dag := newTestDAG(&dagconfig.MainNetParams)
genesisNode := dag.genesis
blockVersion := int32(0x10000000)
blockTime := genesisNode.Header().Timestamp