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
3 changes: 3 additions & 0 deletions config/bounds/bounds.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ var MaxTxnBytesPerBlock int
// MaxAppTxnForeignApps is the max number of foreign apps per txn across all consensus versions
var MaxAppTxnForeignApps int

// MaxAppAccess is the max number of references allowed in txn.Access per txn across all consensus versions
var MaxAppAccess int

// MaxEvalDeltaTotalLogSize is the maximum size of the sum of all log sizes in a single eval delta.
const MaxEvalDeltaTotalLogSize = 1024

Expand Down
1 change: 1 addition & 0 deletions config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,7 @@ func checkSetAllocBounds(p ConsensusParams) {
checkSetMax(p.MaxTxnBytesPerBlock, &bounds.MaxTxnBytesPerBlock)

checkSetMax(p.MaxAppTxnForeignApps, &bounds.MaxAppTxnForeignApps)
checkSetMax(p.MaxAppAccess, &bounds.MaxAppAccess)
}

// DeepCopy creates a deep copy of a consensus protocols map.
Expand Down
30 changes: 15 additions & 15 deletions data/appRateLimiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,32 +265,32 @@ func txgroupToKeys(txgroup []transactions.SignedTxn, origin []byte, seed uint64,
txnToBucket := func(appIdx basics.AppIndex) int {
return int(memhash64(uint64(appIdx), seed) % uint64(numBuckets))
}
seen := make(map[basics.AppIndex]struct{}, len(txgroup)*(1+bounds.MaxAppTxnForeignApps))
seen := make(map[basics.AppIndex]struct{}, len(txgroup)*(1+max(bounds.MaxAppTxnForeignApps, bounds.MaxAppAccess)))
valid := func(appIdx basics.AppIndex) bool {
if appIdx != 0 {
_, ok := seen[appIdx]
return !ok
}
return false
}
record := func(appIdx basics.AppIndex) {
// hash appIdx into a bucket, do not use modulo without hashing first since it could
// assign two vanilla (and presumable, popular) apps to the same bucket.
if valid(appIdx) {
keysBuckets.buckets = append(keysBuckets.buckets, txnToBucket(appIdx))
keysBuckets.keys = append(keysBuckets.keys, txnToDigest(appIdx))
seen[appIdx] = struct{}{}
}
}
for i := range txgroup {
if txgroup[i].Txn.Type == protocol.ApplicationCallTx {
appIdx := txgroup[i].Txn.ApplicationID
if valid(appIdx) {
keysBuckets.buckets = append(keysBuckets.buckets, txnToBucket(appIdx))
keysBuckets.keys = append(keysBuckets.keys, txnToDigest(appIdx))
seen[appIdx] = struct{}{}
record(appIdx)
for _, appIdx := range txgroup[i].Txn.ForeignApps {
record(appIdx)
}
// hash appIdx into a bucket, do not use modulo without hashing first since it could
// assign two vanilla (and presumable, popular) apps to the same bucket.
if len(txgroup[i].Txn.ForeignApps) > 0 {
for _, appIdx := range txgroup[i].Txn.ForeignApps {
if valid(appIdx) {
keysBuckets.buckets = append(keysBuckets.buckets, txnToBucket(appIdx))
keysBuckets.keys = append(keysBuckets.keys, txnToDigest(appIdx))
seen[appIdx] = struct{}{}
}
}
for _, acc := range txgroup[i].Txn.Access {
record(acc.App)
}
}
}
Expand Down
26 changes: 21 additions & 5 deletions data/appRateLimiter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,32 +459,48 @@ func TestAppRateLimiter_TxgroupToKeys(t *testing.T) {

kb := txgroupToKeys(txgroup, nil, 123, [16]byte{}, 1)
require.Equal(t, 0, len(kb.keys))
require.Equal(t, len(kb.buckets), len(kb.buckets))
require.Equal(t, len(kb.keys), len(kb.buckets))
putAppKeyBuf(kb)

txgroup[0].Txn.ApplicationID = 1
kb = txgroupToKeys(txgroup, nil, 123, [16]byte{}, 1)
require.Equal(t, 1, len(kb.keys))
require.Equal(t, len(kb.buckets), len(kb.buckets))
require.Equal(t, len(kb.keys), len(kb.buckets))
putAppKeyBuf(kb)

txgroup[0].Txn.ForeignApps = append(txgroup[0].Txn.ForeignApps, 1)
kb = txgroupToKeys(txgroup, nil, 123, [16]byte{}, 1)
require.Equal(t, 1, len(kb.keys))
require.Equal(t, len(kb.buckets), len(kb.buckets))
require.Equal(t, len(kb.keys), len(kb.buckets))
putAppKeyBuf(kb)

txgroup[0].Txn.ForeignApps = append(txgroup[0].Txn.ForeignApps, 2)
kb = txgroupToKeys(txgroup, nil, 123, [16]byte{}, 1)
require.Equal(t, 2, len(kb.keys))
require.Equal(t, len(kb.buckets), len(kb.buckets))
require.Equal(t, len(kb.keys), len(kb.buckets))
putAppKeyBuf(kb)

apptxn.ApplicationID = 2
txgroup = append(txgroup, transactions.SignedTxn{Txn: apptxn})
kb = txgroupToKeys(txgroup, nil, 123, [16]byte{}, 1)
require.Equal(t, 2, len(kb.keys))
require.Equal(t, len(kb.buckets), len(kb.buckets))
require.Equal(t, len(kb.keys), len(kb.buckets))
putAppKeyBuf(kb)

// new app if from access list
apptxn.Access = []transactions.ResourceRef{{App: 3}}
txgroup = append(txgroup, transactions.SignedTxn{Txn: apptxn})
kb = txgroupToKeys(txgroup, nil, 123, [16]byte{}, 1)
require.Equal(t, 3, len(kb.keys))
require.Equal(t, len(kb.keys), len(kb.buckets))
putAppKeyBuf(kb)

// known app id in access list
apptxn.Access = []transactions.ResourceRef{{App: 3}, {App: 2}}
txgroup = append(txgroup, transactions.SignedTxn{Txn: apptxn})
kb = txgroupToKeys(txgroup, nil, 123, [16]byte{}, 1)
require.Equal(t, 3, len(kb.keys))
require.Equal(t, len(kb.keys), len(kb.buckets))
putAppKeyBuf(kb)
}

Expand Down
Loading