erigon22: MakeCanonical must update txNums (#5211)

This commit is contained in:
Alex Sharov 2022-08-29 11:44:31 +07:00 committed by GitHub
parent 5e441bfa2a
commit 01f2965d8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 17 deletions

View File

@ -29,12 +29,17 @@ func (s *TxNums) Append(blockNum, maxTxnNum uint64) {
err := fmt.Errorf("trying append blockNum=%d, but already have=%d", blockNum, len(s.nums))
panic(err)
}
if len(s.nums) < int(blockNum) {
err := fmt.Errorf("append with gap blockNum=%d, but current heigh=%d", blockNum, len(s.nums))
panic(err)
}
s.nums = append(s.nums, maxTxnNum)
//fmt.Printf("append: %d, %d, %d\n", blockNum, maxTxnNum, len(s.nums))
//fmt.Printf("after append: %d, %d, %d\n", s.nums, blockNum, maxTxnNum)
}
func (s *TxNums) Unwind(unwindTo uint64) {
//fmt.Printf("before unwind: %d, %d\n", unwindTo, s.nums)
s.nums = s.nums[:unwindTo]
//fmt.Printf("unwind: %d, %d\n", unwindTo, s.nums)
//fmt.Printf("after unwind: %d, %d\n", unwindTo, s.nums)
}
func (s *TxNums) Find(endTxNumMinimax uint64) (ok bool, blockNum uint64) {
blockNum = uint64(sort.Search(len(s.nums), func(i int) bool {

View File

@ -712,7 +712,7 @@ func deleteBody(db kv.Deleter, hash common.Hash, number uint64) {
}
// MakeBodiesCanonical - move all txs of non-canonical blocks from NonCanonicalTxs table to EthTx table
func MakeBodiesCanonical(tx kv.RwTx, from uint64, ctx context.Context, logPrefix string, logEvery *time.Ticker) error {
func MakeBodiesCanonical(tx kv.RwTx, from uint64, ctx context.Context, logPrefix string, logEvery *time.Ticker, cb func(blockNum, lastTxnNum uint64)) error {
for blockNum := from; ; blockNum++ {
h, err := ReadCanonicalHash(tx, blockNum)
if err != nil {
@ -755,6 +755,10 @@ func MakeBodiesCanonical(tx kv.RwTx, from uint64, ctx context.Context, logPrefix
if err := WriteBodyForStorage(tx, h, blockNum, bodyForStorage); err != nil {
return err
}
if cb != nil {
lastTxnNum := bodyForStorage.BaseTxId + uint64(bodyForStorage.TxAmount)
cb(blockNum, lastTxnNum)
}
select {
case <-ctx.Done():

View File

@ -118,7 +118,11 @@ func BodiesForward(
// Property of blockchain: same block in different forks will have different hashes.
// Means - can mark all canonical blocks as non-canonical on unwind, and
// do opposite here - without storing any meta-info.
if err := rawdb.MakeBodiesCanonical(tx, s.BlockNumber+1, ctx, logPrefix, logEvery); err != nil {
if err := rawdb.MakeBodiesCanonical(tx, s.BlockNumber+1, ctx, logPrefix, logEvery, func(blockNum, lastTxnNum uint64) {
if cfg.historyV2 {
cfg.txNums.Append(blockNum, lastTxnNum)
}
}); err != nil {
return fmt.Errorf("make block canonical: %w", err)
}
@ -303,7 +307,7 @@ func UnwindBodiesStage(u *UnwindState, tx kv.RwTx, cfg BodiesCfg, ctx context.Co
return err
}
if cfg.historyV2 {
cfg.txNums.Unwind(u.UnwindPoint)
cfg.txNums.Unwind(u.UnwindPoint + 1)
}
if err = u.Done(tx); err != nil {

View File

@ -43,7 +43,7 @@ func TestBodiesUnwind(t *testing.T) {
require.Equal(5*(3+2), int(n)) // from 0, 5 block with 3 txn in each
}
{
err = rawdb.MakeBodiesCanonical(tx, 5+1, ctx, "test", logEvery) // block 5 already canonical, start from next one
err = rawdb.MakeBodiesCanonical(tx, 5+1, ctx, "test", logEvery, nil) // block 5 already canonical, start from next one
require.NoError(err)
n, err := tx.ReadSequence(kv.EthTx)
require.NoError(err)
@ -68,7 +68,7 @@ func TestBodiesUnwind(t *testing.T) {
require.NoError(err)
require.Equal(5*(3+2), int(n)) // from 0, 5 block with 3 txn in each
err = rawdb.MakeBodiesCanonical(tx, 5+1, ctx, "test", logEvery) // block 5 already canonical, start from next one
err = rawdb.MakeBodiesCanonical(tx, 5+1, ctx, "test", logEvery, nil) // block 5 already canonical, start from next one
require.NoError(err)
n, err = tx.ReadSequence(kv.EthTx)
require.NoError(err)

View File

@ -742,16 +742,12 @@ func (p *Promoter) UnwindOnHistoryV2(logPrefix string, agg *state.Aggregator22,
if err := accounts.Deserialise2(&acc, v); err != nil {
return err
}
if !(acc.Incarnation > 0 && acc.IsEmptyCodeHash()) {
value := make([]byte, acc.EncodingLengthForStorage())
acc.EncodeForStorage(value)
return collector.Collect(newK, value)
}
if codeHash, err := p.tx.GetOne(kv.ContractCode, dbutils.GenerateStoragePrefix(newK, acc.Incarnation)); err == nil {
copy(acc.CodeHash[:], codeHash)
} else {
return fmt.Errorf("adjusting codeHash for ks %x, inc %d: %w", newK, acc.Incarnation, err)
if acc.Incarnation > 0 && acc.IsEmptyCodeHash() {
if codeHash, err := p.tx.GetOne(kv.ContractCode, dbutils.GenerateStoragePrefix(newK, acc.Incarnation)); err == nil {
copy(acc.CodeHash[:], codeHash)
} else {
return fmt.Errorf("adjusting codeHash for ks %x, inc %d: %w", newK, acc.Incarnation, err)
}
}
value := make([]byte, acc.EncodingLengthForStorage())