6c1e7fec01
* evm: keeper statedb refactor * keeper: implement stateDB account, balance, nonce and suicide functions * keeper: implement stateDB code and iterator functions * keeper: implement stateDB log and preimage functions * update code to use CommitStateDB * tests updates * journal changes (wip) * cache fields * journal and logs * minor cleanup * evm: remove journal related changes * evm: delete empty account code and storage state * app, evm: transient store * ante, evm: refund gas transient * evm: remove transient keeper state fields * address comments from review * evm: undo revision change
243 lines
6.2 KiB
Go
243 lines
6.2 KiB
Go
package types
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
ethcmn "github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/cosmos/ethermint/crypto/ethsecp256k1"
|
|
)
|
|
|
|
type AccessListTestSuite struct {
|
|
suite.Suite
|
|
|
|
address ethcmn.Address
|
|
accessList *AccessListMappings
|
|
}
|
|
|
|
func (suite *AccessListTestSuite) SetupTest() {
|
|
privkey, err := ethsecp256k1.GenerateKey()
|
|
suite.Require().NoError(err)
|
|
|
|
suite.address = ethcmn.BytesToAddress(privkey.PubKey().Address().Bytes())
|
|
suite.accessList = NewAccessListMappings()
|
|
suite.accessList.addresses[suite.address] = 1
|
|
}
|
|
|
|
func TestAccessListTestSuite(t *testing.T) {
|
|
suite.Run(t, new(AccessListTestSuite))
|
|
}
|
|
|
|
func (suite *AccessListTestSuite) TestContainsAddress() {
|
|
found := suite.accessList.ContainsAddress(suite.address)
|
|
suite.Require().True(found)
|
|
}
|
|
|
|
func (suite *AccessListTestSuite) TestContains() {
|
|
testCases := []struct {
|
|
name string
|
|
malleate func()
|
|
expAddrPresent bool
|
|
expSlotPresent bool
|
|
}{
|
|
{"out of range", func() {}, true, false},
|
|
{
|
|
"address, no slots",
|
|
func() {
|
|
suite.accessList.addresses[suite.address] = -1
|
|
}, true, false,
|
|
},
|
|
{
|
|
"no address, no slots",
|
|
func() {
|
|
delete(suite.accessList.addresses, suite.address)
|
|
}, false, false,
|
|
},
|
|
{
|
|
"address, slot not present",
|
|
func() {
|
|
suite.accessList.addresses[suite.address] = 0
|
|
suite.accessList.slots = make([]map[ethcmn.Hash]struct{}, 1)
|
|
}, true, false,
|
|
},
|
|
{
|
|
"address, slots",
|
|
func() {
|
|
suite.accessList.addresses[suite.address] = 0
|
|
suite.accessList.slots = make([]map[ethcmn.Hash]struct{}, 1)
|
|
suite.accessList.slots[0] = make(map[ethcmn.Hash]struct{})
|
|
suite.accessList.slots[0][ethcmn.Hash{}] = struct{}{}
|
|
}, true, true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc.malleate()
|
|
|
|
addrPresent, slotPresent := suite.accessList.Contains(suite.address, ethcmn.Hash{})
|
|
|
|
suite.Require().Equal(tc.expAddrPresent, addrPresent, tc.name)
|
|
suite.Require().Equal(tc.expSlotPresent, slotPresent, tc.name)
|
|
}
|
|
}
|
|
|
|
func (suite *AccessListTestSuite) TestCopy() {
|
|
expAccessList := NewAccessListMappings()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
malleate func()
|
|
}{
|
|
{"empty", func() {
|
|
expAccessList.slots = make([]map[ethcmn.Hash]struct{}, 0)
|
|
}},
|
|
{
|
|
"single address", func() {
|
|
expAccessList = NewAccessListMappings()
|
|
expAccessList.slots = make([]map[ethcmn.Hash]struct{}, 0)
|
|
expAccessList.addresses[suite.address] = -1
|
|
},
|
|
},
|
|
{
|
|
"single address, single slot",
|
|
func() {
|
|
expAccessList = NewAccessListMappings()
|
|
expAccessList.addresses[suite.address] = 0
|
|
expAccessList.slots = make([]map[ethcmn.Hash]struct{}, 1)
|
|
expAccessList.slots[0] = make(map[ethcmn.Hash]struct{})
|
|
expAccessList.slots[0][ethcmn.Hash{}] = struct{}{}
|
|
},
|
|
},
|
|
{
|
|
"multiple addresses, single slot each",
|
|
func() {
|
|
expAccessList = NewAccessListMappings()
|
|
expAccessList.slots = make([]map[ethcmn.Hash]struct{}, 10)
|
|
for i := 0; i < 10; i++ {
|
|
expAccessList.addresses[ethcmn.BytesToAddress([]byte(fmt.Sprintf("%d", i)))] = i
|
|
expAccessList.slots[i] = make(map[ethcmn.Hash]struct{})
|
|
expAccessList.slots[i][ethcmn.BytesToHash([]byte(fmt.Sprintf("%d", i)))] = struct{}{}
|
|
}
|
|
},
|
|
},
|
|
{
|
|
"multiple addresses, multiple slots each",
|
|
func() {
|
|
expAccessList = NewAccessListMappings()
|
|
expAccessList.slots = make([]map[ethcmn.Hash]struct{}, 10)
|
|
for i := 0; i < 10; i++ {
|
|
expAccessList.addresses[ethcmn.BytesToAddress([]byte(fmt.Sprintf("%d", i)))] = i
|
|
expAccessList.slots[i] = make(map[ethcmn.Hash]struct{})
|
|
for j := 0; j < 10; j++ {
|
|
expAccessList.slots[i][ethcmn.BytesToHash([]byte(fmt.Sprintf("%d-%d", i, j)))] = struct{}{}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc.malleate()
|
|
|
|
accessList := expAccessList.Copy()
|
|
suite.Require().EqualValues(expAccessList, accessList, tc.name)
|
|
}
|
|
}
|
|
|
|
func (suite *AccessListTestSuite) TestAddAddress() {
|
|
testCases := []struct {
|
|
name string
|
|
address ethcmn.Address
|
|
ok bool
|
|
}{
|
|
{"already present", suite.address, false},
|
|
{"ok", ethcmn.Address{}, true},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
ok := suite.accessList.AddAddress(tc.address)
|
|
suite.Require().Equal(tc.ok, ok, tc.name)
|
|
}
|
|
}
|
|
|
|
func (suite *AccessListTestSuite) TestAddSlot() {
|
|
testCases := []struct {
|
|
name string
|
|
malleate func()
|
|
expAddrChange bool
|
|
expSlotChange bool
|
|
}{
|
|
{"out of range", func() {}, false, false},
|
|
{
|
|
"address not present added, slot added",
|
|
func() {
|
|
delete(suite.accessList.addresses, suite.address)
|
|
}, true, true,
|
|
},
|
|
{
|
|
"address present, slot not present added",
|
|
func() {
|
|
suite.accessList.addresses[suite.address] = 0
|
|
suite.accessList.slots = make([]map[ethcmn.Hash]struct{}, 1)
|
|
suite.accessList.slots[0] = make(map[ethcmn.Hash]struct{})
|
|
}, false, true,
|
|
},
|
|
{
|
|
"address present, slot present",
|
|
func() {
|
|
suite.accessList.addresses[suite.address] = 0
|
|
suite.accessList.slots = make([]map[ethcmn.Hash]struct{}, 1)
|
|
suite.accessList.slots[0] = make(map[ethcmn.Hash]struct{})
|
|
suite.accessList.slots[0][ethcmn.Hash{}] = struct{}{}
|
|
}, false, false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc.malleate()
|
|
|
|
addrChange, slotChange := suite.accessList.AddSlot(suite.address, ethcmn.Hash{})
|
|
suite.Require().Equal(tc.expAddrChange, addrChange, tc.name)
|
|
suite.Require().Equal(tc.expSlotChange, slotChange, tc.name)
|
|
}
|
|
}
|
|
|
|
func (suite *AccessListTestSuite) TestDeleteSlot() {
|
|
testCases := []struct {
|
|
name string
|
|
malleate func()
|
|
expPanic bool
|
|
}{
|
|
{"panics, out of range", func() {}, true},
|
|
{"panics, address not found", func() {
|
|
delete(suite.accessList.addresses, suite.address)
|
|
}, true},
|
|
{
|
|
"single slot present",
|
|
func() {
|
|
suite.accessList.addresses[suite.address] = 0
|
|
suite.accessList.slots = make([]map[ethcmn.Hash]struct{}, 1)
|
|
suite.accessList.slots[0] = make(map[ethcmn.Hash]struct{})
|
|
suite.accessList.slots[0][ethcmn.Hash{}] = struct{}{}
|
|
}, false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc.malleate()
|
|
|
|
if tc.expPanic {
|
|
suite.Require().Panics(func() {
|
|
suite.accessList.DeleteSlot(suite.address, ethcmn.Hash{})
|
|
}, tc.name)
|
|
} else {
|
|
suite.Require().NotPanics(func() {
|
|
suite.accessList.DeleteSlot(suite.address, ethcmn.Hash{})
|
|
}, tc.name)
|
|
}
|
|
}
|
|
}
|