Skip to content

Commit

Permalink
ledger: fix accounts cache ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
algorandskiy committed Sep 29, 2022
1 parent 5be155b commit 40503eb
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 1 deletion.
2 changes: 1 addition & 1 deletion ledger/accountdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -4761,7 +4761,7 @@ func (prd *persistedResourcesData) before(other *persistedResourcesData) bool {
// before compares the round numbers of two persistedAccountData and determines if the current persistedAccountData
// happened before the other.
func (pac *persistedOnlineAccountData) before(other *persistedOnlineAccountData) bool {
return pac.round < other.round
return pac.updRound < other.updRound
}

// txTailRoundLease is used as part of txTailRound for storing
Expand Down
107 changes: 107 additions & 0 deletions ledger/acctonline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,113 @@ func TestAcctOnlineCacheDBSync(t *testing.T) {
})
}

// TestAcctOnlineBaseAccountCache checks the data correctness for a case when
// some accounts gets online and then offline in the same commit range,
// and then online again in the next range with the same voting data
func TestAcctOnlineBaseAccountCache(t *testing.T) {
partitiontest.PartitionTest(t)

const seedLookback = 2
const seedInteval = 3
const maxBalLookback = 2 * seedLookback * seedInteval

const numAccts = 5 // does not matter, some number of accounts
allAccts := make([]basics.BalanceRecord, numAccts)
genesisAccts := []map[basics.Address]basics.AccountData{{}}
genesisAccts[0] = make(map[basics.Address]basics.AccountData, numAccts)
var addrA basics.Address
for i := 0; i < numAccts; i++ {
allAccts[i] = basics.BalanceRecord{
Addr: ledgertesting.RandomAddress(),
AccountData: ledgertesting.RandomOnlineAccountData(0),
}
if i == 0 {
addrA = allAccts[i].Addr
allAccts[i].AccountData.Status = basics.Offline
allAccts[i].AccountData.VoteLastValid = 0
}
genesisAccts[0][allAccts[i].Addr] = allAccts[i].AccountData
}

addSinkAndPoolAccounts(genesisAccts)

testProtocolVersion := protocol.ConsensusVersion("test-protocol-TestAcctOnlineBaseAccountCache")
protoParams := config.Consensus[protocol.ConsensusCurrentVersion]
protoParams.MaxBalLookback = maxBalLookback
protoParams.SeedLookback = seedLookback
protoParams.SeedRefreshInterval = seedInteval
config.Consensus[testProtocolVersion] = protoParams
defer func() {
delete(config.Consensus, testProtocolVersion)
}()

ml := makeMockLedgerForTracker(t, true, 1, testProtocolVersion, genesisAccts)
defer ml.Close()
conf := config.GetDefaultLocal()
conf.MaxAcctLookback = maxBalLookback

au, oa := newAcctUpdates(t, ml, conf)
defer oa.close()
_, totals, err := au.LatestTotals()
require.NoError(t, err)

accounts := genesisAccts

acctDatas := [3]ledgercore.AccountData{
{AccountBaseData: ledgercore.AccountBaseData{Status: basics.Online}, VotingData: ledgercore.VotingData{VoteLastValid: basics.Round(1000 + maxBalLookback)}},
{AccountBaseData: ledgercore.AccountBaseData{Status: basics.Offline}, VotingData: ledgercore.VotingData{}},
{AccountBaseData: ledgercore.AccountBaseData{Status: basics.Online}, VotingData: ledgercore.VotingData{VoteLastValid: basics.Round(1000 + maxBalLookback)}},
}
// set online, offline, online
for i := 1; i <= 3; i++ {
var updates ledgercore.AccountDeltas
updates.Upsert(addrA, acctDatas[i-1])
base := accounts[i-1]
newAccts := applyPartialDeltas(base, updates)
accounts = append(accounts, newAccts)
totals = newBlock(t, ml, testProtocolVersion, protoParams, basics.Round(i), base, updates, totals)
}

// add maxBalLookback + 2 empty blocks and next commit would commit the first two rounds
for i := 4; i <= maxBalLookback+2; i++ {
var updates ledgercore.AccountDeltas
base := accounts[i-1]
totals = newBlock(t, ml, testProtocolVersion, protoParams, basics.Round(i), base, updates, totals)
accounts = append(accounts, base)
}

rnd := maxBalLookback + 2
commitSync(t, oa, ml, basics.Round(rnd))
poad, has := oa.baseOnlineAccounts.read(addrA)
require.True(t, has)
require.Empty(t, poad.accountData)

data, err := oa.lookupOnlineAccountData(2, addrA)
require.NoError(t, err)
require.Empty(t, data.VotingData.VoteLastValid)

// add one more and next commit would commit the third rounds
{
i := rnd + 1
var updates ledgercore.AccountDeltas
base := accounts[i-1]
totals = newBlock(t, ml, testProtocolVersion, protoParams, basics.Round(i), base, updates, totals)
commitSync(t, oa, ml, basics.Round(i))
}

poad, has = oa.baseOnlineAccounts.read(addrA)
require.True(t, has)
require.NotEmpty(t, poad.accountData)

data, err = oa.lookupOnlineAccountData(basics.Round(3), addrA)
require.NoError(t, err)
require.NotEmpty(t, data.VotingData.VoteLastValid)

data, err = oa.lookupOnlineAccountData(basics.Round(rnd+1), addrA)
require.NoError(t, err)
require.NotEmpty(t, data.VotingData.VoteLastValid)
}

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

Expand Down

0 comments on commit 40503eb

Please sign in to comment.