Skip to content

Commit

Permalink
marginally optimize txnToDigest a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
algorandskiy committed Nov 8, 2023
1 parent 5fc75b6 commit 8c4c28b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
23 changes: 13 additions & 10 deletions data/appRateLimiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,16 +248,19 @@ func txgroupToKeys(txgroup []transactions.SignedTxn, origin []byte, seed uint64,
// The 16 bytes salt makes it harder to find collisions if an adversary attempts to censor
// some app by finding a collision with some app and flood a network with such transactions:
// h(app + relay_ip) = h(app2 + relay_ip).
var buf [8 + 16 + 16]byte // uint64 + 16 bytes of salt + up to 16 bytes of address
txnToDigest := func(appIdx basics.AppIndex) keyType {
binary.LittleEndian.PutUint64(buf[:8], uint64(appIdx))
copy(buf[8:], salt[:])
copied := copy(buf[8+16:], origin)

h := blake2b.Sum256(buf[:8+16+copied])
var key keyType
copy(key[:], h[:len(key)])
return key
// uint64 + 16 bytes of salt + up to 16 bytes of address
// salt and origin are fixed so pre-copy them into the buf
var buf [8 + 16 + 16]byte
copy(buf[8:], salt[:])
copied := copy(buf[8+16:], origin)
bufLen := 8 + 16 + copied

txnToDigest := func(appIdx basics.AppIndex) (key keyType) {
binary.LittleEndian.PutUint64(buf[:8], uint64(appIdx))
h := blake2b.Sum256(buf[:bufLen])
copy(key[:], h[:len(keyType{})])
return
}
txnToBucket := func(appIdx basics.AppIndex) int {
return int(memhash64(uint64(appIdx), seed) % uint64(numBuckets))
Expand All @@ -283,9 +286,9 @@ func txgroupToKeys(txgroup []transactions.SignedTxn, origin []byte, seed uint64,
if len(txgroup[i].Txn.ForeignApps) > 0 {
for _, appIdx := range txgroup[i].Txn.ForeignApps {
if valid(appIdx) {
seen[appIdx] = struct{}{}
keysBuckets.buckets = append(keysBuckets.buckets, txnToBucket(appIdx))
keysBuckets.keys = append(keysBuckets.keys, txnToDigest(appIdx))
seen[appIdx] = struct{}{}
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions data/appRateLimiter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,41 @@ func TestAppRateLimiter_TxgroupToKeys(t *testing.T) {
require.Equal(t, len(kb.buckets), len(kb.buckets))
putAppKeyBuf(kb)
}

func BenchmarkAppRateLimiter_TxgroupToKeys(b *testing.B) {
rnd := rand.New(rand.NewSource(123))

txgroups := make([][]transactions.SignedTxn, 0, b.N)
for i := 0; i < b.N; i++ {
txgroup := make([]transactions.SignedTxn, 0, config.MaxTxGroupSize)
for j := 0; j < config.MaxTxGroupSize; j++ {
apptxn := transactions.Transaction{
Type: protocol.ApplicationCallTx,
ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
ApplicationID: basics.AppIndex(rnd.Uint64()),
ForeignApps: []basics.AppIndex{basics.AppIndex(rnd.Uint64()), basics.AppIndex(rnd.Uint64()), basics.AppIndex(rnd.Uint64()), basics.AppIndex(rnd.Uint64())},
},
}
txgroup = append(txgroup, transactions.SignedTxn{Txn: apptxn})
}
txgroups = append(txgroups, txgroup)
}

b.ResetTimer()
b.ReportAllocs()

origin := make([]byte, 4)
_, err := rnd.Read(origin)
require.NoError(b, err)
require.NotEmpty(b, origin)

salt := [16]byte{}
_, err = rnd.Read(salt[:])
require.NoError(b, err)
require.NotEmpty(b, salt)

for i := 0; i < b.N; i++ {
kb := txgroupToKeys(txgroups[i], origin, 123, salt, numBuckets)
putAppKeyBuf(kb)
}
}

0 comments on commit 8c4c28b

Please sign in to comment.