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 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"` diff --git a/protocol/config/consensus.go b/protocol/config/consensus.go index 90174faa..94ce41be 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 @@ -400,6 +402,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 @@ -581,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 @@ -618,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. @@ -662,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 @@ -702,8 +761,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, @@ -1234,13 +1294,34 @@ func initConsensusProtocols() { // for the sake of future manual calculations, we'll round that down a bit : v37.ApprovedUpgrades[protocol.ConsensusV38] = 10000 + v39 := v38 + v39.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{} + + v39.LogicSigVersion = 10 + v39.EnableLogicSigCostPooling = true + + v39.AgreementDeadlineTimeoutPeriod0 = 4 * time.Second + + v39.DynamicFilterTimeout = true + + v39.StateProofBlockHashInLightHeader = true + + // For future upgrades, round times will likely be shorter so giving ourselves some buffer room + v39.MaxUpgradeWaitRounds = 250000 + + 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 := v38 + vFuture := v39 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.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/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"` 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