Skip to content

Commit

Permalink
Added block hash into block key
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverbundalo committed Feb 26, 2024
1 parent 89e648d commit 63f046b
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 95 deletions.
18 changes: 9 additions & 9 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ func (b *Blockchain) GetReceiptsByHash(hash types.Hash) ([]*types.Receipt, error
return nil, err
}

return b.db.ReadReceipts(n)
return b.db.ReadReceipts(n, hash)
}

// GetBodyByHash returns the body by their hash
Expand Down Expand Up @@ -478,7 +478,7 @@ func (b *Blockchain) readHeader(hash types.Hash) (*types.Header, bool) {
return nil, false
}

hh, err := b.db.ReadHeader(n)
hh, err := b.db.ReadHeader(n, hash)
if err != nil {
return nil, false
}
Expand All @@ -497,7 +497,7 @@ func (b *Blockchain) readBody(hash types.Hash) (*types.Body, bool) {
return nil, false
}

bb, err := b.db.ReadBody(n)
bb, err := b.db.ReadBody(n, hash)
if err != nil {
b.logger.Error("failed to read body", "err", err)

Expand All @@ -508,7 +508,7 @@ func (b *Blockchain) readBody(hash types.Hash) (*types.Body, bool) {
if updated := b.recoverFromFieldsInTransactions(bb.Transactions); updated {
batchWriter := b.db.NewWriter()

batchWriter.PutBody(n, bb)
batchWriter.PutBody(n, hash, bb)

if err := batchWriter.WriteBatch(); err != nil {
b.logger.Warn("failed to write body into storage", "hash", hash, "err", err)
Expand Down Expand Up @@ -538,7 +538,7 @@ func (b *Blockchain) readTotalDifficulty(headerHash types.Hash) (*big.Int, bool)
return nil, false
}

dbDifficulty, ok := b.db.ReadTotalDifficulty(n)
dbDifficulty, ok := b.db.ReadTotalDifficulty(n, headerHash)
if !ok {
return nil, false
}
Expand Down Expand Up @@ -848,7 +848,7 @@ func (b *Blockchain) WriteFullBlock(fblock *types.FullBlock, source string) erro
// write the receipts, do it only after the header has been written.
// Otherwise, a client might ask for a header once the receipt is valid,
// but before it is written into the storage
batchWriter.PutReceipts(block.Number(), fblock.Receipts)
batchWriter.PutReceipts(block.Number(), block.Hash(), fblock.Receipts)

// update snapshot
if err := b.consensus.ProcessHeaders([]*types.Header{header}); err != nil {
Expand Down Expand Up @@ -919,7 +919,7 @@ func (b *Blockchain) WriteBlock(block *types.Block, source string) error {
// write the receipts, do it only after the header has been written.
// Otherwise, a client might ask for a header once the receipt is valid,
// but before it is written into the storage
batchWriter.PutReceipts(block.Number(), blockReceipts)
batchWriter.PutReceipts(block.Number(), block.Hash(), blockReceipts)

// update snapshot
if err := b.consensus.ProcessHeaders([]*types.Header{header}); err != nil {
Expand Down Expand Up @@ -1019,7 +1019,7 @@ func (b *Blockchain) writeBody(batchWriter *storagev2.Writer, block *types.Block
}

// Write the full body (txns + receipts)
batchWriter.PutBody(block.Number(), block.Body())
batchWriter.PutBody(block.Number(), block.Hash(), block.Body())

// Write txn lookups (txHash -> block number)
for _, txn := range block.Transactions {
Expand Down Expand Up @@ -1211,7 +1211,7 @@ func (b *Blockchain) writeHeaderImpl(
}

batchWriter.PutHeader(header)
batchWriter.PutTotalDifficulty(header.Number, incomingTD)
batchWriter.PutTotalDifficulty(header.Number, header.Hash, incomingTD)
batchWriter.PutForks(forks)
batchWriter.PutBlockLookup(header.Hash, header.Number)

Expand Down
54 changes: 12 additions & 42 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1097,16 +1097,18 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) {
assert.ErrorIs(t, blockchain.verifyBlockParent(block), ErrParentNotFound)
})

t.Run("Parent hash mismatch", func(t *testing.T) {
t.Run("Invalid parent hash", func(t *testing.T) {
t.Parallel()

// Set up the storage callback
storageCallback := func(storage *storagev2.Storage) {
h := emptyHeader
h := &types.Header{
Hash: types.ZeroHash,
}

w := storage.NewWriter()

w.PutBlockLookup(types.ZeroHash, h.Number)
w.PutBlockLookup(h.Hash, h.Number)
w.PutHeader(h)
err := w.WriteBatch()
require.NoError(t, err)
Expand All @@ -1128,38 +1130,6 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) {
assert.ErrorIs(t, blockchain.verifyBlockParent(block), ErrParentHashMismatch)
})

t.Run("Invalid block sequence", func(t *testing.T) {
t.Parallel()

// Set up the storage callback
storageCallback := func(storage *storagev2.Storage) {
h := emptyHeader

w := storage.NewWriter()

w.PutBlockLookup(types.ZeroHash, h.Number)
w.PutHeader(h)
err := w.WriteBatch()
require.NoError(t, err)
}

blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{
StorageCallback: storageCallback,
})
if err != nil {
t.Fatalf("unable to instantiate new blockchain, %v", err)
}

// Create a dummy block with a number much higher than the parent
block := &types.Block{
Header: &types.Header{
Number: 10,
},
}

assert.ErrorIs(t, blockchain.verifyBlockParent(block), ErrParentHashMismatch)
})

t.Run("Invalid block sequence", func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -1205,7 +1175,7 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) {

w := storage.NewWriter()

w.PutBlockLookup(types.ZeroHash, h.Number)
w.PutBlockLookup(h.Hash, h.Number)
w.PutHeader(h)
err := w.WriteBatch()
require.NoError(t, err)
Expand Down Expand Up @@ -1664,15 +1634,15 @@ func TestBlockchain_WriteFullBlock(t *testing.T) {
require.NoError(t, err)
require.Equal(t, header.Number, n)

b, err := bc.db.ReadBody(header.Number)
b, err := bc.db.ReadBody(header.Number, header.Hash)
require.NoError(t, err)
require.NotNil(t, b)

l, err := bc.db.ReadTxLookup(tx.Hash())
require.NoError(t, err)
require.Equal(t, header.Number, l)

h, err := bc.db.ReadHeader(header.Number)
h, err := bc.db.ReadHeader(header.Number, header.Hash)
require.NoError(t, err)
require.NotNil(t, h)

Expand All @@ -1684,11 +1654,11 @@ func TestBlockchain_WriteFullBlock(t *testing.T) {
require.True(t, ok)
require.Equal(t, header.Hash, ch)

td, ok := bc.db.ReadTotalDifficulty(header.Number)
td, ok := bc.db.ReadTotalDifficulty(header.Number, header.Hash)
require.True(t, ok)
require.NotNil(t, td)

r, err := bc.db.ReadReceipts(header.Number)
r, err := bc.db.ReadReceipts(header.Number, header.Hash)
require.NoError(t, err)
require.NotNil(t, r)
}
Expand Down Expand Up @@ -1810,9 +1780,9 @@ func blockWriter(tb testing.TB, numberOfBlocks uint64, blockTime, checkInterval
}

batchWriter.PutHeader(block.Block.Header)
batchWriter.PutBody(block.Block.Number(), block.Block.Body())
batchWriter.PutBody(block.Block.Number(), block.Block.Hash(), block.Block.Body())

batchWriter.PutReceipts(block.Block.Number(), receipts)
batchWriter.PutReceipts(block.Block.Number(), block.Block.Hash(), receipts)

require.NoError(tb, blockchain.writeBatchAndUpdate(batchWriter, block.Block.Header, big.NewInt(0), false))

Expand Down
12 changes: 6 additions & 6 deletions blockchain/storagev2/leveldb/leveldb_perf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *stora
}

// Main DB sorted
batchWriter.PutBody(b.Block.Number(), b.Block.Body())
batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body())
batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash())
batchWriter.PutHeader(b.Block.Header)
batchWriter.PutReceipts(b.Block.Number(), b.Receipts)
batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts)

return batchWriter
}
Expand Down Expand Up @@ -230,16 +230,16 @@ func TestReadBlockPerf(t *testing.T) {
n := uint64(1 + rand.Intn(10000))

tn := time.Now().UTC()
_, err1 := s.ReadBody(n)
h, ok := s.ReadCanonicalHash(n)
_, err3 := s.ReadHeader(n)
_, err4 := s.ReadReceipts(n)
_, err1 := s.ReadBody(n, h)
_, err3 := s.ReadHeader(n, h)
_, err4 := s.ReadReceipts(n, h)
b, err5 := s.ReadBlockLookup(h)
d := time.Since(tn)

watchTime = watchTime + d.Milliseconds()

if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil {
if !ok || err1 != nil || err3 != nil || err4 != nil || err5 != nil {
t.Logf("\terror")
}

Expand Down
4 changes: 2 additions & 2 deletions blockchain/storagev2/leveldb/leveldb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ insertloop:
case b := <-blockchain:
batchWriter := s.NewWriter()

batchWriter.PutBody(b.Block.Number(), b.Block.Body())
batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body())

for _, tx := range b.Block.Transactions {
batchWriter.PutTxLookup(tx.Hash(), b.Block.Number())
Expand All @@ -239,7 +239,7 @@ insertloop:
batchWriter.PutHeader(b.Block.Header)
batchWriter.PutHeadNumber(uint64(i))
batchWriter.PutHeadHash(b.Block.Header.Hash)
batchWriter.PutReceipts(b.Block.Number(), b.Receipts)
batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts)
batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash())

if err := batchWriter.WriteBatch(); err != nil {
Expand Down
12 changes: 6 additions & 6 deletions blockchain/storagev2/mdbx/mdbx_perf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *stora
}

// Main DB sorted
batchWriter.PutBody(b.Block.Number(), b.Block.Body())
batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body())
batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash())
batchWriter.PutHeader(b.Block.Header)
batchWriter.PutReceipts(b.Block.Number(), b.Receipts)
batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts)

return batchWriter
}
Expand Down Expand Up @@ -205,16 +205,16 @@ func TestReadBlockPerf(t *testing.T) {
n := uint64(1 + rand.Intn(10000))

tn := time.Now().UTC()
_, err1 := s.ReadBody(n)
h, ok := s.ReadCanonicalHash(n)
_, err3 := s.ReadHeader(n)
_, err4 := s.ReadReceipts(n)
_, err1 := s.ReadBody(n, h)
_, err3 := s.ReadHeader(n, h)
_, err4 := s.ReadReceipts(n, h)
b, err5 := s.ReadBlockLookup(h)
d := time.Since(tn)

watchTime = watchTime + d.Milliseconds()

if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil {
if !ok || err1 != nil || err3 != nil || err4 != nil || err5 != nil {
t.Logf("\terror")
}

Expand Down
4 changes: 2 additions & 2 deletions blockchain/storagev2/mdbx/mdbx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ insertloop:
case b := <-blockchain:
batchWriter := s.NewWriter()

batchWriter.PutBody(b.Block.Number(), b.Block.Body())
batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body())

for _, tx := range b.Block.Transactions {
batchWriter.PutTxLookup(tx.Hash(), b.Block.Number())
Expand All @@ -229,7 +229,7 @@ insertloop:
batchWriter.PutHeader(b.Block.Header)
batchWriter.PutHeadNumber(uint64(i))
batchWriter.PutHeadHash(b.Block.Header.Hash)
batchWriter.PutReceipts(b.Block.Number(), b.Receipts)
batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts)
batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash())

