Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ type ConsensusParams struct {
// be read in the transaction
MaxAppTxnForeignAssets int

// maximum number of "foreign references" (accounts, asa, app)
// that can be attached to a single app call.
MaxAppTotalTxnReferences int

// maximum cost of application approval program or clear state program
MaxAppProgramCost int

Expand Down Expand Up @@ -859,6 +863,11 @@ func initConsensusProtocols() {
// Can look up 2 assets to see asset parameters
v24.MaxAppTxnForeignAssets = 2

// Intended to have no effect in v24 (it's set to accounts +
// asas + apps). In later vers, it allows increasing the
// individual limits while maintaining same max references.
v24.MaxAppTotalTxnReferences = 8

// 64 byte keys @ ~333 microAlgos/byte + delta
v24.SchemaMinBalancePerEntry = 25000

Expand Down Expand Up @@ -953,6 +962,16 @@ func initConsensusProtocols() {
vFuture.MaxExtraAppProgramPages = 3
vFuture.MaxAppProgramLen = 2048

// Individual limits raised
vFuture.MaxAppTxnForeignApps = 8
vFuture.MaxAppTxnForeignAssets = 8
// but MaxAppTxnReferences is unchanged.

// MaxAppTxnAccounts has not been raised yet. It is already
// higher (4) and there is a multiplicative effect in
// "reachability" between accounts and creatables, so we
// retain 4 x 4 as worst case.

// enable the InitialRewardsRateCalculation fix
vFuture.InitialRewardsRateCalculation = true
// Enable transaction Merkle tree.
Expand Down
5 changes: 5 additions & 0 deletions data/transactions/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,11 @@ func (tx Transaction) WellFormed(spec SpecialAddresses, proto config.ConsensusPa
return fmt.Errorf("tx.ForeignAssets too long, max number of foreign assets is %d", proto.MaxAppTxnForeignAssets)
}

// Limit the sum of all types of references that bring in account records
if len(tx.Accounts)+len(tx.ForeignApps)+len(tx.ForeignAssets) > proto.MaxAppTotalTxnReferences {
return fmt.Errorf("tx has too many references, max is %d", proto.MaxAppTotalTxnReferences)
}

if tx.ExtraProgramPages > uint32(proto.MaxExtraAppProgramPages) {
return fmt.Errorf("tx.ExtraProgramPages too large, max number of extra pages is %d", proto.MaxExtraAppProgramPages)
}
Expand Down
65 changes: 65 additions & 0 deletions data/transactions/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,71 @@ func TestWellFormedErrors(t *testing.T) {
proto: futureProto,
expectedError: fmt.Errorf("tx.ExtraProgramPages too large, max number of extra pages is %d", futureProto.MaxExtraAppProgramPages),
},
{
tx: Transaction{
Type: protocol.ApplicationCallTx,
Header: okHeader,
ApplicationCallTxnFields: ApplicationCallTxnFields{
ApplicationID: 1,
ForeignApps: []basics.AppIndex{10, 11},
},
},
spec: specialAddr,
proto: protoV27,
},
{
tx: Transaction{
Type: protocol.ApplicationCallTx,
Header: okHeader,
ApplicationCallTxnFields: ApplicationCallTxnFields{
ApplicationID: 1,
ForeignApps: []basics.AppIndex{10, 11, 12},
},
},
spec: specialAddr,
proto: protoV27,
expectedError: fmt.Errorf("tx.ForeignApps too long, max number of foreign apps is 2"),
},
{
tx: Transaction{
Type: protocol.ApplicationCallTx,
Header: okHeader,
ApplicationCallTxnFields: ApplicationCallTxnFields{
ApplicationID: 1,
ForeignApps: []basics.AppIndex{10, 11, 12, 13, 14, 15, 16, 17},
},
},
spec: specialAddr,
proto: futureProto,
},
{
tx: Transaction{
Type: protocol.ApplicationCallTx,
Header: okHeader,
ApplicationCallTxnFields: ApplicationCallTxnFields{
ApplicationID: 1,
ForeignAssets: []basics.AssetIndex{14, 15, 16, 17, 18, 19, 20, 21, 22},
},
},
spec: specialAddr,
proto: futureProto,
expectedError: fmt.Errorf("tx.ForeignAssets too long, max number of foreign assets is 8"),
},
{
tx: Transaction{
Type: protocol.ApplicationCallTx,
Header: okHeader,
ApplicationCallTxnFields: ApplicationCallTxnFields{
ApplicationID: 1,
Accounts: []basics.Address{basics.Address{}, basics.Address{}, basics.Address{}},
ForeignApps: []basics.AppIndex{14, 15, 16, 17},
ForeignAssets: []basics.AssetIndex{14, 15, 16, 17},
},
},
spec: specialAddr,
proto: futureProto,
expectedError: fmt.Errorf("tx has too many references, max is 8"),
},
}
for _, usecase := range usecases {
err := usecase.tx.WellFormed(usecase.spec, usecase.proto)
Expand Down