diff --git a/blockbook.go b/blockbook.go index c3bb4884..6bbe5a2f 100644 --- a/blockbook.go +++ b/blockbook.go @@ -23,12 +23,8 @@ type AddressTransactionOracle interface { GetAddressTransactions(address string, lower uint32, higher uint32, fn func(txids []string) error) error } -type OutpointIndex interface { - IndexBlockOutpoints(block *Block) error -} - -type AddressIndex interface { - IndexBlockAddresses(block *Block, txids map[string][]string) error +type BlockIndex interface { + IndexBlock(block *Block, txids map[string][]string) error } var ( @@ -86,7 +82,7 @@ func main() { log.Fatal(err) } } else { - if err = indexBlocks(rpc, rpc, db, db, height, until); err != nil { + if err = indexBlocks(rpc, rpc, db, height, until); err != nil { log.Fatal(err) } } @@ -148,7 +144,7 @@ func (tx *Tx) CollectAddresses(o OutpointAddressOracle) ([]string, error) { return addrs, nil } -func indexBlocks(bo BlockOracle, oao OutpointAddressOracle, ai AddressIndex, oi OutpointIndex, lower uint32, higher uint32) error { +func indexBlocks(bo BlockOracle, oao OutpointAddressOracle, bi BlockIndex, lower uint32, higher uint32) error { for height := lower; height <= higher; height++ { hash, err := bo.GetBlockHash(height) if err != nil { @@ -162,10 +158,7 @@ func indexBlocks(bo BlockOracle, oao OutpointAddressOracle, ai AddressIndex, oi if err != nil { return err } - if err := oi.IndexBlockOutpoints(block); err != nil { - return err - } - if err := ai.IndexBlockAddresses(block, addrs); err != nil { + if err := bi.IndexBlock(block, addrs); err != nil { return err } } diff --git a/rocksdb.go b/rocksdb.go index bf3b8cf4..aa2e3111 100644 --- a/rocksdb.go +++ b/rocksdb.go @@ -87,14 +87,28 @@ func (d *RocksDB) GetAddressTransactions(address string, lower uint32, higher ui return nil } -// Address Index - -func (d *RocksDB) IndexBlockAddresses(block *Block, txids map[string][]string) error { - log.Printf("rocksdb: address put %d in %d %s", len(txids), block.Height, block.Hash) - +func (d *RocksDB) IndexBlock(block *Block, txids map[string][]string) error { wb := gorocksdb.NewWriteBatch() defer wb.Destroy() + if err := d.writeHeight(wb, block); err != nil { + return err + } + if err := d.writeOutpoints(wb, block); err != nil { + return err + } + if err := d.writeAddresses(wb, block, txids); err != nil { + return err + } + + return d.db.Write(d.wo, wb) +} + +// Address Index + +func (d *RocksDB) writeAddresses(wb *gorocksdb.WriteBatch, block *Block, txids map[string][]string) error { + log.Printf("rocksdb: address put %d in %d %s", len(txids), block.Height, block.Hash) + for addr, txids := range txids { k, err := packAddressKey(block.Height, addr) if err != nil { @@ -106,8 +120,7 @@ func (d *RocksDB) IndexBlockAddresses(block *Block, txids map[string][]string) e } wb.Put(k, v) } - - return d.db.Write(d.wo, wb) + return nil } func packAddressKey(height uint32, address string) (b []byte, err error) { @@ -146,19 +159,9 @@ func unpackAddressVal(b []byte) (txids []string, err error) { // Outpoint index -func (d *RocksDB) IndexBlockOutpoints(block *Block) error { +func (d *RocksDB) writeOutpoints(wb *gorocksdb.WriteBatch, block *Block) error { log.Printf("rocksdb: outpoints put %d in %d %s", len(block.Txs), block.Height, block.Hash) - wb := gorocksdb.NewWriteBatch() - defer wb.Destroy() - - bv, err := packBlockValue(block.Hash) - if err != nil { - return err - } - bk := packUint(block.Height) - wb.Put(bk, bv) - for _, tx := range block.Txs { for _, vout := range tx.Vout { k, err := packOutpointKey(block.Height, tx.Txid, vout.N) @@ -172,8 +175,7 @@ func (d *RocksDB) IndexBlockOutpoints(block *Block) error { wb.Put(k, v) } } - - return d.db.Write(d.wo, wb) + return nil } func packOutpointKey(height uint32, txid string, vout uint32) (b []byte, err error) { @@ -223,6 +225,21 @@ func unpackOutpointValue(b []byte) (addrs []string, err error) { return } +// Block index + +func (d *RocksDB) writeHeight(wb *gorocksdb.WriteBatch, block *Block) error { + log.Printf("rocksdb: height put %d %s", block.Height, block.Hash) + + bv, err := packBlockValue(block.Hash) + if err != nil { + return err + } + bk := packUint(block.Height) + wb.Put(bk, bv) + + return nil +} + // Helpers func packUint(i uint32) []byte {