Skip to content

Commit

Permalink
core/state: reduce memory allocation in IsAddressBlacklisted (#460)
Browse files Browse the repository at this point in the history
* core/state: add GetLocMappingAtKey test

* core/state: reduce memory allocation in GetLocMappingAtKey

> go test -bench=BenchmarkGetLocMappingAtKey -benchtime=5s

Before

goos: linux
goarch: amd64
pkg: github.com/ethereum/go-ethereum/core/state
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
BenchmarkGetLocMappingAtKey-8            8499260               877.7 ns/op           664 B/op          9 allocs/op

After

goos: linux
goarch: amd64
pkg: github.com/ethereum/go-ethereum/core/state
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
BenchmarkGetLocMappingAtKey-8            9745719               592.2 ns/op           584 B/op          5 allocs/op

* core/state: add IsAddressBlacklisted test

* core/state: reduce memory allocation in IsAddressBlacklisted

> go test -bench=BenchmarkIsAddressBlacklisted -benchtime=5s

Before

goos: linux
goarch: amd64
pkg: github.com/ethereum/go-ethereum/core/state
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
BenchmarkIsAddressBlacklisted-8          3349110              2432 ns/op             480 B/op         11 allocs/op

After

goos: linux
goarch: amd64
pkg: github.com/ethereum/go-ethereum/core/state
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
BenchmarkIsAddressBlacklisted-8          3863929              2245 ns/op             352 B/op          9 allocs/op

* core/state: reduce memory allocation in GetLocSimpleVariable
  • Loading branch information
minh-bq authored Jul 1, 2024
1 parent 5677825 commit 265bf11
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 10 deletions.
18 changes: 12 additions & 6 deletions core/state/location_cacl.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
package state

import (
"encoding/binary"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)

func GetLocSimpleVariable(slot uint64) common.Hash {
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
var slotHash common.Hash

binary.BigEndian.PutUint64(slotHash[len(slotHash)-8:], slot)
return slotHash
}

func GetLocMappingAtKey(key common.Hash, slot uint64) common.Hash {
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
ret := new(big.Int)
ret.SetBytes(retByte)
return common.BigToHash(ret)
var buffer []byte

buffer = key.Bytes()
// Write 8-byte slot to 32-byte space in big endian order.
// First write 24 0-bytes then write 8-slot in big endian.
buffer = common.PadTo(buffer, len(buffer)+24)
buffer = binary.BigEndian.AppendUint64(buffer, slot)
return crypto.Keccak256Hash(buffer)
}

func GetLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {
Expand Down
33 changes: 33 additions & 0 deletions core/state/location_cacl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package state

import (
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
)

func TestGetLocSimpleVariable(t *testing.T) {
hash := GetLocSimpleVariable(12)
expect := common.BigToHash(big.NewInt(12))

if hash != expect {
t.Fatalf("Hash mismatches, got %s expect %s", hash, expect)
}
}

func TestGetLocMappingAtKey(t *testing.T) {
hash := GetLocMappingAtKey(common.BigToHash(big.NewInt(10)), 12)

expect := common.HexToHash("0x9e6c92d7be355807bd948171438a5e65aaf9e4c36f1405c1b9ca25d27c4ea3a0")
if hash != expect {
t.Fatalf("Hash mismatches, got %s expect %s", hash, expect)
}
}

func BenchmarkGetLocMappingAtKey(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
GetLocMappingAtKey(common.BigToHash(big.NewInt(10)), 12)
}
}
14 changes: 10 additions & 4 deletions core/state/statedb_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ var (
slotRoninValidatorMapping = map[string]uint64{
VALIDATORS: 6,
}
valueOne common.Hash
)

func init() {
valueOne.SetBytes([]byte{0x1})
}

// IsWhitelistedDeployer reads the contract storage to check if an address is allow to deploy
func IsWhitelistedDeployerV2(statedb *StateDB, address common.Address, blockTime uint64, whiteListContract *common.Address) bool {
contract := *whiteListContract
Expand Down Expand Up @@ -94,15 +99,16 @@ func IsAddressBlacklisted(statedb *StateDB, blacklistAddr *common.Address, addre

contract := *blacklistAddr
disabledSlot := slotBlacklistContractMapping[DISABLED]
disabled := statedb.GetState(contract, GetLocSimpleVariable(disabledSlot))
if disabled.Big().Cmp(big.NewInt(1)) == 0 {
disabledStateValue := statedb.GetState(contract, GetLocSimpleVariable(disabledSlot))

if disabledStateValue == valueOne {
return false
}

blacklistedSlot := slotBlacklistContractMapping[BLACKLISTED]
valueLoc := GetLocMappingAtKey(address.Hash(), blacklistedSlot)
blacklisted := statedb.GetState(contract, valueLoc)
return blacklisted.Big().Cmp(big.NewInt(1)) == 0
blacklistedStateValue := statedb.GetState(contract, valueLoc)
return blacklistedStateValue == valueOne
}

func GetSCValidators(statedb *StateDB) []common.Address {
Expand Down
49 changes: 49 additions & 0 deletions core/state/statedb_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package state

import (
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
)

func TestIsAddressBlacklisted(t *testing.T) {
blackListContract := common.Address{0x11}

statedb, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)

blacklistedAddress := common.BigToAddress(common.Big3)
// Blacklist address 0x000..0003
statedb.SetState(
blackListContract,
common.HexToHash("0x7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b"),
common.BigToHash(common.Big1),
)
if !IsAddressBlacklisted(statedb, &blackListContract, &blacklistedAddress) {
t.Fatalf("Expect address %s to be blacklisted", blacklistedAddress.String())
}

notBlacklistedAddress := common.BigToAddress(big.NewInt(10))
if IsAddressBlacklisted(statedb, &blackListContract, &notBlacklistedAddress) {
t.Fatalf("Expect address %s to be not blacklisted", notBlacklistedAddress.String())
}

statedb.SetState(blackListContract, common.BigToHash(common.Big2), common.BigToHash(common.Big1))
if IsAddressBlacklisted(statedb, &blackListContract, &blacklistedAddress) {
t.Fatalf("Expect address %s to be not blacklisted", blacklistedAddress.String())
}
}

func BenchmarkIsAddressBlacklisted(b *testing.B) {
statedb, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
blackListContract := common.Address{0x11}

queriedAddress := common.BigToAddress(common.Big3)

b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
IsAddressBlacklisted(statedb, &blackListContract, &queriedAddress)
}
}

0 comments on commit 265bf11

Please sign in to comment.