Skip to content

Commit

Permalink
Replace common.Address map keys with common.AddresBytes
Browse files Browse the repository at this point in the history
  • Loading branch information
jdowning100 committed Jun 6, 2023
1 parent e0f9af2 commit 0bffbcb
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 94 deletions.
40 changes: 40 additions & 0 deletions common/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package common

import (
"database/sql/driver"
"encoding/hex"
"encoding/json"
"fmt"
"reflect"
Expand All @@ -11,6 +12,7 @@ import (

"github.com/dominant-strategies/go-quai/common/hexutil"
"github.com/dominant-strategies/go-quai/rlp"
"golang.org/x/crypto/sha3"
)

type Address struct {
Expand Down Expand Up @@ -231,3 +233,41 @@ func IsHexAddress(s string) bool {
}
return len(s) == 2*AddressLength && isHex(s)
}

// Hex returns a hex string representation of the address.
func (a AddressBytes) Hex() string {
return string(a.checksumHex())
}

// String implements fmt.Stringer.
func (a AddressBytes) String() string {
return a.Hex()
}

func (a AddressBytes) checksumHex() []byte {
buf := a.hex()

// compute checksum
sha := sha3.NewLegacyKeccak256()
sha.Write(buf[2:])
hash := sha.Sum(nil)
for i := 2; i < len(buf); i++ {
hashByte := hash[(i-2)/2]
if i%2 == 0 {
hashByte = hashByte >> 4
} else {
hashByte &= 0xf
}
if buf[i] > '9' && hashByte > 7 {
buf[i] -= 32
}
}
return buf[:]
}

func (a AddressBytes) hex() []byte {
var buf [len(a)*2 + 2]byte
copy(buf[:2], "0x")
hex.Encode(buf[2:], a[:])
return buf[:]
}
16 changes: 8 additions & 8 deletions core/state/access_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ import (
)

type accessList struct {
addresses map[common.Address]int
addresses map[common.AddressBytes]int
slots []map[common.Hash]struct{}
}

// ContainsAddress returns true if the address is in the access list.
func (al *accessList) ContainsAddress(address common.Address) bool {
func (al *accessList) ContainsAddress(address common.AddressBytes) bool {
_, ok := al.addresses[address]
return ok
}

// Contains checks if a slot within an account is present in the access list, returning
// separate flags for the presence of the account and the slot respectively.
func (al *accessList) Contains(address common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
func (al *accessList) Contains(address common.AddressBytes, slot common.Hash) (addressPresent bool, slotPresent bool) {
idx, ok := al.addresses[address]
if !ok {
// no such address (and hence zero slots)
Expand All @@ -50,7 +50,7 @@ func (al *accessList) Contains(address common.Address, slot common.Hash) (addres
// newAccessList creates a new accessList.
func newAccessList() *accessList {
return &accessList{
addresses: make(map[common.Address]int),
addresses: make(map[common.AddressBytes]int),
}
}

Expand All @@ -73,7 +73,7 @@ func (a *accessList) Copy() *accessList {

// AddAddress adds an address to the access list, and returns 'true' if the operation
// caused a change (addr was not previously in the list).
func (al *accessList) AddAddress(address common.Address) bool {
func (al *accessList) AddAddress(address common.AddressBytes) bool {
if _, present := al.addresses[address]; present {
return false
}
Expand All @@ -86,7 +86,7 @@ func (al *accessList) AddAddress(address common.Address) bool {
// - address added
// - slot added
// For any 'true' value returned, a corresponding journal entry must be made.
func (al *accessList) AddSlot(address common.Address, slot common.Hash) (addrChange bool, slotChange bool) {
func (al *accessList) AddSlot(address common.AddressBytes, slot common.Hash) (addrChange bool, slotChange bool) {
idx, addrPresent := al.addresses[address]
if !addrPresent || idx == -1 {
// Address not present, or addr present but no slots there
Expand All @@ -110,7 +110,7 @@ func (al *accessList) AddSlot(address common.Address, slot common.Hash) (addrCha
// This operation needs to be performed in the same order as the addition happened.
// This method is meant to be used by the journal, which maintains ordering of
// operations.
func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
func (al *accessList) DeleteSlot(address common.AddressBytes, slot common.Hash) {
idx, addrOk := al.addresses[address]
// There are two ways this can fail
if !addrOk {
Expand All @@ -131,6 +131,6 @@ func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
// needs to be performed in the same order as the addition happened.
// This method is meant to be used by the journal, which maintains ordering of
// operations.
func (al *accessList) DeleteAddress(address common.Address) {
func (al *accessList) DeleteAddress(address common.AddressBytes) {
delete(al.addresses, address)
}
4 changes: 2 additions & 2 deletions core/state/journal.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@ type (
}
// Changes to the access list
accessListAddAccountChange struct {
address *common.Address
address *common.AddressBytes
}
accessListAddSlotChange struct {
address *common.Address
address *common.AddressBytes
slot *common.Hash
}
)
Expand Down
16 changes: 9 additions & 7 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -992,35 +992,37 @@ func (s *StateDB) PrepareAccessList(sender common.Address, dst *common.Address,

// AddAddressToAccessList adds the given address to the access list
func (s *StateDB) AddAddressToAccessList(addr common.Address) {
if s.accessList.AddAddress(addr) {
s.journal.append(accessListAddAccountChange{&addr})
addrBytes := addr.Bytes20()
if s.accessList.AddAddress(addrBytes) {
s.journal.append(accessListAddAccountChange{&addrBytes})
}
}

// AddSlotToAccessList adds the given (address, slot)-tuple to the access list
func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {
addrMod, slotMod := s.accessList.AddSlot(addr, slot)
addrBytes := addr.Bytes20()
addrMod, slotMod := s.accessList.AddSlot(addrBytes, slot)
if addrMod {
// In practice, this should not happen, since there is no way to enter the
// scope of 'address' without having the 'address' become already added
// to the access list (via call-variant, create, etc).
// Better safe than sorry, though
s.journal.append(accessListAddAccountChange{&addr})
s.journal.append(accessListAddAccountChange{&addrBytes})
}
if slotMod {
s.journal.append(accessListAddSlotChange{
address: &addr,
address: &addrBytes,
slot: &slot,
})
}
}

// AddressInAccessList returns true if the given address is in the access list.
func (s *StateDB) AddressInAccessList(addr common.Address) bool {
return s.accessList.ContainsAddress(addr)
return s.accessList.ContainsAddress(addr.Bytes20())
}

// SlotInAccessList returns true if the given (address, slot)-tuple is in the access list.
func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
return s.accessList.Contains(addr, slot)
return s.accessList.Contains(addr.Bytes20(), slot)
}
4 changes: 2 additions & 2 deletions core/types/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
signer := LatestSignerForChainID(common.Big1)

// Generate a batch of transactions with overlapping values, but shifted nonces
groups := map[common.Address]Transactions{}
groups := map[common.AddressBytes]Transactions{}
expectedCount := 0
for start, key := range keys {
addr := crypto.PubkeyToAddress(key.PublicKey)
Expand Down Expand Up @@ -271,7 +271,7 @@ func TestTransactionTimeSort(t *testing.T) {
keys[i], _ = crypto.GenerateKey()
}
// Generate a batch of transactions with overlapping prices, but different creation times
groups := map[common.Address]Transactions{}
groups := map[common.AddressBytes]Transactions{}
for start, key := range keys {
addr := crypto.PubkeyToAddress(key.PublicKey)

Expand Down
28 changes: 14 additions & 14 deletions core/vm/access_list_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,22 @@ import (

// accessList is an accumulator for the set of accounts and storage slots an EVM
// contract execution touches.
type accessList map[common.Address]accessListSlots
type accessList map[common.AddressBytes]accessListSlots

// accessListSlots is an accumulator for the set of storage slots within a single
// contract that an EVM contract execution touches.
type accessListSlots map[common.Hash]struct{}

// newAccessList creates a new accessList.
func newAccessList() accessList {
return make(map[common.Address]accessListSlots)
return make(map[common.AddressBytes]accessListSlots)
}

// addAddress adds an address to the accesslist.
func (al accessList) addAddress(address common.Address) {
// Set address if not previously present
if _, present := al[address]; !present {
al[address] = make(map[common.Hash]struct{})
if _, present := al[address.Bytes20()]; !present {
al[address.Bytes20()] = make(map[common.Hash]struct{})
}
}

Expand All @@ -51,7 +51,7 @@ func (al accessList) addSlot(address common.Address, slot common.Hash) {
al.addAddress(address)

// Set the slot on the surely existent storage set
al[address][slot] = struct{}{}
al[address.Bytes20()][slot] = struct{}{}
}

// equal checks if the content of the current access list is the same as the
Expand Down Expand Up @@ -96,7 +96,7 @@ func (al accessList) equal(other accessList) bool {
func (al accessList) accessList() types.AccessList {
acl := make(types.AccessList, 0, len(al))
for addr, slots := range al {
tuple := types.AccessTuple{Address: addr, StorageKeys: []common.Hash{}}
tuple := types.AccessTuple{Address: common.Bytes20ToAddress(addr), StorageKeys: []common.Hash{}}
for slot := range slots {
tuple.StorageKeys = append(tuple.StorageKeys, slot)
}
Expand All @@ -108,23 +108,23 @@ func (al accessList) accessList() types.AccessList {
// AccessListTracer is a tracer that accumulates touched accounts and storage
// slots into an internal set.
type AccessListTracer struct {
excl map[common.Address]struct{} // Set of account to exclude from the list
list accessList // Set of accounts and storage slots touched
excl map[common.AddressBytes]struct{} // Set of account to exclude from the list
list accessList // Set of accounts and storage slots touched
}

// NewAccessListTracer creates a new tracer that can generate AccessLists.
// An optional AccessList can be specified to occupy slots and addresses in
// the resulting accesslist.
func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompiles []common.Address) *AccessListTracer {
excl := map[common.Address]struct{}{
from: {}, to: {},
excl := map[common.AddressBytes]struct{}{
from.Bytes20(): {}, to.Bytes20(): {},
}
for _, addr := range precompiles {
excl[addr] = struct{}{}
excl[addr.Bytes20()] = struct{}{}
}
list := newAccessList()
for _, al := range acl {
if _, ok := excl[al.Address]; !ok {
if _, ok := excl[al.Address.Bytes20()]; !ok {
list.addAddress(al.Address)
}
for _, slot := range al.StorageKeys {
Expand All @@ -149,13 +149,13 @@ func (a *AccessListTracer) CaptureState(env *EVM, pc uint64, op OpCode, gas, cos
}
if (op == EXTCODECOPY || op == EXTCODEHASH || op == EXTCODESIZE || op == BALANCE || op == SELFDESTRUCT) && stack.len() >= 1 {
addr := common.Bytes20ToAddress(stack.data[stack.len()-1].Bytes20())
if _, ok := a.excl[addr]; !ok {
if _, ok := a.excl[addr.Bytes20()]; !ok {
a.list.addAddress(addr)
}
}
if (op == DELEGATECALL || op == CALL || op == STATICCALL || op == CALLCODE) && stack.len() >= 5 {
addr := common.Bytes20ToAddress(stack.data[stack.len()-2].Bytes20())
if _, ok := a.excl[addr]; !ok {
if _, ok := a.excl[addr.Bytes20()]; !ok {
a.list.addAddress(addr)
}
}
Expand Down
42 changes: 21 additions & 21 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,33 @@ type PrecompiledContract interface {
Run(input []byte) ([]byte, error) // Run runs the precompiled contract
}

var TranslatedAddresses = map[common.Address]int{
common.BytesToAddress([]byte{1}): 0,
common.BytesToAddress([]byte{2}): 1,
common.BytesToAddress([]byte{3}): 2,
common.BytesToAddress([]byte{4}): 3,
common.BytesToAddress([]byte{5}): 4,
common.BytesToAddress([]byte{6}): 5,
common.BytesToAddress([]byte{7}): 6,
common.BytesToAddress([]byte{8}): 7,
common.BytesToAddress([]byte{9}): 8,
var TranslatedAddresses = map[common.AddressBytes]int{
common.AddressBytes([20]byte{1}): 0,
common.AddressBytes([20]byte{2}): 1,
common.AddressBytes([20]byte{3}): 2,
common.AddressBytes([20]byte{4}): 3,
common.AddressBytes([20]byte{5}): 4,
common.AddressBytes([20]byte{6}): 5,
common.AddressBytes([20]byte{7}): 6,
common.AddressBytes([20]byte{8}): 7,
common.AddressBytes([20]byte{9}): 8,
}

var (
PrecompiledContracts map[common.Address]PrecompiledContract = make(map[common.Address]PrecompiledContract)
PrecompiledAddresses map[string][]common.Address = make(map[string][]common.Address)
PrecompiledContracts map[common.AddressBytes]PrecompiledContract = make(map[common.AddressBytes]PrecompiledContract)
PrecompiledAddresses map[string][]common.Address = make(map[string][]common.Address)
)

func InitializePrecompiles() {
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][0]] = &ecrecover{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][1]] = &sha256hash{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][2]] = &ripemd160hash{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][3]] = &dataCopy{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][4]] = &bigModExp{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][5]] = &bn256Add{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][6]] = &bn256ScalarMul{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][7]] = &bn256Pairing{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][8]] = &blake2F{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][0].Bytes20()] = &ecrecover{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][1].Bytes20()] = &sha256hash{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][2].Bytes20()] = &ripemd160hash{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][3].Bytes20()] = &dataCopy{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][4].Bytes20()] = &bigModExp{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][5].Bytes20()] = &bn256Add{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][6].Bytes20()] = &bn256ScalarMul{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][7].Bytes20()] = &bn256Pairing{}
PrecompiledContracts[PrecompiledAddresses[common.NodeLocation.Name()][8].Bytes20()] = &blake2F{}
}

func init() {
Expand Down
Loading

0 comments on commit 0bffbcb

Please sign in to comment.