Skip to content

Commit 71e39cd

Browse files
authored
Merge pull request #3553 from algoidan/create-v31-version
## Summary Create an update path that would enable the following features: 1. Batch Verification (#3031) 2. State Proof Keys (#2990) 3. TEAL 6 (#3397) 4. Expired Participation Keys (#2924) 5. Fix rewards calculation bug (#3403) ## Test Plan Unit tests added.
2 parents 102c6ff + 6326a0c commit 71e39cd

File tree

12 files changed

+103
-79
lines changed

12 files changed

+103
-79
lines changed

config/consensus.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,31 @@ func initConsensusProtocols() {
10571057
// v29 can be upgraded to v30, with an update delay of 7 days ( see calculation above )
10581058
v29.ApprovedUpgrades[protocol.ConsensusV30] = 140000
10591059

1060+
v31 := v30
1061+
v31.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{}
1062+
v31.EnableBatchVerification = true
1063+
v31.RewardsCalculationFix = true
1064+
v31.MaxProposedExpiredOnlineAccounts = 32
1065+
1066+
// Enable TEAL 6 / AVM 1.1
1067+
v31.LogicSigVersion = 6
1068+
v31.EnableInnerTransactionPooling = true
1069+
v31.IsolateClearState = true
1070+
1071+
// stat proof key registration
1072+
v31.EnableStateProofKeyregCheck = true
1073+
1074+
// Maximum validity period for key registration, to prevent generating too many StateProof keys
1075+
v31.MaxKeyregValidPeriod = 256*(1<<16) - 1
1076+
1077+
Consensus[protocol.ConsensusV31] = v31
1078+
1079+
// v30 can be upgraded to v31, with an update delay of 7 days ( see calculation above )
1080+
v30.ApprovedUpgrades[protocol.ConsensusV31] = 140000
1081+
10601082
// ConsensusFuture is used to test features that are implemented
10611083
// but not yet released in a production protocol version.
1062-
vFuture := v30
1084+
vFuture := v31
10631085
vFuture.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{}
10641086

10651087
// FilterTimeout for period 0 should take a new optimized, configured value, need to revisit this later
@@ -1072,23 +1094,6 @@ func initConsensusProtocols() {
10721094
vFuture.CompactCertWeightThreshold = (1 << 32) * 30 / 100
10731095
vFuture.CompactCertSecKQ = 128
10741096

1075-
// Enable TEAL 6 / AVM 1.1
1076-
vFuture.LogicSigVersion = 6
1077-
vFuture.EnableInnerTransactionPooling = true
1078-
vFuture.IsolateClearState = true
1079-
1080-
vFuture.MaxProposedExpiredOnlineAccounts = 32
1081-
1082-
vFuture.EnableBatchVerification = true
1083-
1084-
vFuture.RewardsCalculationFix = true
1085-
1086-
// stat proof key registration
1087-
vFuture.EnableStateProofKeyregCheck = true
1088-
1089-
// Maximum validity period for key registration, to prevent generating too many StateProof keys
1090-
vFuture.MaxKeyregValidPeriod = 256*(1<<16) - 1
1091-
10921097
Consensus[protocol.ConsensusFuture] = vFuture
10931098
}
10941099

data/account/participation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ func FillDBWithParticipationKeys(store db.Accessor, address basics.Address, firs
222222

223223
// TODO: change to ConsensusCurrentVersion when updated
224224
interval := config.Consensus[protocol.ConsensusFuture].CompactCertRounds
225-
maxValidPeriod := config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod
225+
maxValidPeriod := config.Consensus[protocol.ConsensusCurrentVersion].MaxKeyregValidPeriod
226226

227227
if maxValidPeriod != 0 && uint64(lastValid-firstValid) > maxValidPeriod {
228228
return PersistedParticipation{}, fmt.Errorf("the validity period for mss is too large: the limit is %d", maxValidPeriod)

data/account/participation_test.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,8 @@ func TestKeyregValidityOverLimit(t *testing.T) {
462462
partitiontest.PartitionTest(t)
463463
a := require.New(t)
464464

465-
// TODO: change to ConsensusCurrentVersion when updated
466-
maxValidPeriod := config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod
467-
dilution := config.Consensus[protocol.ConsensusFuture].DefaultKeyDilution
465+
maxValidPeriod := config.Consensus[protocol.ConsensusCurrentVersion].MaxKeyregValidPeriod
466+
dilution := config.Consensus[protocol.ConsensusCurrentVersion].DefaultKeyDilution
468467

469468
var address basics.Address
470469
crypto.RandBytes(address[:])
@@ -481,8 +480,7 @@ func TestFillDBWithParticipationKeys(t *testing.T) {
481480
partitiontest.PartitionTest(t)
482481
a := require.New(t)
483482

484-
// TODO: change to ConsensusCurrentVersion when updated
485-
dilution := config.Consensus[protocol.ConsensusFuture].DefaultKeyDilution
483+
dilution := config.Consensus[protocol.ConsensusCurrentVersion].DefaultKeyDilution
486484

487485
var address basics.Address
488486
crypto.RandBytes(address[:])
@@ -499,19 +497,19 @@ func TestKeyregValidityPeriod(t *testing.T) {
499497
partitiontest.PartitionTest(t)
500498
a := require.New(t)
501499

502-
// TODO: change to ConsensusCurrentVersion when updated
503-
// setup patched version
504-
version := config.Consensus[protocol.ConsensusFuture]
505-
oldValue := config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod
500+
// Patch the global consensus variable since FillDBWithParticipationKeys uses is to check the validity period
501+
// this allows us to reduce the runtime of the test while checking the logic of FillDBWithParticipationKeys
502+
version := config.Consensus[protocol.ConsensusCurrentVersion]
503+
oldValue := config.Consensus[protocol.ConsensusCurrentVersion].MaxKeyregValidPeriod
506504
version.MaxKeyregValidPeriod = 256*(1<<4) - 1
507-
config.Consensus[protocol.ConsensusFuture] = version
505+
config.Consensus[protocol.ConsensusCurrentVersion] = version
508506
defer func() {
509507
version.MaxKeyregValidPeriod = oldValue
510-
config.Consensus[protocol.ConsensusFuture] = version
508+
config.Consensus[protocol.ConsensusCurrentVersion] = version
511509
}()
512510

513-
maxValidPeriod := config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod
514-
dilution := config.Consensus[protocol.ConsensusFuture].DefaultKeyDilution
511+
maxValidPeriod := config.Consensus[protocol.ConsensusCurrentVersion].MaxKeyregValidPeriod
512+
dilution := config.Consensus[protocol.ConsensusCurrentVersion].DefaultKeyDilution
515513

516514
var address basics.Address
517515

gen/generate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ func generateGenesisFiles(outDir string, protoVersion protocol.ConsensusVersion,
270270
data.VoteFirstValid = part.FirstValid
271271
data.VoteLastValid = part.LastValid
272272
data.VoteKeyDilution = part.KeyDilution
273-
if config.Consensus[protocol.ConsensusFuture].EnableStateProofKeyregCheck {
273+
if protoParams.EnableStateProofKeyregCheck {
274274
data.StateProofID = *part.StateProofVerifier()
275275
}
276276
}

ledger/accountdb_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ func TestAccountDBRound(t *testing.T) {
290290
}
291291

292292
func TestAccountStorageWithStateProofID(t *testing.T) {
293-
proto := config.Consensus[protocol.ConsensusFuture]
293+
proto := config.Consensus[protocol.ConsensusCurrentVersion]
294294

295295
dbs, _ := dbOpenTest(t, true)
296296
setDbLogging(t, dbs)

ledger/apply/keyreg_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,21 +188,21 @@ func TestStateProofPKKeyReg(t *testing.T) {
188188
secretParticipation := keypair()
189189

190190
tx := createTestTxn(t, src, secretParticipation, vrfSecrets)
191-
mockBal := makeMockBalances(protocol.ConsensusCurrentVersion)
191+
mockBal := makeMockBalances(protocol.ConsensusV30)
192192
err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
193193
require.NoError(t, err)
194194

195195
acct, err := mockBal.Get(tx.Src(), false)
196196
require.NoError(t, err)
197-
require.Equal(t, acct.StateProofID.IsEmpty(), true)
197+
require.True(t, acct.StateProofID.IsEmpty())
198198

199-
mockBal = makeMockBalances(protocol.ConsensusFuture)
199+
mockBal = makeMockBalances(protocol.ConsensusCurrentVersion)
200200
err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
201201
require.NoError(t, err)
202202

203203
acct, err = mockBal.Get(tx.Src(), false)
204204
require.NoError(t, err)
205-
require.Equal(t, acct.StateProofID.IsEmpty(), false)
205+
require.False(t, acct.StateProofID.IsEmpty())
206206
}
207207

208208
func createTestTxn(t *testing.T, src basics.Address, secretParticipation *crypto.SignatureSecrets, vrfSecrets *crypto.VRFSecrets) transactions.Transaction {

protocol/consensus.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ const ConsensusV30 = ConsensusVersion(
164164
"https://github.com/algorandfoundation/specs/tree/bc36005dbd776e6d1eaf0c560619bb183215645c",
165165
)
166166

167+
// ConsensusV31 enables the batch verification for ed25519 signatures, Fix reward calculation issue, introduces the ability
168+
// to force an expired participation offline, enables TEAL 6 ( AVM 1.1 ) and add support for creating
169+
// state proof keys.
170+
const ConsensusV31 = ConsensusVersion(
171+
"https://github.com/algorandfoundation/specs/tree/85e6db1fdbdef00aa232c75199e10dc5fe9498f6",
172+
)
173+
167174
// ConsensusFuture is a protocol that should not appear in any production
168175
// network, but is used to test features before they are released.
169176
const ConsensusFuture = ConsensusVersion(
@@ -176,7 +183,7 @@ const ConsensusFuture = ConsensusVersion(
176183

177184
// ConsensusCurrentVersion is the latest version and should be used
178185
// when a specific version is not provided.
179-
const ConsensusCurrentVersion = ConsensusV30
186+
const ConsensusCurrentVersion = ConsensusV31
180187

181188
// Error is used to indicate that an unsupported protocol has been detected.
182189
type Error ConsensusVersion

test/e2e-go/features/participation/onlineOfflineParticipation_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ func TestAccountGoesOnlineForShortPeriod(t *testing.T) {
284284

285285
// we try to register online with a period in which we don't have stateproof keys
286286
partKeyFirstValid := uint64(1)
287+
// TODO: Change consensus version when compact certs are deployed
287288
partKeyLastValid := config.Consensus[protocol.ConsensusFuture].CompactCertRounds - 1
288289
partkeyResponse, _, err := client.GenParticipationKeys(newAccount, partKeyFirstValid, partKeyLastValid, 1000)
289290
a.NoError(err, "rest client should be able to add participation key to new account")

test/e2e-go/features/participation/participationExpiration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func testExpirationAccounts(t *testing.T, fixture *fixtures.RestClientFixture, f
7676
_, currentRound := fixture.GetBalanceAndRound(richAccount)
7777
// account adds part key
7878
partKeyFirstValid := uint64(0)
79-
partKeyValidityPeriod := uint64(150)
79+
partKeyValidityPeriod := uint64(150) // TODO: maybe increase?
8080
partKeyLastValid = currentRound + partKeyValidityPeriod
8181
partkeyResponse, _, err := sClient.GenParticipationKeys(sAccount, partKeyFirstValid, partKeyLastValid, 0)
8282
a.NoError(err)

test/e2e-go/restAPI/restClient_test.go

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,9 @@ func TestAccountParticipationInfo(t *testing.T) {
553553
firstRound := basics.Round(params.LastRound + 1)
554554
lastRound := basics.Round(params.LastRound + 1000)
555555
dilution := uint64(100)
556+
var stateproof merklesignature.Verifier
557+
stateproof[0] = 1 // change some byte so the stateproof is not considered empty (required since consensus v31)
558+
556559
randomVotePKStr := randomString(32)
557560
var votePK crypto.OneTimeSignatureVerifier
558561
copy(votePK[:], []byte(randomVotePKStr))
@@ -576,6 +579,7 @@ func TestAccountParticipationInfo(t *testing.T) {
576579
VoteKeyDilution: dilution,
577580
VoteFirst: firstRound,
578581
VoteLast: lastRound,
582+
StateProofPK: stateproof,
579583
},
580584
}
581585
txID, err := testClient.SignAndBroadcastTransaction(wh, nil, tx)
@@ -590,6 +594,7 @@ func TestAccountParticipationInfo(t *testing.T) {
590594
a.Equal(uint64(firstRound), account.Participation.VoteFirst, "API must print correct first participation round")
591595
a.Equal(uint64(lastRound), account.Participation.VoteLast, "API must print correct last participation round")
592596
a.Equal(dilution, account.Participation.VoteKeyDilution, "API must print correct key dilution")
597+
// TODO: should we update the v1 API to support state proof? Currently it does not return this field.
593598
}
594599

595600
func TestSupply(t *testing.T) {
@@ -1063,9 +1068,6 @@ func TestStateProofInParticipationInfo(t *testing.T) {
10631068
var localFixture fixtures.RestClientFixture
10641069

10651070
proto := config.Consensus[protocol.ConsensusCurrentVersion]
1066-
// TODO: remove these 2 lines when CurrentVersion contains them already
1067-
proto.EnableStateProofKeyregCheck = true
1068-
proto.MaxKeyregValidPeriod = config.Consensus[protocol.ConsensusFuture].MaxKeyregValidPeriod
10691071
localFixture.SetConsensus(config.ConsensusProtocols{protocol.ConsensusCurrentVersion: proto})
10701072

10711073
localFixture.Setup(t, filepath.Join("nettemplates", "TwoNodes50Each.json"))
@@ -1168,22 +1170,7 @@ func TestNilStateProofInParticipationInfo(t *testing.T) {
11681170
a := require.New(fixtures.SynchronizedTest(t))
11691171
var localFixture fixtures.RestClientFixture
11701172

1171-
// currently, the genesis creator uses the EnableStateProofKeyregCheck flag on the future
1172-
// version to write a statproof to the genesis file.
1173-
// we want to create a gensis file without state proof.
1174-
// + need to revert this change if other tests use that
1175-
tmp := config.Consensus[protocol.ConsensusFuture]
1176-
tmp.EnableStateProofKeyregCheck = false
1177-
config.Consensus[protocol.ConsensusFuture] = tmp
1178-
1179-
defer func() {
1180-
tmp := config.Consensus[protocol.ConsensusFuture]
1181-
tmp.EnableStateProofKeyregCheck = true
1182-
config.Consensus[protocol.ConsensusFuture] = tmp
1183-
}()
1184-
1185-
localFixture.SetConsensus(config.Consensus)
1186-
localFixture.Setup(t, filepath.Join("nettemplates", "TwoNodes50Each.json"))
1173+
localFixture.Setup(t, filepath.Join("nettemplates", "TwoNodes50EachV30.json"))
11871174
defer localFixture.Shutdown()
11881175

11891176
testClient := localFixture.LibGoalClient
@@ -1226,7 +1213,6 @@ func TestNilStateProofInParticipationInfo(t *testing.T) {
12261213
VotePK: votePK,
12271214
SelectionPK: selPK,
12281215
VoteFirst: firstRound,
1229-
StateProofPK: merklesignature.Verifier{},
12301216
VoteLast: lastRound,
12311217
VoteKeyDilution: dilution,
12321218
Nonparticipation: false,

0 commit comments

Comments
 (0)