Skip to content

Commit 78bad64

Browse files
authored
Merge pull request #519 from gzliudan/eip2929
implement EIP-2929 for EIP-1559
2 parents 3b9fc51 + 8568af0 commit 78bad64

20 files changed

+948
-47
lines changed

common/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var BerlinBlock = big.NewInt(9999999999)
5151
var LondonBlock = big.NewInt(9999999999)
5252
var MergeBlock = big.NewInt(9999999999)
5353
var ShanghaiBlock = big.NewInt(9999999999)
54+
var Eip1559Block = big.NewInt(9999999999)
5455

5556
var TIPXDCXTestnet = big.NewInt(38383838)
5657
var IsTestnet bool = false

common/constants/constants.go.devnet

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ var TIPXDCXCancellationFee = big.NewInt(225000)
4747
var TIPXDCXCancellationFeeTestnet = big.NewInt(225000)
4848
var TIPXDCXMinerDisable = big.NewInt(15894900)
4949
var TIPXDCXReceiverDisable = big.NewInt(18018000)
50-
var BerlinBlock = big.NewInt(9999999999)
51-
var LondonBlock = big.NewInt(9999999999)
52-
var MergeBlock = big.NewInt(9999999999)
50+
var BerlinBlock = big.NewInt(16832700)
51+
var LondonBlock = big.NewInt(16832700)
52+
var MergeBlock = big.NewInt(16832700)
5353
var ShanghaiBlock = big.NewInt(16832700)
54+
var Eip1559Block = big.NewInt(9999999999)
5455

5556
var TIPXDCXTestnet = big.NewInt(0)
5657
var IsTestnet bool = false

common/constants/constants.go.testnet

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ var TIPXDCXCancellationFee = big.NewInt(23779191)
4747
var TIPXDCXCancellationFeeTestnet = big.NewInt(23779191)
4848
var TIPXDCXMinerDisable = big.NewInt(61290000) // Target 31st March 2024
4949
var TIPXDCXReceiverDisable = big.NewInt(9999999999)
50-
var BerlinBlock = big.NewInt(9999999999)
51-
var LondonBlock = big.NewInt(9999999999)
52-
var MergeBlock = big.NewInt(9999999999)
50+
var BerlinBlock = big.NewInt(61290000)
51+
var LondonBlock = big.NewInt(61290000)
52+
var MergeBlock = big.NewInt(61290000)
5353
var ShanghaiBlock = big.NewInt(61290000) // Target 31st March 2024
54+
var Eip1559Block = big.NewInt(9999999999)
5455

5556
var TIPXDCXTestnet = big.NewInt(23779191)
5657
var IsTestnet bool = false

