Skip to content

Commit 219b78d

Browse files
authored
Merge pull request #2110 from onetechnical/onetechnical/relstable2.5.6
go-algorand 2.5.6-stable
2 parents 304815d + fcfaf87 commit 219b78d

15 files changed

+1225
-93
lines changed

buildnumber.dat

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5
1+
6

config/consensus.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ type ConsensusParams struct {
348348

349349
// update the initial rewards rate calculation to take the reward pool minimum balance into account
350350
InitialRewardsRateCalculation bool
351+
352+
// NoEmptyLocalDeltas updates how ApplyDelta.EvalDelta.LocalDeltas are stored
353+
NoEmptyLocalDeltas bool
351354
}
352355

353356
// PaysetCommitType enumerates possible ways for the block header to commit to
@@ -872,9 +875,24 @@ func initConsensusProtocols() {
872875
v25.ApprovedUpgrades[protocol.ConsensusV26] = 140000
873876
v24.ApprovedUpgrades[protocol.ConsensusV26] = 140000
874877

878+
// v27 updates ApplyDelta.EvalDelta.LocalDeltas format
879+
v27 := v26
880+
v27.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{}
881+
882+
// Enable the ApplyDelta.EvalDelta.LocalDeltas fix
883+
v27.NoEmptyLocalDeltas = true
884+
885+
Consensus[protocol.ConsensusV27] = v27
886+
887+
// v26 can be upgraded to v27, with an update delay of 3 days
888+
// 60279 = (3 * 24 * 60 * 60 / 4.3)
889+
// for the sake of future manual calculations, we'll round that down
890+
// a bit :
891+
v26.ApprovedUpgrades[protocol.ConsensusV27] = 60000
892+
875893
// ConsensusFuture is used to test features that are implemented
876894
// but not yet released in a production protocol version.
877-
vFuture := v26
895+
vFuture := v27
878896
vFuture.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{}
879897

880898
// FilterTimeout for period 0 should take a new optimized, configured value, need to revisit this later
@@ -895,7 +913,7 @@ func initConsensusProtocols() {
895913
Consensus[protocol.ConsensusFuture] = vFuture
896914
}
897915

898-
// Global defines global Algorand protocol parameters which should not be overriden.
916+
// Global defines global Algorand protocol parameters which should not be overridden.
899917
type Global struct {
900918
SmallLambda time.Duration // min amount of time to wait for leader's credential (i.e., time to propagate one credential)
901919
BigLambda time.Duration // max amount of time to wait for leader's proposal (i.e., time to propagate one block)

crypto/merklearray/worker.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ import (
2525
// workerState describes a group of goroutines processing a sequential list
2626
// of maxidx elements starting from 0.
2727
type workerState struct {
28+
// maxidx is the total number of elements to process, and nextidx
29+
// is the next element that a worker should process.
30+
maxidx uint64
31+
nextidx uint64
32+
2833
// nworkers is the number of workers that can be started.
2934
// This field gets decremented once workers are launched,
3035
// and represents the number of remaining workers that can
@@ -43,11 +48,6 @@ type workerState struct {
4348
// wg tracks outstanding workers, to determine when all workers
4449
// have finished their processing.
4550
wg sync.WaitGroup
46-
47-
// maxidx is the total number of elements to process, and nextidx
48-
// is the next element that a worker should process.
49-
maxidx uint64
50-
nextidx uint64
5151
}
5252

5353
func newWorkerState(max uint64) *workerState {

data/transactions/logic/eval.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ type LedgerForLogic interface {
134134
CreatorAddress() basics.Address
135135
OptedIn(addr basics.Address, appIdx basics.AppIndex) (bool, error)
136136

137-
GetLocal(addr basics.Address, appIdx basics.AppIndex, key string) (value basics.TealValue, exists bool, err error)
138-
SetLocal(addr basics.Address, key string, value basics.TealValue) error
139-
DelLocal(addr basics.Address, key string) error
137+
GetLocal(addr basics.Address, appIdx basics.AppIndex, key string, accountIdx uint64) (value basics.TealValue, exists bool, err error)
138+
SetLocal(addr basics.Address, key string, value basics.TealValue, accountIdx uint64) error
139+
DelLocal(addr basics.Address, key string, accountIdx uint64) error
140140

141141
GetGlobal(appIdx basics.AppIndex, key string) (value basics.TealValue, exists bool, err error)
142142
SetGlobal(key string, value basics.TealValue) error
@@ -2059,7 +2059,7 @@ func (cx *evalContext) appReadLocalKey(appIdx uint64, accountIdx uint64, key str
20592059
if err != nil {
20602060
return basics.TealValue{}, false, err
20612061
}
2062-
return cx.Ledger.GetLocal(addr, basics.AppIndex(appIdx), key)
2062+
return cx.Ledger.GetLocal(addr, basics.AppIndex(appIdx), key, accountIdx)
20632063
}
20642064

20652065
// appWriteLocalKey writes value to local key/value cow
@@ -2069,7 +2069,7 @@ func (cx *evalContext) appWriteLocalKey(accountIdx uint64, key string, tv basics
20692069
if err != nil {
20702070
return err
20712071
}
2072-
return cx.Ledger.SetLocal(addr, key, tv)
2072+
return cx.Ledger.SetLocal(addr, key, tv, accountIdx)
20732073
}
20742074

20752075
// appDeleteLocalKey deletes a value from the key/value cow
@@ -2079,7 +2079,7 @@ func (cx *evalContext) appDeleteLocalKey(accountIdx uint64, key string) error {
20792079
if err != nil {
20802080
return err
20812081
}
2082-
return cx.Ledger.DelLocal(addr, key)
2082+
return cx.Ledger.DelLocal(addr, key, accountIdx)
20832083
}
20842084

20852085
func (cx *evalContext) appReadGlobalKey(foreignAppsIndex uint64, key string) (basics.TealValue, bool, error) {

data/transactions/logic/evalStateful_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ func (l *testLedger) DelGlobal(key string) error {
258258
return nil
259259
}
260260

261-
func (l *testLedger) GetLocal(addr basics.Address, appIdx basics.AppIndex, key string) (basics.TealValue, bool, error) {
261+
func (l *testLedger) GetLocal(addr basics.Address, appIdx basics.AppIndex, key string, accountIdx uint64) (basics.TealValue, bool, error) {
262262
if appIdx == 0 {
263263
appIdx = l.appID
264264
}
@@ -285,7 +285,7 @@ func (l *testLedger) GetLocal(addr basics.Address, appIdx basics.AppIndex, key s
285285
return val, ok, nil
286286
}
287287

288-
func (l *testLedger) SetLocal(addr basics.Address, key string, value basics.TealValue) error {
288+
func (l *testLedger) SetLocal(addr basics.Address, key string, value basics.TealValue, accountIdx uint64) error {
289289
appIdx := l.appID
290290

291291
br, ok := l.balances[addr]
@@ -313,7 +313,7 @@ func (l *testLedger) SetLocal(addr basics.Address, key string, value basics.Teal
313313
return nil
314314
}
315315

316-
func (l *testLedger) DelLocal(addr basics.Address, key string) error {
316+
func (l *testLedger) DelLocal(addr basics.Address, key string, accountIdx uint64) error {
317317
appIdx := l.appID
318318

319319
br, ok := l.balances[addr]

ledger/accountdb.go

+45-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ var accountsResetExprs = []string{
114114
// accountDBVersion is the database version that this binary would know how to support and how to upgrade to.
115115
// details about the content of each of the versions can be found in the upgrade functions upgradeDatabaseSchemaXXXX
116116
// and their descriptions.
117-
var accountDBVersion = int32(4)
117+
var accountDBVersion = int32(5)
118118

119119
// persistedAccountData is used for representing a single account stored on the disk. In addition to the
120120
// basics.AccountData, it also stores complete referencing information used to maintain the base accounts
@@ -631,6 +631,50 @@ func accountsAddNormalizedBalance(tx *sql.Tx, proto config.ConsensusParams) erro
631631
return rows.Err()
632632
}
633633

634+
// removeEmptyAccountData removes empty AccountData msgp-encoded entries from accountbase table
635+
// and optionally returns list of addresses that were eliminated
636+
func removeEmptyAccountData(tx *sql.Tx, queryAddresses bool) (num int64, addresses []basics.Address, err error) {
637+
if queryAddresses {
638+
rows, err := tx.Query("SELECT address FROM accountbase where length(data) = 1 and data = x'80'") // empty AccountData is 0x80
639+
if err != nil {
640+
return 0, nil, err
641+
}
642+
defer rows.Close()
643+
644+
for rows.Next() {
645+
var addrbuf []byte
646+
err = rows.Scan(&addrbuf)
647+
if err != nil {
648+
return 0, nil, err
649+
}
650+
var addr basics.Address
651+
if len(addrbuf) != len(addr) {
652+
err = fmt.Errorf("Account DB address length mismatch: %d != %d", len(addrbuf), len(addr))
653+
return 0, nil, err
654+
}
655+
copy(addr[:], addrbuf)
656+
addresses = append(addresses, addr)
657+
}
658+
659+
// if the above loop was abrupted by an error, test it now.
660+
if err = rows.Err(); err != nil {
661+
return 0, nil, err
662+
}
663+
}
664+
665+
result, err := tx.Exec("DELETE from accountbase where length(data) = 1 and data = x'80'")
666+
if err != nil {
667+
return 0, nil, err
668+
}
669+
num, err = result.RowsAffected()
670+
if err != nil {
671+
// something wrong on getting rows count but data deleted, ignore the error
672+
num = int64(len(addresses))
673+
err = nil
674+
}
675+
return num, addresses, err
676+
}
677+
634678
// accountDataToOnline returns the part of the AccountData that matters
635679
// for online accounts (to answer top-N queries). We store a subset of
636680
// the full AccountData because we need to store a large number of these

ledger/acctupdates.go

+63
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,12 @@ func (au *accountUpdates) accountsInitialize(ctx context.Context, tx *sql.Tx) (b
10691069
au.log.Warnf("accountsInitialize failed to upgrade accounts database (ledger.tracker.sqlite) from schema 3 : %v", err)
10701070
return 0, err
10711071
}
1072+
case 4:
1073+
dbVersion, err = au.upgradeDatabaseSchema4(ctx, tx)
1074+
if err != nil {
1075+
au.log.Warnf("accountsInitialize failed to upgrade accounts database (ledger.tracker.sqlite) from schema 4 : %v", err)
1076+
return 0, err
1077+
}
10721078
default:
10731079
return 0, fmt.Errorf("accountsInitialize unable to upgrade database from schema version %d", dbVersion)
10741080
}
@@ -1324,6 +1330,63 @@ func (au *accountUpdates) upgradeDatabaseSchema3(ctx context.Context, tx *sql.Tx
13241330
return 4, nil
13251331
}
13261332

1333+
// upgradeDatabaseSchema4 does not change the schema but migrates data:
1334+
// remove empty AccountData entries from accountbase table
1335+
func (au *accountUpdates) upgradeDatabaseSchema4(ctx context.Context, tx *sql.Tx) (updatedDBVersion int32, err error) {
1336+
1337+
queryAddresses := au.catchpointInterval != 0
1338+
numDeleted, addresses, err := removeEmptyAccountData(tx, queryAddresses)
1339+
if err != nil {
1340+
return 0, err
1341+
}
1342+
1343+
if queryAddresses && len(addresses) > 0 {
1344+
mc, err := makeMerkleCommitter(tx, false)
1345+
if err != nil {
1346+
// at this point record deleted and DB is pruned for account data
1347+
// if hash deletion fails just log it and do not about startup
1348+
au.log.Errorf("upgradeDatabaseSchema4: failed to create merkle committer: %v", err)
1349+
goto done
1350+
}
1351+
trie, err := merkletrie.MakeTrie(mc, trieMemoryConfig)
1352+
if err != nil {
1353+
au.log.Errorf("upgradeDatabaseSchema4: failed to create merkle trie: %v", err)
1354+
goto done
1355+
}
1356+
1357+
var totalHashesDeleted int
1358+
for _, addr := range addresses {
1359+
hash := accountHashBuilder(addr, basics.AccountData{}, []byte{0x80})
1360+
deleted, err := trie.Delete(hash)
1361+
if err != nil {
1362+
au.log.Errorf("upgradeDatabaseSchema4: failed to delete hash '%s' from merkle trie for account %v: %v", hex.EncodeToString(hash), addr, err)
1363+
} else {
1364+
if !deleted {
1365+
au.log.Warnf("upgradeDatabaseSchema4: failed to delete hash '%s' from merkle trie for account %v", hex.EncodeToString(hash), addr)
1366+
} else {
1367+
totalHashesDeleted++
1368+
}
1369+
}
1370+
}
1371+
1372+
if _, err = trie.Commit(); err != nil {
1373+
au.log.Errorf("upgradeDatabaseSchema4: failed to commit changes to merkle trie: %v", err)
1374+
}
1375+
1376+
au.log.Infof("upgradeDatabaseSchema4: deleted %d hashes", totalHashesDeleted)
1377+
}
1378+
1379+
done:
1380+
au.log.Infof("upgradeDatabaseSchema4: deleted %d rows", numDeleted)
1381+
1382+
// update version
1383+
_, err = db.SetUserVersion(ctx, tx, 5)
1384+
if err != nil {
1385+
return 0, fmt.Errorf("accountsInitialize unable to update database schema version from 4 to 5: %v", err)
1386+
}
1387+
return 5, nil
1388+
}
1389+
13271390
// deleteStoredCatchpoints iterates over the storedcatchpoints table and deletes all the files stored on disk.
13281391
// once all the files have been deleted, it would go ahead and remove the entries from the table.
13291392
func (au *accountUpdates) deleteStoredCatchpoints(ctx context.Context, dbQueries *accountsDbQueries) (err error) {

0 commit comments

Comments
 (0)