From c3065d32f4c3125c3e39062e76b30e6a77254bb8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 9 Oct 2014 01:41:08 -0500 Subject: [PATCH] Make use of the new btcchain MedianTimeSource. This commit uses the new MedianTimeSource API in btcchain to create a median time source which is stored in the server and is fed time samples from all remote nodes that are connected. It also modifies all call sites which now require the the time source to pass it in. --- blockmanager.go | 8 +++++--- peer.go | 4 ++++ rpcserver.go | 7 ++++--- server.go | 3 +++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/blockmanager.go b/blockmanager.go index 4b15d638..6a96b56d 100644 --- a/blockmanager.go +++ b/blockmanager.go @@ -519,7 +519,7 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) { // current returns true if we believe we are synced with our peers, false if we // still have blocks to check func (b *blockManager) current() bool { - if !b.blockChain.IsCurrent() { + if !b.blockChain.IsCurrent(b.server.timeSource) { return false } @@ -591,7 +591,8 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) { // Process the block to include validation, best chain selection, orphan // handling, etc. - isOrphan, err := b.blockChain.ProcessBlock(bmsg.block, behaviorFlags) + isOrphan, err := b.blockChain.ProcessBlock(bmsg.block, + b.server.timeSource, behaviorFlags) if err != nil { // When the error is a rule error, it means the block was simply // rejected as opposed to something actually going wrong, so log @@ -1065,7 +1066,8 @@ out: case processBlockMsg: isOrphan, err := b.blockChain.ProcessBlock( - msg.block, msg.flags) + msg.block, b.server.timeSource, + msg.flags) if err != nil { msg.reply <- processBlockResponse{ isOrphan: false, diff --git a/peer.go b/peer.go index 5e32bb13..394bba49 100644 --- a/peer.go +++ b/peer.go @@ -444,6 +444,10 @@ func (p *peer) handleVersionMsg(msg *btcwire.MsgVersion) { p.updateAddresses(msg) } + // Add the remote peer time as a sample for creating an offset against + // the local clock to keep the network time in sync. + p.server.timeSource.AddTimeSample(p.addr, msg.Timestamp) + // Signal the block manager this peer is a new sync candidate. p.server.blockManager.NewPeer(p) diff --git a/rpcserver.go b/rpcserver.go index 92a24de5..14032834 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3071,7 +3071,7 @@ func handleSubmitBlock(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{}) return nil, nil } -func verifyChain(db btcdb.Db, level, depth int32) error { +func verifyChain(db btcdb.Db, level, depth int32, timeSource btcchain.MedianTimeSource) error { _, curHeight64, err := db.NewestSha() if err != nil { rpcsLog.Errorf("Verify is unable to fetch current block "+ @@ -3105,7 +3105,7 @@ func verifyChain(db btcdb.Db, level, depth int32) error { // Level 1 does basic chain sanity checks. if level > 0 { err := btcchain.CheckBlockSanity(block, - activeNetParams.PowLimit) + activeNetParams.PowLimit, timeSource) if err != nil { rpcsLog.Errorf("Verify is unable to "+ "validate block at sha %v height "+ @@ -3140,7 +3140,8 @@ func handleValidateAddress(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struc func handleVerifyChain(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.VerifyChainCmd) - err := verifyChain(s.server.db, c.CheckLevel, c.CheckDepth) + err := verifyChain(s.server.db, c.CheckLevel, c.CheckDepth, + s.server.timeSource) return err == nil, nil } diff --git a/server.go b/server.go index 71477b12..87ac6335 100644 --- a/server.go +++ b/server.go @@ -19,6 +19,7 @@ import ( "sync/atomic" "time" + "github.com/conformal/btcchain" "github.com/conformal/btcd/addrmgr" "github.com/conformal/btcdb" "github.com/conformal/btcjson" @@ -90,6 +91,7 @@ type server struct { quit chan struct{} nat NAT db btcdb.Db + timeSource btcchain.MedianTimeSource } type peerState struct { @@ -1229,6 +1231,7 @@ func newServer(listenAddrs []string, db btcdb.Db, netParams *btcnet.Params) (*se modifyRebroadcastInv: make(chan interface{}), nat: nat, db: db, + timeSource: btcchain.NewMedianTime(), } bm, err := newBlockManager(&s) if err != nil {