core/state/access_list.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Copyright 2020 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package state
18+
19+
import (
20+
"github.com/XinFinOrg/XDPoSChain/common"
21+
)
22+
23+
type accessList struct {
24+
addresses map[common.Address]int
25+
slots []map[common.Hash]struct{}
26+
}
27+
28+
// ContainsAddress returns true if the address is in the access list.
29+
func (al *accessList) ContainsAddress(address common.Address) bool {
30+
_, ok := al.addresses[address]
31+
return ok
32+
}
33+
34+
// Contains checks if a slot within an account is present in the access list, returning
35+
// separate flags for the presence of the account and the slot respectively.
36+
func (al *accessList) Contains(address common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
37+
idx, ok := al.addresses[address]
38+
if !ok {
39+
// no such address (and hence zero slots)
40+
return false, false
41+
}
42+
if idx == -1 {
43+
// address yes, but no slots
44+
return true, false
45+
}
46+
_, slotPresent = al.slots[idx][slot]
47+
return true, slotPresent
48+
}
49+
50+
// newAccessList creates a new accessList.
51+
func newAccessList() *accessList {
52+
return &accessList{
53+
addresses: make(map[common.Address]int),
54+
}
55+
}
56+
57+
// Copy creates an independent copy of an accessList.
58+
func (a *accessList) Copy() *accessList {
59+
cp := newAccessList()
60+
for k, v := range a.addresses {
61+
cp.addresses[k] = v
62+
}
63+
cp.slots = make([]map[common.Hash]struct{}, len(a.slots))
64+
for i, slotMap := range a.slots {
65+
newSlotmap := make(map[common.Hash]struct{}, len(slotMap))
66+
for k := range slotMap {
67+
newSlotmap[k] = struct{}{}
68+
}
69+
cp.slots[i] = newSlotmap
70+
}
71+
return cp
72+
}
73+
74+
// AddAddress adds an address to the access list, and returns 'true' if the operation
75+
// caused a change (addr was not previously in the list).
76+
func (al *accessList) AddAddress(address common.Address) bool {
77+
if _, present := al.addresses[address]; present {
78+
return false
79+
}
80+
al.addresses[address] = -1
81+
return true
82+
}
83+
84+
// AddSlot adds the specified (addr, slot) combo to the access list.
85+
// Return values are:
86+
// - address added
87+
// - slot added
88+
// For any 'true' value returned, a corresponding journal entry must be made.
89+
func (al *accessList) AddSlot(address common.Address, slot common.Hash) (addrChange bool, slotChange bool) {
90+
idx, addrPresent := al.addresses[address]
91+
if !addrPresent || idx == -1 {
92+
// Address not present, or addr present but no slots there
93+
al.addresses[address] = len(al.slots)
94+
slotmap := map[common.Hash]struct{}{slot: {}}
95+
al.slots = append(al.slots, slotmap)
96+
return !addrPresent, true
97+
}
98+
// There is already an (address,slot) mapping
99+
slotmap := al.slots[idx]
100+
if _, ok := slotmap[slot]; !ok {
101+
slotmap[slot] = struct{}{}
102+
// Journal add slot change
103+
return false, true
104+
}
105+
// No changes required
106+
return false, false
107+
}
108+
109+
// DeleteSlot removes an (address, slot)-tuple from the access list.
110+
// This operation needs to be performed in the same order as the addition happened.
111+
// This method is meant to be used by the journal, which maintains ordering of
112+
// operations.
113+
func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
114+
idx, addrOk := al.addresses[address]
115+
// There are two ways this can fail
116+
if !addrOk {
117+
panic("reverting slot change, address not present in list")
118+
}
119+
slotmap := al.slots[idx]
120+
delete(slotmap, slot)
121+
// If that was the last (first) slot, remove it
122+
// Since additions and rollbacks are always performed in order,
123+
// we can delete the item without worrying about screwing up later indices
124+
if len(slotmap) == 0 {
125+
al.slots = al.slots[:idx]
126+
al.addresses[address] = -1
127+
}
128+
}
129+
130+
// DeleteAddress removes an address from the access list. This operation
131+
// needs to be performed in the same order as the addition happened.
132+
// This method is meant to be used by the journal, which maintains ordering of
133+
// operations.
134+
func (al *accessList) DeleteAddress(address common.Address) {
135+
delete(al.addresses, address)
136+
}

