Skip to content

Commit

Permalink
Kill database.Block and use btcutil.Block everywhere instead
Browse files Browse the repository at this point in the history
  • Loading branch information
marcopeereboom committed Jul 26, 2024
1 parent b4035af commit 58740de
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 77 deletions.
11 changes: 3 additions & 8 deletions database/tbcd/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"math/big"
"time"

"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"

Expand Down Expand Up @@ -60,10 +61,10 @@ type Database interface {

// Block
BlocksMissing(ctx context.Context, count int) ([]BlockIdentifier, error)
BlockInsert(ctx context.Context, b *Block) (int64, error)
BlockInsert(ctx context.Context, b *btcutil.Block) (int64, error)
// XXX replace BlockInsert with plural version
// BlocksInsert(ctx context.Context, bs []*Block) (int64, error)
BlockByHash(ctx context.Context, hash *chainhash.Hash) (*Block, error)
BlockByHash(ctx context.Context, hash *chainhash.Hash) (*btcutil.Block, error)

// Transactions
BlockUtxoUpdate(ctx context.Context, direction int, utxos map[Outpoint]CacheOutput) error
Expand Down Expand Up @@ -126,12 +127,6 @@ func (bh BlockHeader) ParentHash() *chainhash.Hash {
return &wh.PrevBlock
}

// Block contains a raw bitcoin block and its corresponding hash.
type Block struct {
Hash *chainhash.Hash
Block database.ByteArray // this needs to be converted to either wire or btcutil
}

// BlockIdentifier uniquely identifies a block using it's hash and height.
type BlockIdentifier struct {
Height uint64
Expand Down
35 changes: 24 additions & 11 deletions database/tbcd/level/level.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"time"

"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/davecgh/go-spew/spew"
"github.com/dgraph-io/ristretto"
Expand Down Expand Up @@ -627,28 +628,32 @@ func (l *ldb) BlocksMissing(ctx context.Context, count int) ([]tbcd.BlockIdentif
return bis, nil
}

func (l *ldb) BlockInsert(ctx context.Context, b *tbcd.Block) (int64, error) {
func (l *ldb) BlockInsert(ctx context.Context, b *btcutil.Block) (int64, error) {
log.Tracef("BlockInsert")
defer log.Tracef("BlockInsert exit")

bh, err := l.BlockHeaderByHash(ctx, b.Hash)
bh, err := l.BlockHeaderByHash(ctx, b.Hash())
if err != nil {
return -1, fmt.Errorf("block header by hash: %w", err)
}

// Insert block without transaction, if it succeeds and the missing
// does not it will be simply redone.
bDB := l.pool[level.BlocksDB]
has, err := bDB.Has(b.Hash[:], nil)
has, err := bDB.Has(b.Hash()[:], nil)
if err != nil {
return -1, fmt.Errorf("block insert has: %w", err)
}
if !has {
// Insert block since we do not have it yet
if err = bDB.Put(b.Hash[:], b.Block, nil); err != nil {
rawBlock, err := b.Bytes()
if err != nil {
return -1, fmt.Errorf("encoding block: %w", err)
}
if err = bDB.Put(b.Hash()[:], rawBlock, nil); err != nil {
return -1, fmt.Errorf("blocks insert put: %w", err)
}
l.blockCache.Set(string(b.Hash[:]), b, int64(len(b.Hash)+len(b.Block)))
l.blockCache.Set(string(b.Hash()[:]), b, int64(32+len(rawBlock)))
}

// Remove block identifier from blocks missing
Expand All @@ -664,14 +669,20 @@ func (l *ldb) BlockInsert(ctx context.Context, b *tbcd.Block) (int64, error) {
return int64(bh.Height), nil
}

func (l *ldb) BlockByHash(ctx context.Context, hash *chainhash.Hash) (*tbcd.Block, error) {
func (l *ldb) BlockByHash(ctx context.Context, hash *chainhash.Hash) (*btcutil.Block, error) {
log.Tracef("BlockByHash")
defer log.Tracef("BlockByHash exit")

// Get height
bh, err := l.BlockHeaderByHash(ctx, hash)
if err != nil {
return nil, fmt.Errorf("could not obtain block height: %w", err)
}

// Try cache first
cb, _ := l.blockCache.Get(string(hash[:]))
if cb != nil {
return cb.(*tbcd.Block), nil
return cb.(*btcutil.Block), nil
}

bDB := l.pool[level.BlocksDB]
Expand All @@ -682,11 +693,13 @@ func (l *ldb) BlockByHash(ctx context.Context, hash *chainhash.Hash) (*tbcd.Bloc
}
return nil, fmt.Errorf("block get: %w", err)
}
b := &tbcd.Block{
Hash: hash,
Block: eb,
b, err := btcutil.NewBlockFromBytes(eb)
if err != nil {
return nil, fmt.Errorf("block decode: %w", err)
}
l.blockCache.Set(string(hash[:]), b, int64(len(b.Hash)+len(b.Block)))
b.SetHeight(int32(bh.Height))
l.blockCache.Set(string(hash[:]), b, int64(32+len(eb)))

return b, nil
}

Expand Down
30 changes: 5 additions & 25 deletions service/tbc/crawler.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,10 @@ func (s *Server) scriptValue(ctx context.Context, op tbcd.Outpoint) ([]byte, int
if len(blockHashes) == 0 {
return nil, 0, errors.New("script value: no block hashes")
}
blk, err := s.db.BlockByHash(ctx, blockHashes[0])
b, err := s.db.BlockByHash(ctx, blockHashes[0])
if err != nil {
return nil, 0, fmt.Errorf("block by hash: %w", err)
}
b, err := btcutil.NewBlockFromBytes(blk.Block)
if err != nil {
return nil, 0, fmt.Errorf("new block: %w", err)
}
for _, tx := range b.Transactions() {
if !tx.Hash().IsEqual(txId) {
continue
Expand Down Expand Up @@ -316,14 +312,10 @@ func (s *Server) indexUtxosInBlocks(ctx context.Context, endHash *chainhash.Hash
}

// Index block
eb, err := s.db.BlockByHash(ctx, bh.Hash)
b, err := s.db.BlockByHash(ctx, bh.Hash)
if err != nil {
return 0, last, fmt.Errorf("block by hash %v: %w", bh, err)
}
b, err := btcutil.NewBlockFromBytes(eb.Block)
if err != nil {
return 0, last, fmt.Errorf("could not decode block %v: %w", hh, err)
}

// fixupCache is executed in parallel meaning that the utxos
// map must be locked as it is being processed.
Expand Down Expand Up @@ -430,14 +422,10 @@ func (s *Server) unindexUtxosInBlocks(ctx context.Context, endHash *chainhash.Ha
}

// Index block
eb, err := s.db.BlockByHash(ctx, bh.Hash)
b, err := s.db.BlockByHash(ctx, bh.Hash)
if err != nil {
return 0, last, fmt.Errorf("block by hash %v: %w", bh, err)
}
b, err := btcutil.NewBlockFromBytes(eb.Block)
if err != nil {
return 0, last, fmt.Errorf("could not decode block %v: %w", hh, err)
}

err = s.unprocessUtxos(ctx, b.Transactions(), utxos)
if err != nil {
Expand Down Expand Up @@ -691,14 +679,10 @@ func (s *Server) indexTxsInBlocks(ctx context.Context, endHash *chainhash.Hash,
}

// Index block
eb, err := s.db.BlockByHash(ctx, bh.Hash)
b, err := s.db.BlockByHash(ctx, bh.Hash)
if err != nil {
return 0, last, fmt.Errorf("block by hash %v: %w", bh, err)
}
b, err := btcutil.NewBlockFromBytes(eb.Block)
if err != nil {
return 0, last, fmt.Errorf("could not decode block %v: %w", hh, err)
}

err = processTxs(b.Hash(), b.Transactions(), txs)
if err != nil {
Expand Down Expand Up @@ -797,14 +781,10 @@ func (s *Server) unindexTxsInBlocks(ctx context.Context, endHash *chainhash.Hash
}

// Index block
eb, err := s.db.BlockByHash(ctx, bh.Hash)
b, err := s.db.BlockByHash(ctx, bh.Hash)
if err != nil {
return 0, last, fmt.Errorf("block by hash %v: %w", bh, err)
}
b, err := btcutil.NewBlockFromBytes(eb.Block)
if err != nil {
return 0, last, fmt.Errorf("could not decode block %v: %w", hh, err)
}

err = processTxs(b.Hash(), b.Transactions(), txs)
if err != nil {
Expand Down
41 changes: 8 additions & 33 deletions service/tbc/tbc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1241,18 +1241,14 @@ func (s *Server) handleBlock(ctx context.Context, p *peer, msg *wire.MsgBlock) {

block := btcutil.NewBlock(msg)
bhs := block.Hash().String()
bb, err := block.Bytes() // XXX we should not being doing this twice but requires a modification to the wire package
rawBlock, err := block.Bytes()
if err != nil {
log.Errorf("block bytes %v: %v", block.Hash(), err)
log.Errorf("Unable to get raw block %v: %v", bhs, err)
return
}
b := &tbcd.Block{
Hash: block.Hash(),
Block: bb,
}

if s.cfg.BlockSanity {
err = blockchain.CheckBlockSanity(block, s.chainParams.PowLimit,
err := blockchain.CheckBlockSanity(block, s.chainParams.PowLimit,
s.timeSource)
if err != nil {
log.Errorf("Unable to validate block hash %v: %v", bhs, err)
Expand All @@ -1274,7 +1270,7 @@ func (s *Server) handleBlock(ctx context.Context, p *peer, msg *wire.MsgBlock) {
// }
}

height, err := s.db.BlockInsert(ctx, b)
height, err := s.db.BlockInsert(ctx, block)
if err != nil {
log.Errorf("block insert %v: %v", bhs, err)
} else {
Expand Down Expand Up @@ -1307,7 +1303,7 @@ func (s *Server) handleBlock(ctx context.Context, p *peer, msg *wire.MsgBlock) {

// Stats
if err == nil {
s.blocksSize += uint64(len(b.Block) + len(b.Hash))
s.blocksSize += uint64(len(rawBlock) + 32)
if _, ok := s.blocksInserted[bhs]; ok {
s.blocksDuplicate++
} else {
Expand Down Expand Up @@ -1376,14 +1372,7 @@ func (s *Server) insertGenesis(ctx context.Context) error {
}

log.Debugf("Inserting genesis block")
gb, err := btcutil.NewBlock(s.chainParams.GenesisBlock).Bytes()
if err != nil {
return fmt.Errorf("genesis block encode: %w", err)
}
_, err = s.db.BlockInsert(ctx, &tbcd.Block{
Hash: s.chainParams.GenesisHash,
Block: gb,
})
_, err = s.db.BlockInsert(ctx, btcutil.NewBlock(s.chainParams.GenesisBlock))
if err != nil {
return fmt.Errorf("genesis block insert: %w", err)
}
Expand Down Expand Up @@ -1577,13 +1566,7 @@ func (s *Server) TxById(ctx context.Context, txId *chainhash.Hash) (*wire.MsgTx,
if err != nil {
return nil, err
}

parsedBlock, err := btcutil.NewBlockFromBytes(block.Block)
if err != nil {
return nil, err
}

for _, tx := range parsedBlock.Transactions() {
for _, tx := range block.Transactions() {
if tx.Hash().IsEqual(txId) {
return tx.MsgTx(), nil
}
Expand Down Expand Up @@ -1631,15 +1614,10 @@ func (s *Server) FeesAtHeight(ctx context.Context, height, count int64) (uint64,
panic("fees at height: unsupported fork")
// return 0, fmt.Errorf("too many block headers: %v", len(bhs))
}
be, err := s.db.BlockByHash(ctx, bhs[0].Hash)
b, err := s.db.BlockByHash(ctx, bhs[0].Hash)
if err != nil {
return 0, fmt.Errorf("block by hash: %w", err)
}
b, err := btcutil.NewBlockFromBytes(be.Block)
if err != nil {
return 0, fmt.Errorf("could not decode block %v %v: %v",
height, bhs[0].Hash, err)
}

// walk block tx'
if err = feesFromTransactions(b.Transactions()); err != nil {
Expand All @@ -1656,9 +1634,6 @@ type SyncInfo struct {
BlockHeader HashHeight
Utxo HashHeight
Tx HashHeight
// BlockHeaderHeight uint64 // last block header height
// UtxoHeight uint64 // last indexed utxo block height
// TxHeight uint64 // last indexed tx block height
}

func (s *Server) synced(ctx context.Context) (si SyncInfo) {
Expand Down

0 comments on commit 58740de

Please sign in to comment.