Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

Commit 265bf11

Browse files
authored
core/state: reduce memory allocation in IsAddressBlacklisted (#460)
* 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
1 parent 5677825 commit 265bf11

File tree

4 files changed

+104
-10
lines changed

4 files changed

+104
-10
lines changed

core/state/location_cacl.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
package state
22

33
import (
4+
"encoding/binary"
45
"math/big"
56

67
"github.com/ethereum/go-ethereum/common"
78
"github.com/ethereum/go-ethereum/crypto"
89
)
910

1011
func GetLocSimpleVariable(slot uint64) common.Hash {
11-
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
12+
var slotHash common.Hash
13+
14+
binary.BigEndian.PutUint64(slotHash[len(slotHash)-8:], slot)
1215
return slotHash
1316
}
1417

1518
func GetLocMappingAtKey(key common.Hash, slot uint64) common.Hash {
16-
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
17-
retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
18-
ret := new(big.Int)
19-
ret.SetBytes(retByte)
20-
return common.BigToHash(ret)
19+
var buffer []byte
20+
21+
buffer = key.Bytes()
22+
// Write 8-byte slot to 32-byte space in big endian order.
23+
// First write 24 0-bytes then write 8-slot in big endian.
24+
buffer = common.PadTo(buffer, len(buffer)+24)
25+
buffer = binary.BigEndian.AppendUint64(buffer, slot)
26+
return crypto.Keccak256Hash(buffer)
2127
}
2228

2329
func GetLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {

core/state/location_cacl_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package state
2+
3+
import (
4+
"math/big"
5+
"testing"
6+
7+
"github.com/ethereum/go-ethereum/common"
8+
)
9+
10+
func TestGetLocSimpleVariable(t *testing.T) {
11+
hash := GetLocSimpleVariable(12)
12+
expect := common.BigToHash(big.NewInt(12))
13+
14+
if hash != expect {
15+
t.Fatalf("Hash mismatches, got %s expect %s", hash, expect)
16+
}
17+
}
18+
19+
func TestGetLocMappingAtKey(t *testing.T) {
20+
hash := GetLocMappingAtKey(common.BigToHash(big.NewInt(10)), 12)
21+
22+
expect := common.HexToHash("0x9e6c92d7be355807bd948171438a5e65aaf9e4c36f1405c1b9ca25d27c4ea3a0")
23+
if hash != expect {
24+
t.Fatalf("Hash mismatches, got %s expect %s", hash, expect)
25+
}
26+
}
27+
28+
func BenchmarkGetLocMappingAtKey(b *testing.B) {
29+
b.ReportAllocs()
30+
for i := 0; i < b.N; i++ {
31+
GetLocMappingAtKey(common.BigToHash(big.NewInt(10)), 12)
32+
}
33+
}

core/state/statedb_utils.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ var (
3434
slotRoninValidatorMapping = map[string]uint64{
3535
VALIDATORS: 6,
3636
}
37+
valueOne common.Hash
3738
)
3839

40+
func init() {
41+
valueOne.SetBytes([]byte{0x1})
42+
}
43+
3944
// IsWhitelistedDeployer reads the contract storage to check if an address is allow to deploy
4045
func IsWhitelistedDeployerV2(statedb *StateDB, address common.Address, blockTime uint64, whiteListContract *common.Address) bool {
4146
contract := *whiteListContract
@@ -94,15 +99,16 @@ func IsAddressBlacklisted(statedb *StateDB, blacklistAddr *common.Address, addre
9499

95100
contract := *blacklistAddr
96101
disabledSlot := slotBlacklistContractMapping[DISABLED]
97-
disabled := statedb.GetState(contract, GetLocSimpleVariable(disabledSlot))
98-
if disabled.Big().Cmp(big.NewInt(1)) == 0 {
102+
disabledStateValue := statedb.GetState(contract, GetLocSimpleVariable(disabledSlot))
103+
104+
if disabledStateValue == valueOne {
99105
return false
100106
}
101107

102108
blacklistedSlot := slotBlacklistContractMapping[BLACKLISTED]
103109
valueLoc := GetLocMappingAtKey(address.Hash(), blacklistedSlot)
104-
blacklisted := statedb.GetState(contract, valueLoc)
105-
return blacklisted.Big().Cmp(big.NewInt(1)) == 0
110+
blacklistedStateValue := statedb.GetState(contract, valueLoc)
111+
return blacklistedStateValue == valueOne
106112
}
107113

108114
func GetSCValidators(statedb *StateDB) []common.Address {

core/state/statedb_utils_test.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package state
2+
3+
import (
4+
"math/big"
5+
"testing"
6+
7+
"github.com/ethereum/go-ethereum/common"
8+
"github.com/ethereum/go-ethereum/core/rawdb"
9+
)
10+
11+
func TestIsAddressBlacklisted(t *testing.T) {
12+
blackListContract := common.Address{0x11}
13+
14+
statedb, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
15+
16+
blacklistedAddress := common.BigToAddress(common.Big3)
17+
// Blacklist address 0x000..0003
18+
statedb.SetState(
19+
blackListContract,
20+
common.HexToHash("0x7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b"),
21+
common.BigToHash(common.Big1),
22+
)
23+
if !IsAddressBlacklisted(statedb, &blackListContract, &blacklistedAddress) {
24+
t.Fatalf("Expect address %s to be blacklisted", blacklistedAddress.String())
25+
}
26+
27+
notBlacklistedAddress := common.BigToAddress(big.NewInt(10))
28+
if IsAddressBlacklisted(statedb, &blackListContract, &notBlacklistedAddress) {
29+
t.Fatalf("Expect address %s to be not blacklisted", notBlacklistedAddress.String())
30+
}
31+
32+
statedb.SetState(blackListContract, common.BigToHash(common.Big2), common.BigToHash(common.Big1))
33+
if IsAddressBlacklisted(statedb, &blackListContract, &blacklistedAddress) {
34+
t.Fatalf("Expect address %s to be not blacklisted", blacklistedAddress.String())
35+
}
36+
}
37+
38+
func BenchmarkIsAddressBlacklisted(b *testing.B) {
39+
statedb, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
40+
blackListContract := common.Address{0x11}
41+
42+
queriedAddress := common.BigToAddress(common.Big3)
43+
44+
b.ResetTimer()
45+
b.ReportAllocs()
46+
for i := 0; i < b.N; i++ {
47+
IsAddressBlacklisted(statedb, &blackListContract, &queriedAddress)
48+
}
49+
}

0 commit comments

Comments
 (0)