Skip to content

Commit

Permalink
ledger: remove redundant block header cache (#5540)
Browse files Browse the repository at this point in the history
  • Loading branch information
algonautshant authored Aug 2, 2023
1 parent d82200a commit 8c87fa5
Show file tree
Hide file tree
Showing 25 changed files with 100 additions and 586 deletions.
4 changes: 0 additions & 4 deletions cmd/tealdbg/localLedger.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,6 @@ func (l *localLedger) BlockHdr(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, nil
}

func (l *localLedger) BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, nil
}

func (l *localLedger) GetStateProofVerificationContext(_ basics.Round) (*ledgercore.StateProofVerificationContext, error) {
return nil, fmt.Errorf("localLedger: GetStateProofVerificationContext, needed for state proof verification, is not implemented in debugger")
}
Expand Down
4 changes: 0 additions & 4 deletions daemon/algod/api/server/v2/dryrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,6 @@ func (dl *dryrunLedger) BlockHdr(basics.Round) (bookkeeping.BlockHeader, error)
return bookkeeping.BlockHeader{}, nil
}

func (dl *dryrunLedger) BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, nil
}

func (dl *dryrunLedger) CheckDup(config.ConsensusParams, basics.Round, basics.Round, basics.Round, transactions.Txid, ledgercore.Txlease) error {
return nil
}
Expand Down
27 changes: 18 additions & 9 deletions data/ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,11 @@ func TestConsensusVersion(t *testing.T) {
require.NotNil(t, &l)

blk := genesisInitState.Block
flushOffset := uint64(129) // pendingDeltasFlushThreshold = 128 will flush every 128 rounds (RewardsPool acct)
// txTailRetainSize = MaxTxnLife + DeeperBlockHeaderHistory = 1000 + 1

// add 5 blocks.
for rnd := basics.Round(1); rnd < basics.Round(consensusParams.MaxTxnLife+5); rnd++ {
// add some blocks.
for rnd := basics.Round(1); rnd < basics.Round(consensusParams.MaxTxnLife+flushOffset); rnd++ {
blk.BlockHeader.Round++
blk.BlockHeader.Seed[0] = byte(uint64(rnd))
blk.BlockHeader.Seed[1] = byte(uint64(rnd) / 256)
Expand All @@ -378,31 +380,38 @@ func TestConsensusVersion(t *testing.T) {
require.NoError(t, l.AddBlock(blk, agreement.Certificate{}))
l.WaitForCommit(rnd)
}
// ensure that all the first 5 has the expected version.
for rnd := basics.Round(consensusParams.MaxTxnLife); rnd < basics.Round(consensusParams.MaxTxnLife+5); rnd++ {
// ensure that all the first flushOffset have the expected version.
for rnd := basics.Round(consensusParams.MaxTxnLife); rnd < basics.Round(consensusParams.MaxTxnLife+flushOffset); rnd++ {
ver, err := l.ConsensusVersion(rnd)
require.NoError(t, err)
require.Equal(t, previousProtocol, ver)
}
// the next UpgradeVoteRounds can also be known to have the previous version.
for rnd := basics.Round(consensusParams.MaxTxnLife + 5); rnd < basics.Round(consensusParams.MaxTxnLife+5+consensusParams.UpgradeVoteRounds); rnd++ {
for rnd := basics.Round(consensusParams.MaxTxnLife + flushOffset); rnd < basics.Round(consensusParams.MaxTxnLife+
flushOffset+consensusParams.UpgradeVoteRounds); rnd++ {
ver, err := l.ConsensusVersion(rnd)
require.NoError(t, err)
require.Equal(t, previousProtocol, ver)
}

// but two rounds ahead is not known.
ver, err := l.ConsensusVersion(basics.Round(consensusParams.MaxTxnLife + 6 + consensusParams.UpgradeVoteRounds))
ver, err := l.ConsensusVersion(basics.Round(consensusParams.MaxTxnLife + flushOffset + 1 + consensusParams.UpgradeVoteRounds))
require.Equal(t, protocol.ConsensusVersion(""), ver)
require.Equal(t, ledgercore.ErrNoEntry{Round: basics.Round(consensusParams.MaxTxnLife + 6 + consensusParams.UpgradeVoteRounds), Latest: basics.Round(consensusParams.MaxTxnLife + 4), Committed: basics.Round(consensusParams.MaxTxnLife + 4)}, err)
require.Equal(t, ledgercore.ErrNoEntry{
Round: basics.Round(consensusParams.MaxTxnLife + flushOffset + 1 + consensusParams.UpgradeVoteRounds),
Latest: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1),
Committed: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1)}, err)

// check round #1 which was already dropped.
ver, err = l.ConsensusVersion(basics.Round(1))
require.Equal(t, protocol.ConsensusVersion(""), ver)
require.Equal(t, ledgercore.ErrNoEntry{Round: basics.Round(1), Latest: basics.Round(consensusParams.MaxTxnLife + 4), Committed: basics.Round(consensusParams.MaxTxnLife + 4)}, err)
require.Equal(t, ledgercore.ErrNoEntry{
Round: basics.Round(1),
Latest: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1),
Committed: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1)}, err)

// add another round, with upgrade
rnd := basics.Round(consensusParams.MaxTxnLife + 5)
rnd := basics.Round(consensusParams.MaxTxnLife + flushOffset)
blk.BlockHeader.Round++
blk.BlockHeader.Seed[0] = byte(uint64(rnd))
blk.BlockHeader.Seed[1] = byte(uint64(rnd) / 256)
Expand Down
11 changes: 5 additions & 6 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,16 @@ func computeMinAvmVersion(group []transactions.SignedTxnWithAD) uint64 {
// only exposes things that consensus has already agreed upon, so it is
// "stateless" for signature purposes.
type LedgerForSignature interface {
BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error)
BlockHdr(basics.Round) (bookkeeping.BlockHeader, error)
}

// NoHeaderLedger is intended for debugging situations in which it is reasonable
// to preclude the use of `block` and `txn LastValidTime`
type NoHeaderLedger struct {
}

// BlockHdrCached always errors
func (NoHeaderLedger) BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error) {
// BlockHdr always errors
func (NoHeaderLedger) BlockHdr(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, fmt.Errorf("no block header access")
}

Expand All @@ -224,7 +224,6 @@ type LedgerForLogic interface {
Authorizer(addr basics.Address) (basics.Address, error)
Round() basics.Round
PrevTimestamp() int64
BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error)

AssetHolding(addr basics.Address, assetIdx basics.AssetIndex) (basics.AssetHolding, error)
AssetParams(aidx basics.AssetIndex) (basics.AssetParams, basics.Address, error)
Expand Down Expand Up @@ -2949,7 +2948,7 @@ func (cx *EvalContext) txnFieldToStack(stxn *transactions.SignedTxnWithAD, fs *t
if err != nil {
return sv, err
}
hdr, err := cx.SigLedger.BlockHdrCached(rnd)
hdr, err := cx.SigLedger.BlockHdr(rnd)
if err != nil {
return sv, err
}
Expand Down Expand Up @@ -5827,7 +5826,7 @@ func opBlock(cx *EvalContext) error {
return fmt.Errorf("invalid block field %s", f)
}

hdr, err := cx.SigLedger.BlockHdrCached(round)
hdr, err := cx.SigLedger.BlockHdr(round)
if err != nil {
return err
}
Expand Down
14 changes: 12 additions & 2 deletions data/transactions/logic/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,9 @@ func defaultAppParamsWithVersion(version uint64, txns ...transactions.SignedTxn)
ep := NewAppEvalParams(transactions.WrapSignedTxnsWithAD(txns), makeTestProtoV(version), &transactions.SpecialAddresses{})
if ep != nil { // If supplied no apps, ep is nil.
ep.Trace = &strings.Builder{}
ep.Ledger = NewLedger(nil)
ep.SigLedger = ep.Ledger
ledger := NewLedger(nil)
ep.Ledger = ledger
ep.SigLedger = ledger
}
return ep
}
Expand Down Expand Up @@ -6011,3 +6012,12 @@ pop
int 1
`, 8)
}

func TestNoHeaderLedger(t *testing.T) {
partitiontest.PartitionTest(t)

nhl := NoHeaderLedger{}
_, err := nhl.BlockHdr(1)
require.Error(t, err)
require.Equal(t, err, fmt.Errorf("no block header access"))
}
4 changes: 2 additions & 2 deletions data/transactions/logic/ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ func (l *Ledger) PrevTimestamp() int64 {
return int64(rand.Uint32() + 1)
}

// BlockHdrCached returns the block header for the given round, if it is available
func (l *Ledger) BlockHdrCached(round basics.Round) (bookkeeping.BlockHeader, error) {
// BlockHdr returns the block header for the given round, if it is available
func (l *Ledger) BlockHdr(round basics.Round) (bookkeeping.BlockHeader, error) {
hdr := bookkeeping.BlockHeader{}
// Return a fake seed that is different for each round
seed := committee.Seed{}
Expand Down
3 changes: 0 additions & 3 deletions data/transactions/verify/txn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ type DummyLedgerForSignature struct {
badHdr bool
}

func (d *DummyLedgerForSignature) BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error) {
return createDummyBlockHeader(), nil
}
func (d *DummyLedgerForSignature) BlockHdr(rnd basics.Round) (blk bookkeeping.BlockHeader, err error) {
if d.badHdr {
return bookkeeping.BlockHeader{}, fmt.Errorf("test error block hdr")
Expand Down
14 changes: 4 additions & 10 deletions ledger/acctupdates.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ type accountUpdatesLedgerEvaluator struct {
au *accountUpdates
// ao is onlineAccounts for voters access
ao *onlineAccounts
// txtail allows implementation of BlockHdrCached
// txtail allows BlockHdr to serve blockHdr without going to disk
tail *txTail
// prevHeader is the previous header to the current one. The usage of this is only in the context of initializeCaches where we iteratively
// building the ledgercore.StateDelta, which requires a peek on the "previous" header information.
Expand Down Expand Up @@ -758,17 +758,11 @@ func (aul *accountUpdatesLedgerEvaluator) BlockHdr(r basics.Round) (bookkeeping.
if r == aul.prevHeader.Round {
return aul.prevHeader, nil
}
return bookkeeping.BlockHeader{}, ledgercore.ErrNoEntry{}
}

// BlockHdrCached returns the header of the given round. We use the txTail
// tracker directly to avoid the tracker registry lock.
func (aul *accountUpdatesLedgerEvaluator) BlockHdrCached(r basics.Round) (bookkeeping.BlockHeader, error) {
hdr, ok := aul.tail.blockHeader(r)
if !ok {
return bookkeeping.BlockHeader{}, fmt.Errorf("no cached header data for round %d", r)
if ok {
return hdr, nil
}
return hdr, nil
return bookkeeping.BlockHeader{}, ledgercore.ErrNoEntry{}
}

// LatestTotals returns the totals of all accounts for the most recent round, as well as the round number
Expand Down
13 changes: 13 additions & 0 deletions ledger/acctupdates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2711,3 +2711,16 @@ func TestAcctUpdatesLookupStateDelta(t *testing.T) {
require.Contains(t, data.Assets, aidx3)
require.NotContains(t, data.Assets, aidx2)
}

func TestAccountUpdatesLedgerEvaluatorNoBlockHdr(t *testing.T) {
partitiontest.PartitionTest(t)

aul := &accountUpdatesLedgerEvaluator{
prevHeader: bookkeeping.BlockHeader{},
tail: &txTail{},
}
hdr, err := aul.BlockHdr(99)
require.Error(t, err)
require.Equal(t, ledgercore.ErrNoEntry{}, err)
require.Equal(t, bookkeeping.BlockHeader{}, hdr)
}
86 changes: 0 additions & 86 deletions ledger/blockHeaderCache.go

This file was deleted.

Loading

0 comments on commit 8c87fa5

Please sign in to comment.