if err := batchWriter.WriteBatch(); err != nil {
Expand Down
20 changes: 10 additions & 10 deletions blockchain/storagev2/storage_read.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

// -- canonical hash --

// ReadCanonicalHash gets the hash from the number of the canonical chain
// ReadCanonicalHash gets the hash from the number of the canonical block
func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, bool) {
data, ok := s.get(CANONICAL, common.EncodeUint64ToBytes(n))
if !ok {
Expand Down Expand Up @@ -58,8 +58,8 @@ func (s *Storage) ReadForks() ([]types.Hash, error) {
// DIFFICULTY //

// ReadTotalDifficulty reads the difficulty
func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, bool) {
v, ok := s.get(DIFFICULTY, common.EncodeUint64ToBytes(bn))
func (s *Storage) ReadTotalDifficulty(bn uint64, bh types.Hash) (*big.Int, bool) {
v, ok := s.get(DIFFICULTY, getKey(bn, bh))
if !ok {
return nil, false
}
Expand All @@ -70,25 +70,25 @@ func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, bool) {
// HEADER //

// ReadHeader reads the header
func (s *Storage) ReadHeader(bn uint64) (*types.Header, error) {
func (s *Storage) ReadHeader(bn uint64, bh types.Hash) (*types.Header, error) {
header := &types.Header{}
err := s.readRLP(HEADER, common.EncodeUint64ToBytes(bn), header)
err := s.readRLP(HEADER, getKey(bn, bh), header)

return header, err
}

// BODY //

// ReadBody reads the body
func (s *Storage) ReadBody(bn uint64) (*types.Body, error) {
func (s *Storage) ReadBody(bn uint64, bh types.Hash) (*types.Body, error) {
body := &types.Body{}
if err := s.readRLP(BODY, common.EncodeUint64ToBytes(bn), body); err != nil {
if err := s.readRLP(BODY, getKey(bn, bh), body); err != nil {
return nil, err
}

// must read header because block number is needed in order to calculate each tx hash
header := &types.Header{}
if err := s.readRLP(HEADER, common.EncodeUint64ToBytes(bn), header); err != nil {
if err := s.readRLP(HEADER, getKey(bn, bh), header); err != nil {
return nil, err
}

Expand All @@ -102,9 +102,9 @@ func (s *Storage) ReadBody(bn uint64) (*types.Body, error) {
// RECEIPTS //

// ReadReceipts reads the receipts
func (s *Storage) ReadReceipts(bn uint64) ([]*types.Receipt, error) {
func (s *Storage) ReadReceipts(bn uint64, bh types.Hash) ([]*types.Receipt, error) {
receipts := &types.Receipts{}
err := s.readRLP(RECEIPTS, common.EncodeUint64ToBytes(bn), receipts)
err := s.readRLP(RECEIPTS, getKey(bn, bh), receipts)

return *receipts, err
}
Expand Down
Loading

0 comments on commit 63f046b

Please sign in to comment.