@@ -3598,3 +3598,89 @@ func TestOnlineAccountsExceedOfflineRows(t *testing.T) {
35983598 require .True (t , history [1 ].AccountData .IsVotingEmpty ())
35993599 require .Equal (t , basics .Round (5 ), history [1 ].UpdRound )
36003600}
3601+
3602+ // TestOnlineAccountsSuspended checks that transfer to suspended account does not produce extra rows
3603+ // in online accounts table. The test is similar to TestOnlineAccountsExceedOfflineRows.
3604+ func TestOnlineAccountsSuspended (t * testing.T ) {
3605+ partitiontest .PartitionTest (t )
3606+ t .Parallel ()
3607+
3608+ dbs , _ := storetesting .DbOpenTest (t , true )
3609+ storetesting .SetDbLogging (t , dbs )
3610+ defer dbs .Close ()
3611+
3612+ tx , err := dbs .Wdb .Handle .Begin ()
3613+ require .NoError (t , err )
3614+ defer tx .Rollback ()
3615+
3616+ proto := config .Consensus [protocol .ConsensusCurrentVersion ]
3617+
3618+ var accts map [basics.Address ]basics.AccountData
3619+ sqlitedriver .AccountsInitTest (t , tx , accts , protocol .ConsensusCurrentVersion )
3620+
3621+ addrA := ledgertesting .RandomAddress ()
3622+
3623+ deltaA := onlineAccountDelta {
3624+ address : addrA ,
3625+ newAcct : []trackerdb.BaseOnlineAccountData {
3626+ {
3627+ MicroAlgos : basics.MicroAlgos {Raw : 100_000_000 },
3628+ IncentiveEligible : true , // does not matter for commit logic but makes the test intent clearer
3629+ BaseVotingData : trackerdb.BaseVotingData {VoteFirstValid : 1 , VoteLastValid : 5 },
3630+ },
3631+ // suspend, offline but non-empty voting data
3632+ {
3633+ MicroAlgos : basics.MicroAlgos {Raw : 100_000_000 },
3634+ IncentiveEligible : false ,
3635+ BaseVotingData : trackerdb.BaseVotingData {VoteFirstValid : 1 , VoteLastValid : 5 },
3636+ },
3637+ },
3638+ updRound : []uint64 {1 , 2 },
3639+ newStatus : []basics.Status {basics .Online , basics .Offline },
3640+ }
3641+ updates := compactOnlineAccountDeltas {}
3642+ updates .deltas = append (updates .deltas , deltaA )
3643+ writer , err := sqlitedriver .MakeOnlineAccountsSQLWriter (tx , updates .len () > 0 )
3644+ require .NoError (t , err )
3645+ defer writer .Close ()
3646+
3647+ lastUpdateRound := basics .Round (2 )
3648+ updated , err := onlineAccountsNewRoundImpl (writer , updates , proto , lastUpdateRound )
3649+ require .NoError (t , err )
3650+ require .Len (t , updated , 2 )
3651+
3652+ var baseOnlineAccounts lruOnlineAccounts
3653+ baseOnlineAccounts .init (logging .TestingLog (t ), 1000 , 800 )
3654+ for _ , persistedAcct := range updated {
3655+ baseOnlineAccounts .write (persistedAcct )
3656+ }
3657+
3658+ // make sure baseOnlineAccounts has the entry
3659+ entry , has := baseOnlineAccounts .read (addrA )
3660+ require .True (t , has )
3661+ require .True (t , entry .AccountData .IsVotingEmpty ())
3662+ require .Equal (t , basics .Round (2 ), entry .UpdRound )
3663+
3664+ acctDelta := ledgercore.AccountDeltas {}
3665+
3666+ // simulate transfer to suspended account
3667+ ad := ledgercore.AccountData {
3668+ AccountBaseData : ledgercore.AccountBaseData {
3669+ Status : basics .Offline ,
3670+ MicroAlgos : basics.MicroAlgos {Raw : 100_000_000 - 1 },
3671+ },
3672+ VotingData : basics.VotingData {
3673+ VoteFirstValid : 1 ,
3674+ VoteLastValid : 5 ,
3675+ },
3676+ }
3677+ acctDelta .Upsert (addrA , ad )
3678+ deltas := []ledgercore.AccountDeltas {acctDelta }
3679+ updates = makeCompactOnlineAccountDeltas (deltas , 3 , baseOnlineAccounts )
3680+
3681+ // insert and make sure no new rows are inserted
3682+ lastUpdateRound = basics .Round (3 )
3683+ updated , err = onlineAccountsNewRoundImpl (writer , updates , proto , lastUpdateRound )
3684+ require .NoError (t , err )
3685+ require .Len (t , updated , 0 )
3686+ }
0 commit comments