From f2b254a346ca631a039e99db25a7cb399b1f7816 Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Fri, 17 Nov 2023 10:19:39 -0500 Subject: [PATCH 1/5] protocol: Add block hash to state proof's LightBlockHeader (#589) --- protocol/config/consensus.go | 5 +++++ types/lightBlockHeader.go | 1 + 2 files changed, 6 insertions(+) diff --git a/protocol/config/consensus.go b/protocol/config/consensus.go index 90174faa..40f5557f 100644 --- a/protocol/config/consensus.go +++ b/protocol/config/consensus.go @@ -400,6 +400,11 @@ type ConsensusParams struct { // their account balances. StateProofExcludeTotalWeightWithRewards bool + // StateProofBlockHashInLightHeader specifies that the LightBlockHeader + // committed to by state proofs should contain the BlockHash of each + // block, instead of the seed. + StateProofBlockHashInLightHeader bool + // EnableAssetCloseAmount adds an extra field to the ApplyData. The field contains the amount of the remaining // asset that were sent to the close-to address. EnableAssetCloseAmount bool diff --git a/types/lightBlockHeader.go b/types/lightBlockHeader.go index c427b1b1..7e4951d6 100644 --- a/types/lightBlockHeader.go +++ b/types/lightBlockHeader.go @@ -11,6 +11,7 @@ type LightBlockHeader struct { _struct struct{} `codec:",omitempty,omitemptyarray"` Seed Seed `codec:"0"` + BlockHash Digest `codec:"1"` RoundNumber Round `codec:"r"` GenesisHash Digest `codec:"gh"` Sha256TxnCommitment Digest `codec:"tc,allocbound=Sha256Size"` From 939542cf463a961092a889b2fc9176cb2dbc83b1 Mon Sep 17 00:00:00 2001 From: Gary <982483+gmalouf@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:34:35 -0500 Subject: [PATCH 2/5] Add period 0 deadline timeout parameter to consensus params. (#618) --- protocol/config/consensus.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/protocol/config/consensus.go b/protocol/config/consensus.go index 40f5557f..408dc9b8 100644 --- a/protocol/config/consensus.go +++ b/protocol/config/consensus.go @@ -143,6 +143,8 @@ type ConsensusParams struct { // time for nodes to wait for block proposal headers for period = 0, value should be configured to suit best case // critical path AgreementFilterTimeoutPeriod0 time.Duration + // Duration of the second agreement step for period=0, value should be configured to suit best case critical path + AgreementDeadlineTimeoutPeriod0 time.Duration FastRecoveryLambda time.Duration // time between fast recovery attempts @@ -707,8 +709,9 @@ func initConsensusProtocols() { DownCommitteeSize: 10000, DownCommitteeThreshold: 7750, - AgreementFilterTimeout: 4 * time.Second, - AgreementFilterTimeoutPeriod0: 4 * time.Second, + AgreementFilterTimeout: 4 * time.Second, + AgreementFilterTimeoutPeriod0: 4 * time.Second, + AgreementDeadlineTimeoutPeriod0: Protocol.BigLambda + Protocol.SmallLambda, FastRecoveryLambda: 5 * time.Minute, @@ -1242,11 +1245,20 @@ func initConsensusProtocols() { // ConsensusFuture is used to test features that are implemented // but not yet released in a production protocol version. vFuture := v38 + vFuture.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{} vFuture.LogicSigVersion = 10 // When moving this to a release, put a new higher LogicSigVersion here vFuture.EnableLogicSigCostPooling = true + vFuture.AgreementDeadlineTimeoutPeriod0 = 4 * time.Second + + vFuture.StateProofBlockHashInLightHeader = true + + // Setting DynamicFilterTimeout in vFuture will impact e2e test performance + // by reducing round time. Hence, it is commented out for now. + // vFuture.DynamicFilterTimeout = true + Consensus[protocol.ConsensusFuture] = vFuture // vAlphaX versions are an separate series of consensus parameters and versions for alphanet From 92422eeda956a0ee9e0cd03f56bac5daad8158ca Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:40:24 -0500 Subject: [PATCH 3/5] Regenerate code from specification file (#620) Co-authored-by: Algorand Generation Bot --- .../common/models/simulation_transaction_exec_trace.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/v2/common/models/simulation_transaction_exec_trace.go b/client/v2/common/models/simulation_transaction_exec_trace.go index ca300a5f..068fe03e 100644 --- a/client/v2/common/models/simulation_transaction_exec_trace.go +++ b/client/v2/common/models/simulation_transaction_exec_trace.go @@ -19,6 +19,16 @@ type SimulationTransactionExecTrace struct { // a clear state program. ClearStateProgramTrace []SimulationOpcodeTraceUnit `json:"clear-state-program-trace,omitempty"` + // ClearStateRollback if true, indicates that the clear state program failed and + // any persistent state changes it produced should be reverted once the program + // exits. + ClearStateRollback bool `json:"clear-state-rollback,omitempty"` + + // ClearStateRollbackError the error message explaining why the clear state program + // failed. This field will only be populated if clear-state-rollback is true and + // the failure was due to an execution error. + ClearStateRollbackError string `json:"clear-state-rollback-error,omitempty"` + // InnerTrace an array of SimulationTransactionExecTrace representing the execution // trace of any inner transactions executed. InnerTrace []SimulationTransactionExecTrace `json:"inner-trace,omitempty"` From b77192e2f0349a5eac6fe66cc262250cc21e283e Mon Sep 17 00:00:00 2001 From: Gary <982483+gmalouf@users.noreply.github.com> Date: Fri, 15 Dec 2023 13:11:20 -0500 Subject: [PATCH 4/5] Consensus: Update consensus files for v39 along with types sync. (#621) * Update consensus files for v39 along with types sync. * Remove unused / linter violating msgp annotation in consensus.go. --- protocol/config/consensus.go | 86 +++++++++++++++++++++++++++++++----- protocol/consensus.go | 8 +++- types/applications.go | 2 +- types/asset.go | 6 +-- types/block.go | 15 +++---- types/genesis.go | 3 +- types/statedelta.go | 5 ++- 7 files changed, 96 insertions(+), 29 deletions(-) diff --git a/protocol/config/consensus.go b/protocol/config/consensus.go index 408dc9b8..94ce41be 100644 --- a/protocol/config/consensus.go +++ b/protocol/config/consensus.go @@ -588,6 +588,42 @@ var MaxAvailableAppProgramLen int // to be taken offline, that would be proposed to be taken offline. var MaxProposedExpiredOnlineAccounts int +// MaxAppTotalArgLen is the maximum number of bytes across all arguments of an application +// max sum([len(arg) for arg in txn.ApplicationArgs]) +var MaxAppTotalArgLen int + +// MaxAssetNameBytes is the maximum asset name length in bytes +var MaxAssetNameBytes int + +// MaxAssetUnitNameBytes is the maximum asset unit name length in bytes +var MaxAssetUnitNameBytes int + +// MaxAssetURLBytes is the maximum asset URL length in bytes +var MaxAssetURLBytes int + +// MaxAppBytesValueLen is the maximum length of a bytes value used in an application's global or +// local key/value store +var MaxAppBytesValueLen int + +// MaxAppBytesKeyLen is the maximum length of a key used in an application's global or local +// key/value store +var MaxAppBytesKeyLen int + +// StateProofTopVoters is a bound on how many online accounts get to +// participate in forming the state proof, by including the +// top StateProofTopVoters accounts (by normalized balance) into the +// vector commitment. +var StateProofTopVoters int + +// MaxTxnBytesPerBlock determines the maximum number of bytes +// that transactions can take up in a block. Specifically, +// the sum of the lengths of encodings of each transaction +// in a block must not exceed MaxTxnBytesPerBlock. +var MaxTxnBytesPerBlock int + +// MaxAppTxnForeignApps is the max number of foreign apps per txn across all consensus versions +var MaxAppTxnForeignApps int + func checkSetMax(value int, curMax *int) { if value > *curMax { *curMax = value @@ -625,6 +661,19 @@ func checkSetAllocBounds(p ConsensusParams) { checkSetMax(p.MaxAppProgramLen, &MaxLogCalls) checkSetMax(p.MaxInnerTransactions*p.MaxTxGroupSize, &MaxInnerTransactionsPerDelta) checkSetMax(p.MaxProposedExpiredOnlineAccounts, &MaxProposedExpiredOnlineAccounts) + + // These bounds are exported to make them available to the msgp generator for calculating + // maximum valid message size for each message going across the wire. + checkSetMax(p.MaxAppTotalArgLen, &MaxAppTotalArgLen) + checkSetMax(p.MaxAssetNameBytes, &MaxAssetNameBytes) + checkSetMax(p.MaxAssetUnitNameBytes, &MaxAssetUnitNameBytes) + checkSetMax(p.MaxAssetURLBytes, &MaxAssetURLBytes) + checkSetMax(p.MaxAppBytesValueLen, &MaxAppBytesValueLen) + checkSetMax(p.MaxAppKeyLen, &MaxAppBytesKeyLen) + checkSetMax(int(p.StateProofTopVoters), &StateProofTopVoters) + checkSetMax(p.MaxTxnBytesPerBlock, &MaxTxnBytesPerBlock) + + checkSetMax(p.MaxAppTxnForeignApps, &MaxAppTxnForeignApps) } // DeepCopy creates a deep copy of a consensus protocols map. @@ -669,6 +718,9 @@ func (cp ConsensusProtocols) Merge(configurableConsensus ConsensusProtocols) Con return staticConsensus } +// initConsensusProtocols defines the consensus protocol values and how values change across different versions of the protocol. +// +// These are the only valid and tested consensus values and transitions. Other settings are not tested and may lead to unexpected behavior. func initConsensusProtocols() { // WARNING: copying a ConsensusParams by value into a new variable // does not copy the ApprovedUpgrades map. Make sure that each new @@ -1242,22 +1294,34 @@ func initConsensusProtocols() { // for the sake of future manual calculations, we'll round that down a bit : v37.ApprovedUpgrades[protocol.ConsensusV38] = 10000 - // ConsensusFuture is used to test features that are implemented - // but not yet released in a production protocol version. - vFuture := v38 + v39 := v38 + v39.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{} - vFuture.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{} + v39.LogicSigVersion = 10 + v39.EnableLogicSigCostPooling = true + + v39.AgreementDeadlineTimeoutPeriod0 = 4 * time.Second + + v39.DynamicFilterTimeout = true - vFuture.LogicSigVersion = 10 // When moving this to a release, put a new higher LogicSigVersion here - vFuture.EnableLogicSigCostPooling = true + v39.StateProofBlockHashInLightHeader = true - vFuture.AgreementDeadlineTimeoutPeriod0 = 4 * time.Second + // For future upgrades, round times will likely be shorter so giving ourselves some buffer room + v39.MaxUpgradeWaitRounds = 250000 - vFuture.StateProofBlockHashInLightHeader = true + Consensus[protocol.ConsensusV39] = v39 + + // v38 can be upgraded to v39, with an update delay of 7d: + // 157000 = (7 * 24 * 60 * 60 / 3.3 round times currently) + // but our current max is 150000 so using that : + v38.ApprovedUpgrades[protocol.ConsensusV39] = 150000 + + // ConsensusFuture is used to test features that are implemented + // but not yet released in a production protocol version. + vFuture := v39 + vFuture.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{} - // Setting DynamicFilterTimeout in vFuture will impact e2e test performance - // by reducing round time. Hence, it is commented out for now. - // vFuture.DynamicFilterTimeout = true + vFuture.LogicSigVersion = 11 // When moving this to a release, put a new higher LogicSigVersion here Consensus[protocol.ConsensusFuture] = vFuture diff --git a/protocol/consensus.go b/protocol/consensus.go index 3a9e525d..aad06796 100644 --- a/protocol/consensus.go +++ b/protocol/consensus.go @@ -195,6 +195,12 @@ const ConsensusV38 = ConsensusVersion( "https://github.com/algorandfoundation/specs/tree/abd3d4823c6f77349fc04c3af7b1e99fe4df699f", ) +// ConsensusV39 enables dynamic filter timeouts, a deadline timeout of 4 seconds, +// TEAL v10 logicSig opcode budget pooling along with elliptic curve ops on some pairing friendly curves. +const ConsensusV39 = ConsensusVersion( + "https://github.com/algorandfoundation/specs/tree/925a46433742afb0b51bb939354bd907fa88bf95", +) + // ConsensusFuture is a protocol that should not appear in any production // network, but is used to test features before they are released. const ConsensusFuture = ConsensusVersion( @@ -224,7 +230,7 @@ const ConsensusVAlpha5 = ConsensusVersion("alpha5") // ConsensusCurrentVersion is the latest version and should be used // when a specific version is not provided. -const ConsensusCurrentVersion = ConsensusV38 +const ConsensusCurrentVersion = ConsensusV39 // Error is used to indicate that an unsupported protocol has been detected. type Error ConsensusVersion diff --git a/types/applications.go b/types/applications.go index fb9a5a94..b398f7cf 100644 --- a/types/applications.go +++ b/types/applications.go @@ -105,7 +105,7 @@ type ApplicationCallTxnFields struct { ApplicationID AppIndex `codec:"apid"` OnCompletion OnCompletion `codec:"apan"` - ApplicationArgs [][]byte `codec:"apaa,allocbound=encodedMaxApplicationArgs"` + ApplicationArgs [][]byte `codec:"apaa,allocbound=encodedMaxApplicationArgs,maxtotalbytes=config.MaxAppTotalArgLen"` Accounts []Address `codec:"apat,allocbound=encodedMaxAccounts"` ForeignApps []AppIndex `codec:"apfa,allocbound=encodedMaxForeignApps"` ForeignAssets []AssetIndex `codec:"apas,allocbound=encodedMaxForeignAssets"` diff --git a/types/asset.go b/types/asset.go index 3fa226ca..89e28426 100644 --- a/types/asset.go +++ b/types/asset.go @@ -40,14 +40,14 @@ type AssetParams struct { // UnitName specifies a hint for the name of a unit of // this asset. - UnitName string `codec:"un"` + UnitName string `codec:"un,allocbound=config.MaxAssetUnitNameBytes"` // AssetName specifies a hint for the name of the asset. - AssetName string `codec:"an"` + AssetName string `codec:"an,allocbound=config.MaxAssetNameBytes"` // URL specifies a URL where more information about the asset can be // retrieved - URL string `codec:"au"` + URL string `codec:"au,allocbound=config.MaxAssetURLBytes"` // MetadataHash specifies a commitment to some unspecified asset // metadata. The format of this metadata is up to the application. diff --git a/types/block.go b/types/block.go index 2e2a1f6c..213fa86c 100644 --- a/types/block.go +++ b/types/block.go @@ -23,7 +23,7 @@ type ( TimeStamp int64 `codec:"ts"` // Genesis ID to which this block belongs. - GenesisID string `codec:"gen"` + GenesisID string `codec:"gen,allocbound=config.MaxGenesisIDLen"` // Genesis hash to which this block belongs. GenesisHash Digest `codec:"gh"` @@ -79,14 +79,9 @@ type ( UpgradeState UpgradeVote - // TxnCounter counts the number of transactions committed in the - // ledger, from the time at which support for this feature was - // introduced. - // - // Specifically, TxnCounter is the number of the next transaction - // that will be committed after this block. It is 0 when no - // transactions have ever been committed (since TxnCounter - // started being supported). + // TxnCounter is the number of the next transaction that will be + // committed after this block. Genesis blocks can start at either + // 0 or 1000, depending on a consensus parameter (AppForbidLowResources). TxnCounter uint64 `codec:"tc"` // StateProofTracking tracks the status of the state proofs, potentially @@ -205,7 +200,7 @@ type ( // A Block contains the Payset and metadata corresponding to a given Round. Block struct { BlockHeader - Payset Payset `codec:"txns"` + Payset Payset `codec:"txns,maxtotalbytes=config.MaxTxnBytesPerBlock"` } // A Payset represents a common, unforgeable, consistent, ordered set of SignedTxn objects. diff --git a/types/genesis.go b/types/genesis.go index 7939b644..4e6ab066 100644 --- a/types/genesis.go +++ b/types/genesis.go @@ -70,8 +70,9 @@ type Account struct { Status byte `codec:"onl"` MicroAlgos uint64 `codec:"algo"` VoteID [32]byte `codec:"vote"` - SelectionID [32]byte `codec:"sel"` StateProofID [64]byte `codec:"stprf"` + SelectionID [32]byte `codec:"sel"` + VoteFirstValid uint64 `codec:"voteFst"` VoteLastValid uint64 `codec:"voteLst"` VoteKeyDilution uint64 `codec:"voteKD"` } diff --git a/types/statedelta.go b/types/statedelta.go index 54c71fb5..84c3a00c 100644 --- a/types/statedelta.go +++ b/types/statedelta.go @@ -313,8 +313,9 @@ type LedgerStateDelta struct { // new block header; read-only Hdr *BlockHeader - // next round for which we expect a state proof. - // zero if no state proof is expected. + // StateProofNext represents modification on StateProofNextRound field in the block header. If the block contains + // a valid state proof transaction, this field will contain the next round for state proof. + // otherwise it will be set to 0. StateProofNext Round // previous block timestamp From b666698d330edf764a643a1ff81ac89b89df3653 Mon Sep 17 00:00:00 2001 From: gmalouf Date: Fri, 15 Dec 2023 18:24:49 +0000 Subject: [PATCH 5/5] bump up version to v2.4.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7315c10..43467b22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# v2.4.0 + + + +## What's Changed +### Enhancements +* protocol: Add block hash to state proof's LightBlockHeader by @zeldovich in https://github.com/algorand/go-algorand-sdk/pull/589 +* Consensus Config: Add period 0 deadline timeout parameter to consensus params. by @gmalouf in https://github.com/algorand/go-algorand-sdk/pull/618 +* Consensus: Update consensus files for v39 along with types sync. by @gmalouf in https://github.com/algorand/go-algorand-sdk/pull/621 +### Other +* Regenerate code with the latest specification file (b5adad95) by @github-actions in https://github.com/algorand/go-algorand-sdk/pull/620 + +## New Contributors +* @zeldovich made their first contribution in https://github.com/algorand/go-algorand-sdk/pull/589 + +**Full Changelog**: https://github.com/algorand/go-algorand-sdk/compare/v2.3.0...v2.4.0 + # v2.3.0 ## What's Changed