diff --git a/blockdag/dag.go b/blockdag/dag.go index fbbe15771..266e283ec 100644 --- a/blockdag/dag.go +++ b/blockdag/dag.go @@ -912,6 +912,11 @@ func (dag *BlockDAG) VirtualBlock() *VirtualBlock { return dag.virtual } +// Height returns the height of the highest tip in the DAG +func (dag *BlockDAG) Height() int32 { + return dag.virtual.tips().maxHeight() +} + // HeaderByHash returns the block header identified by the given hash or an // error if it doesn't exist. func (dag *BlockDAG) HeaderByHash(hash *daghash.Hash) (wire.BlockHeader, error) { diff --git a/blockdag/fullblocks_test.go b/blockdag/fullblocks_test.go index 6c4ef77f7..6e3a50df2 100644 --- a/blockdag/fullblocks_test.go +++ b/blockdag/fullblocks_test.go @@ -274,12 +274,12 @@ func TestFullBlocks(t *testing.T) { // Ensure hash and height match. virtualBlock := dag.VirtualBlock() if virtualBlock.SelectedTipHash() != item.Block.BlockHash() || - virtualBlock.SelectedTipHeight() != blockHeight { + dag.Height() != blockHeight { //TODO: (Ori) the use of dag.Height() and virtualBlock.SelectedTipHash() is wrong, and was done only for compilation t.Fatalf("block %q (hash %s, height %d) should be "+ "the current tip -- got (hash %s, height %d)", item.Name, block.Hash(), blockHeight, virtualBlock.SelectedTipHash(), - virtualBlock.SelectedTipHeight()) + dag.Height()) //TODO: (Ori) the use of dag.Height() and virtualBlock.SelectedTipHash() is wrong, and was done only for compilation } } diff --git a/blockdag/virtualblock.go b/blockdag/virtualblock.go index ae98400af..e1a007f9f 100644 --- a/blockdag/virtualblock.go +++ b/blockdag/virtualblock.go @@ -101,17 +101,6 @@ func (v *VirtualBlock) SelectedTip() *blockNode { return v.selectedParent } -// SelectedTipHeight returns the height of the selected tip of the virtual block. -func (v *VirtualBlock) SelectedTipHeight() int32 { - return v.SelectedTip().height -} - -// Height returns the height of the virtual block. -// In other words: height of highest block + 1 -func (v *VirtualBlock) Height() int32 { - return v.tips().maxHeight() + 1 -} - // TipHashes returns the hashes of the tips of the virtual block. func (v *VirtualBlock) TipHashes() []daghash.Hash { return v.tips().hashes() diff --git a/cmd/findcheckpoint/findcheckpoint.go b/cmd/findcheckpoint/findcheckpoint.go index 87ef91113..7eff25b24 100644 --- a/cmd/findcheckpoint/findcheckpoint.go +++ b/cmd/findcheckpoint/findcheckpoint.go @@ -163,7 +163,7 @@ func main() { // Get the latest block hash and height from the database and report // status. virtualBlock := dag.VirtualBlock() - fmt.Printf("Block database loaded with block height %d\n", virtualBlock.SelectedTipHeight()) + fmt.Printf("Block database loaded with block height %d\n", dag.Height()) // Find checkpoint candidates. selectedTipHash := virtualBlock.SelectedTipHash() diff --git a/mining/cpuminer/cpuminer.go b/mining/cpuminer/cpuminer.go index fdd603168..fe1b43983 100644 --- a/mining/cpuminer/cpuminer.go +++ b/mining/cpuminer/cpuminer.go @@ -16,8 +16,8 @@ import ( "github.com/daglabs/btcd/dagconfig" "github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/mining" - "github.com/daglabs/btcd/wire" "github.com/daglabs/btcd/util" + "github.com/daglabs/btcd/wire" ) const ( @@ -326,7 +326,7 @@ out: // this would otherwise end up building a new block template on // a block that is in the process of becoming stale. m.submitBlockLock.Lock() - curHeight := m.g.VirtualBlock().SelectedTipHeight() + curHeight := m.g.DAGHeight() if curHeight != 0 && !m.cfg.IsCurrent() { m.submitBlockLock.Unlock() time.Sleep(time.Second) @@ -585,7 +585,7 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*daghash.Hash, error) { // be changing and this would otherwise end up building a new block // template on a block that is in the process of becoming stale. m.submitBlockLock.Lock() - curHeight := m.g.VirtualBlock().SelectedTipHeight() + curHeight := m.g.DAGHeight() // Choose a payment address at random. rand.Seed(time.Now().UnixNano()) diff --git a/mining/mining.go b/mining/mining.go index 18d6c70c0..181b25ddc 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -403,7 +403,7 @@ func NewBlkTmplGenerator(policy *Policy, params *dagconfig.Params, func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress util.Address) (*BlockTemplate, error) { // Extend the most recently known best block. virtualBlock := g.dag.VirtualBlock() - nextBlockHeight := virtualBlock.Height() + nextBlockHeight := g.dag.Height() + 1 // Create a standard coinbase transaction paying to the provided // address. NOTE: The coinbase value will be updated to include the @@ -815,6 +815,11 @@ func (g *BlkTmplGenerator) VirtualBlock() *blockdag.VirtualBlock { return g.dag.VirtualBlock() } +// DAGHeight returns the DAG's height +func (g *BlkTmplGenerator) DAGHeight() int32 { + return g.dag.Height() +} + // TxSource returns the associated transaction source. // // This function is safe for concurrent access. diff --git a/netsync/manager.go b/netsync/manager.go index 4df13ddaa..c4a420865 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -227,7 +227,6 @@ func (sm *SyncManager) startSync() { return } - virtualBlock := sm.dag.VirtualBlock() var bestPeer *peerpkg.Peer for peer, state := range sm.peerStates { if !state.syncCandidate { @@ -240,7 +239,7 @@ func (sm *SyncManager) startSync() { // doesn't have a later block when it's equal, it will likely // have one soon so it is a reasonable choice. It also allows // the case where both are at 0 such as during regression test. - if peer.LastBlock() < virtualBlock.SelectedTipHeight() { + if peer.LastBlock() < sm.dag.Height() { //TODO: (Ori) This is probably wrong. Done only for compilation state.syncCandidate = false continue } @@ -285,14 +284,14 @@ func (sm *SyncManager) startSync() { // not support the headers-first approach so do normal block // downloads when in regression test mode. if sm.nextCheckpoint != nil && - virtualBlock.SelectedTipHeight() < sm.nextCheckpoint.Height && - sm.chainParams != &dagconfig.RegressionNetParams { + sm.dag.Height() < sm.nextCheckpoint.Height && + sm.chainParams != &dagconfig.RegressionNetParams { //TODO: (Ori) This is probably wrong. Done only for compilation bestPeer.PushGetHeadersMsg(locator, sm.nextCheckpoint.Hash) sm.headersFirstMode = true log.Infof("Downloading headers for blocks %d to "+ - "%d from peer %s", virtualBlock.SelectedTipHeight()+1, - sm.nextCheckpoint.Height, bestPeer.Addr()) + "%d from peer %s", sm.dag.Height()+1, + sm.nextCheckpoint.Height, bestPeer.Addr()) //TODO: (Ori) This is probably wrong. Done only for compilation } else { bestPeer.PushGetBlocksMsg(locator, &zeroHash) } @@ -395,7 +394,7 @@ func (sm *SyncManager) handleDonePeerMsg(peer *peerpkg.Peer) { if sm.headersFirstMode { virtualBlock := sm.dag.VirtualBlock() selectedTipHash := virtualBlock.SelectedTipHash() - sm.resetHeaderState(&selectedTipHash, virtualBlock.SelectedTipHeight()) + sm.resetHeaderState(&selectedTipHash, sm.dag.Height()) //TODO: (Ori) This is probably wrong. Done only for compilation } sm.startSync() } @@ -484,7 +483,7 @@ func (sm *SyncManager) current() bool { // No matter what chain thinks, if we are below the block we are syncing // to we are not current. - if sm.dag.VirtualBlock().SelectedTipHeight() < sm.syncPeer.LastBlock() { + if sm.dag.Height() < sm.syncPeer.LastBlock() { //TODO: (Ori) This is probably wrong. Done only for compilation return false } return true @@ -619,7 +618,7 @@ func (sm *SyncManager) handleBlockMsg(bmsg *blockMsg) { // potential sync node candidacy. virtualBlock := sm.dag.VirtualBlock() selectedTipHash := virtualBlock.SelectedTipHash() - heightUpdate = virtualBlock.SelectedTipHeight() + heightUpdate = sm.dag.Height() //TODO: (Ori) This is probably wrong. Done only for compilation blkHashUpdate = &selectedTipHash // Clear the rejected transactions. @@ -1394,9 +1393,9 @@ func New(config *Config) (*SyncManager, error) { selectedTipHash := virtualBlock.SelectedTipHash() if !config.DisableCheckpoints { // Initialize the next checkpoint based on the current height. - sm.nextCheckpoint = sm.findNextHeaderCheckpoint(virtualBlock.SelectedTipHeight()) + sm.nextCheckpoint = sm.findNextHeaderCheckpoint(sm.dag.Height()) //TODO: (Ori) This is probably wrong. Done only for compilation if sm.nextCheckpoint != nil { - sm.resetHeaderState(&selectedTipHash, virtualBlock.SelectedTipHeight()) + sm.resetHeaderState(&selectedTipHash, sm.dag.Height()) //TODO: (Ori) This is probably wrong. Done only for compilation) } } else { log.Info("Checkpoints are disabled") diff --git a/server/p2p/p2p.go b/server/p2p/p2p.go index 5a2d1e344..ea3be7528 100644 --- a/server/p2p/p2p.go +++ b/server/p2p/p2p.go @@ -292,7 +292,7 @@ func newServerPeer(s *Server, isPersistent bool) *Peer { func (sp *Peer) newestBlock() (*daghash.Hash, int32, error) { virtualBlock := sp.server.DAG.VirtualBlock() selectedTipHash := virtualBlock.SelectedTipHash() - return &selectedTipHash, virtualBlock.SelectedTipHeight(), nil + return &selectedTipHash, sp.server.DAG.Height(), nil //TODO: (Ori) This is probably wrong. Done only for compilation } // addKnownAddresses adds the given addresses to the set of known addresses to @@ -2419,7 +2419,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params // If no feeEstimator has been found, or if the one that has been found // is behind somehow, create a new one and start over. - if s.FeeEstimator == nil || s.FeeEstimator.LastKnownHeight() != s.DAG.VirtualBlock().SelectedTipHeight() { + if s.FeeEstimator == nil || s.FeeEstimator.LastKnownHeight() != s.DAG.Height() { //TODO: (Ori) This is probably wrong. Done only for compilation s.FeeEstimator = mempool.NewFeeEstimator( mempool.DefaultEstimateFeeMaxRollback, mempool.DefaultEstimateFeeMinRegisteredBlocks) @@ -2437,7 +2437,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params MaxTxVersion: 1, }, DAGParams: dagParams, - BestHeight: func() int32 { return s.DAG.VirtualBlock().SelectedTipHeight() }, + BestHeight: func() int32 { return s.DAG.Height() }, //TODO: (Ori) This is probably wrong. Done only for compilation MedianTimePast: func() time.Time { return s.DAG.VirtualBlock().SelectedTip().CalcPastMedianTime() }, CalcSequenceLock: func(tx *util.Tx, utxoSet blockdag.UTXOSet) (*blockdag.SequenceLock, error) { return s.DAG.CalcSequenceLock(tx, utxoSet, true) diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index c840527a5..76979e61d 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -1011,7 +1011,7 @@ func handleGetBestBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) ( virtualBlock := s.cfg.DAG.VirtualBlock() result := &btcjson.GetBestBlockResult{ Hash: virtualBlock.SelectedTipHash().String(), - Height: virtualBlock.SelectedTipHeight(), + Height: s.cfg.DAG.Height(), //TODO: (Ori) This is probably wrong. Done only for compilation } return result, nil } @@ -1086,11 +1086,10 @@ func handleGetBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte return nil, internalRPCError(err.Error(), context) } blk.SetHeight(blockHeight) - virtualBlock := s.cfg.DAG.VirtualBlock() // Get the hashes for the next blocks unless there are none. var nextHashStrings []string - if blockHeight < virtualBlock.SelectedTipHeight() { + if blockHeight < s.cfg.DAG.Height() { //TODO: (Ori) This is probably wrong. Done only for compilation childHashes, err := s.cfg.DAG.ChildHashesByHash(hash) if err != nil { context := "No next block" @@ -1109,7 +1108,7 @@ func handleGetBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte PreviousHashes: daghash.Strings(blockHeader.PrevBlocks), Nonce: blockHeader.Nonce, Time: blockHeader.Timestamp.Unix(), - Confirmations: uint64(1 + virtualBlock.SelectedTipHeight() - blockHeight), + Confirmations: uint64(1 + s.cfg.DAG.Height() - blockHeight), //TODO: (Ori) This is probably wrong. Done only for compilation Height: int64(blockHeight), Size: int32(len(blkBytes)), Bits: strconv.FormatInt(int64(blockHeader.Bits), 16), @@ -1131,7 +1130,7 @@ func handleGetBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte for i, tx := range txns { rawTxn, err := createTxRawResult(params, tx.MsgTx(), tx.Hash().String(), blockHeader, hash.String(), - blockHeight, virtualBlock.SelectedTipHeight()) + blockHeight, s.cfg.DAG.Height()) //TODO: (Ori) This is probably wrong. Done only for compilation if err != nil { return nil, err } @@ -1172,8 +1171,8 @@ func handleGetBlockDAGInfo(s *Server, cmd interface{}, closeChan <-chan struct{} dagInfo := &btcjson.GetBlockDAGInfoResult{ DAG: params.Name, - Blocks: virtualBlock.SelectedTipHeight(), - Headers: virtualBlock.SelectedTipHeight(), + Blocks: dag.Height(), //TODO: (Ori) This is wrong. Done only for compilation + Headers: dag.Height(), //TODO: (Ori) This is wrong. Done only for compilation TipHashes: daghash.Strings(virtualBlock.TipHashes()), Difficulty: getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, params), MedianTime: virtualBlock.SelectedTip().CalcPastMedianTime().Unix(), @@ -1234,8 +1233,7 @@ func handleGetBlockDAGInfo(s *Server, cmd interface{}, closeChan <-chan struct{} // handleGetBlockCount implements the getblockcount command. func handleGetBlockCount(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - virtualBlock := s.cfg.DAG.VirtualBlock() - return int64(virtualBlock.SelectedTipHeight()), nil + return int64(s.cfg.DAG.Height()), nil //TODO: (Ori) This is wrong. Done only for compilation } // handleGetBlockHash implements the getblockhash command. @@ -1282,11 +1280,10 @@ func handleGetBlockHeader(s *Server, cmd interface{}, closeChan <-chan struct{}) context := "Failed to obtain block height" return nil, internalRPCError(err.Error(), context) } - virtualBlock := s.cfg.DAG.VirtualBlock() // Get the hashes for the next blocks unless there are none. var nextHashStrings []string - if blockHeight < virtualBlock.SelectedTipHeight() { + if blockHeight < s.cfg.DAG.Height() { //TODO: (Ori) This is probably wrong. Done only for compilation childHashes, err := s.cfg.DAG.ChildHashesByHash(hash) if err != nil { context := "No next block" @@ -1298,7 +1295,7 @@ func handleGetBlockHeader(s *Server, cmd interface{}, closeChan <-chan struct{}) params := s.cfg.ChainParams blockHeaderReply := btcjson.GetBlockHeaderVerboseResult{ Hash: c.Hash, - Confirmations: uint64(1 + virtualBlock.SelectedTipHeight() - blockHeight), + Confirmations: uint64(1 + s.cfg.DAG.Height() - blockHeight), //TODO: (Ori) This is probably wrong. Done only for compilation Height: blockHeight, Version: blockHeader.Version, VersionHex: fmt.Sprintf("%08x", blockHeader.Version), @@ -1888,7 +1885,7 @@ func handleGetBlockTemplateRequest(s *Server, request *btcjson.TemplateRequest, } // No point in generating or accepting work before the chain is synced. - currentHeight := s.cfg.DAG.VirtualBlock().SelectedTipHeight() + currentHeight := s.cfg.DAG.Height() if currentHeight != 0 && !s.cfg.SyncMgr.IsCurrent() { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCClientInInitialDownload, @@ -2237,7 +2234,7 @@ func handleGetInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (inter ret := &btcjson.InfoDAGResult{ Version: int32(1000000*version.AppMajor + 10000*version.AppMinor + 100*version.AppPatch), ProtocolVersion: int32(maxProtocolVersion), - Blocks: virtualBlock.SelectedTipHeight(), + Blocks: s.cfg.DAG.Height(), //TODO: (Ori) This is wrong. Done only for compilation TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()), Connections: s.cfg.ConnMgr.ConnectedCount(), Proxy: config.MainConfig().Proxy, @@ -2296,7 +2293,7 @@ func handleGetMiningInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) } result := btcjson.GetMiningInfoResult{ - Blocks: int64(virtualBlock.SelectedTipHeight()), + Blocks: int64(s.cfg.DAG.Height()), //TODO: (Ori) This is wrong. Done only for compilation CurrentBlockSize: uint64(selectedBlock.MsgBlock().SerializeSize()), CurrentBlockTx: uint64(len(selectedBlock.MsgBlock().Transactions)), Difficulty: getDifficultyRatio(virtualBlock.SelectedTip().Header().Bits, s.cfg.ChainParams), @@ -2495,7 +2492,7 @@ func handleGetRawTransaction(s *Server, cmd interface{}, closeChan <-chan struct blkHeader = &header blkHashStr = blkHash.String() - dagHeight = s.cfg.DAG.VirtualBlock().SelectedTipHeight() + dagHeight = s.cfg.DAG.Height() } rawTxn, err := createTxRawResult(s.cfg.ChainParams, mtx, txHash.String(), @@ -2575,7 +2572,7 @@ func handleGetTxOut(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte virtualBlock := s.cfg.DAG.VirtualBlock() bestBlockHash = virtualBlock.SelectedTipHash().String() - confirmations = 1 + virtualBlock.SelectedTipHeight() - entry.BlockHeight() + confirmations = 1 + s.cfg.DAG.Height() - entry.BlockHeight() //TODO: (Ori) This is probably wrong. Done only for compilation value = entry.Amount() pkScript = entry.PkScript() isCoinbase = entry.IsCoinBase() @@ -3068,7 +3065,6 @@ func handleSearchRawTransactions(s *Server, cmd interface{}, closeChan <-chan st } // The verbose flag is set, so generate the JSON object and return it. - virtualBlock := s.cfg.DAG.VirtualBlock() srtList := make([]btcjson.SearchRawTransactionsResult, len(addressTxns)) for i := range addressTxns { // The deserialized transaction is needed, so deserialize the @@ -3138,7 +3134,7 @@ func handleSearchRawTransactions(s *Server, cmd interface{}, closeChan <-chan st result.Time = uint64(blkHeader.Timestamp.Unix()) result.Blocktime = uint64(blkHeader.Timestamp.Unix()) result.BlockHash = blkHashStr - result.Confirmations = uint64(1 + virtualBlock.SelectedTipHeight() - blkHeight) + result.Confirmations = uint64(1 + s.cfg.DAG.Height() - blkHeight) //TODO: (Ori) This is probably wrong. Done only for compilation } } @@ -3327,15 +3323,15 @@ func handleValidateAddress(s *Server, cmd interface{}, closeChan <-chan struct{} func verifyDAG(s *Server, level, depth int32) error { virtualBlock := s.cfg.DAG.VirtualBlock() - finishHeight := virtualBlock.SelectedTipHeight() - depth + finishHeight := s.cfg.DAG.Height() - depth //TODO: (Ori) This is probably wrong. Done only for compilation if finishHeight < 0 { finishHeight = 0 } log.Infof("Verifying chain for %d blocks at level %d", - virtualBlock.SelectedTipHeight()-finishHeight, level) + s.cfg.DAG.Height()-finishHeight, level) //TODO: (Ori) This is probably wrong. Done only for compilation currentHash := virtualBlock.SelectedTipHash() - for height := virtualBlock.SelectedTipHeight(); height > finishHeight; { + for height := s.cfg.DAG.Height(); height > finishHeight; { //TODO: (Ori) This is probably wrong. Done only for compilation // Level 0 just looks up the block. block, err := s.cfg.DAG.BlockByHash(¤tHash) if err != nil {