core/state/journal.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ type journalEntry interface {
2828

2929
type journal []journalEntry
3030

31+
// length returns the current number of entries in the journal.
32+
func (j *journal) length() int {
33+
return len(*j)
34+
}
35+
3136
type (
3237
// Changes to the account trie.
3338
createObjectChange struct {
@@ -75,6 +80,14 @@ type (
7580
prev bool
7681
prevDirty bool
7782
}
83+
// Changes to the access list
84+
accessListAddAccountChange struct {
85+
address *common.Address
86+
}
87+
accessListAddSlotChange struct {
88+
address *common.Address
89+
slot *common.Hash
90+
}
7891
)
7992

8093
func (ch createObjectChange) undo(s *StateDB) {
@@ -138,3 +151,20 @@ func (ch addLogChange) undo(s *StateDB) {
138151
func (ch addPreimageChange) undo(s *StateDB) {
139152
delete(s.preimages, ch.hash)
140153
}
154+
155+
func (ch accessListAddAccountChange) undo(s *StateDB) {
156+
/*
157+
One important invariant here, is that whenever a (addr, slot) is added, if the
158+
addr is not already present, the add causes two journal entries:
159+
- one for the address,
160+
- one for the (address,slot)
161+
Therefore, when unrolling the change, we can always blindly delete the
162+
(addr) at this point, since no storage adds can remain when come upon
163+
a single (addr) change.
164+
*/
165+
s.accessList.DeleteAddress(*ch.address)
166+
}
167+
168+
func (ch accessListAddSlotChange) undo(s *StateDB) {
169+
s.accessList.DeleteSlot(*ch.address, *ch.slot)
170+
}

core/state/statedb.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ type StateDB struct {
7474

7575
preimages map[common.Hash][]byte
7676

77+
// Per-transaction access list
78+
accessList *accessList
79+
7780
// Journal of state modifications. This is the backbone of
7881
// Snapshot and RevertToSnapshot.
7982
journal journal
@@ -121,6 +124,7 @@ func New(root common.Hash, db Database) (*StateDB, error) {
121124
stateObjectsDirty: make(map[common.Address]struct{}),
122125
logs: make(map[common.Hash][]*types.Log),
123126
preimages: make(map[common.Hash][]byte),
127+
accessList: newAccessList(),
124128
}, nil
125129
}
126130

@@ -152,6 +156,7 @@ func (self *StateDB) Reset(root common.Hash) error {
152156
self.logSize = 0
153157
self.preimages = make(map[common.Hash][]byte)
154158
self.clearJournalAndRefund()
159+
self.accessList = newAccessList()
155160
return nil
156161
}
157162

@@ -568,6 +573,12 @@ func (self *StateDB) Copy() *StateDB {
568573
for hash, preimage := range self.preimages {
569574
state.preimages[hash] = preimage
570575
}
576+
// Do we need to copy the access list? In practice: No. At the start of a
577+
// transaction, the access list is empty. In practice, we only ever copy state
578+
// _between_ transactions/blocks, never in the middle of a transaction.
579+
// However, it doesn't cost us much to copy an empty list, so we do it anyway
580+
// to not blow up if we ever decide copy it in the middle of a transaction
581+
state.accessList = self.accessList.Copy()
571582
return state
572583
}
573584

@@ -635,6 +646,7 @@ func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) {
635646
self.thash = thash
636647
self.bhash = bhash
637648
self.txIndex = ti
649+
self.accessList = newAccessList()
638650
}
639651

640652
// DeleteSuicides flags the suicided objects for deletion so that it
@@ -709,6 +721,41 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
709721
return root, err
710722
}
711723

724+
// AddAddressToAccessList adds the given address to the access list
725+
func (s *StateDB) AddAddressToAccessList(addr common.Address) {
726+
if s.accessList.AddAddress(addr) {
727+
s.journal = append(s.journal, accessListAddAccountChange{&addr})
728+
}
729+
}
730+
731+
// AddSlotToAccessList adds the given (address, slot)-tuple to the access list
732+
func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {
733+
addrMod, slotMod := s.accessList.AddSlot(addr, slot)
734+
if addrMod {
735+
// In practice, this should not happen, since there is no way to enter the
736+
// scope of 'address' without having the 'address' become already added
737+
// to the access list (via call-variant, create, etc).
738+
// Better safe than sorry, though
739+
s.journal = append(s.journal, accessListAddAccountChange{&addr})
740+
}
741+
if slotMod {
742+
s.journal = append(s.journal, accessListAddSlotChange{
743+
address: &addr,
744+
slot: &slot,
745+
})
746+
}
747+
}
748+
749+
// AddressInAccessList returns true if the given address is in the access list.
750+
func (s *StateDB) AddressInAccessList(addr common.Address) bool {
751+
return s.accessList.ContainsAddress(addr)
752+
}
753+
754+
// SlotInAccessList returns true if the given (address, slot)-tuple is in the access list.
755+
func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
756+
return s.accessList.Contains(addr, slot)
757+
}
758+
712759
func (s *StateDB) GetOwner(candidate common.Address) common.Address {
713760
slot := slotValidatorMapping["validatorsState"]
714761
// validatorsState[_candidate].owner;

0 commit comments

Comments
 (0)