@@ -97,6 +97,9 @@ type StateDB struct {
97
97
// Per-transaction access list
98
98
accessList * accessList
99
99
100
+ // Transient storage
101
+ transientStorage transientStorage
102
+
100
103
// Journal of state modifications. This is the backbone of
101
104
// Snapshot and RevertToSnapshot.
102
105
journal * journal
@@ -140,6 +143,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
140
143
preimages : make (map [common.Hash ][]byte ),
141
144
journal : newJournal (),
142
145
accessList : newAccessList (),
146
+ transientStorage : newTransientStorage (),
143
147
hasher : crypto .NewKeccakState (),
144
148
}
145
149
if sdb .snaps != nil {
@@ -472,6 +476,35 @@ func (s *StateDB) Suicide(addr common.Address) bool {
472
476
return true
473
477
}
474
478
479
+ // SetTransientState sets transient storage for a given account. It
480
+ // adds the change to the journal so that it can be rolled back
481
+ // to its previous value if there is a revert.
482
+ func (s * StateDB ) SetTransientState (addr common.Address , key , value common.Hash ) {
483
+ prev := s .GetTransientState (addr , key )
484
+ if prev == value {
485
+ return
486
+ }
487
+
488
+ s .journal .append (transientStorageChange {
489
+ account : & addr ,
490
+ key : key ,
491
+ prevalue : prev ,
492
+ })
493
+
494
+ s .setTransientState (addr , key , value )
495
+ }
496
+
497
+ // setTransientState is a lower level setter for transient storage. It
498
+ // is called during a revert to prevent modifications to the journal.
499
+ func (s * StateDB ) setTransientState (addr common.Address , key , value common.Hash ) {
500
+ s .transientStorage .Set (addr , key , value )
501
+ }
502
+
503
+ // GetTransientState gets transient storage for a given account.
504
+ func (s * StateDB ) GetTransientState (addr common.Address , key common.Hash ) common.Hash {
505
+ return s .transientStorage .Get (addr , key )
506
+ }
507
+
475
508
//
476
509
// Setting, updating & deleting state object methods.
477
510
//
@@ -635,8 +668,8 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
635
668
// CreateAccount is called during the EVM CREATE operation. The situation might arise that
636
669
// a contract does the following:
637
670
//
638
- // 1. sends funds to sha(account ++ (nonce + 1))
639
- // 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
671
+ // 1. sends funds to sha(account ++ (nonce + 1))
672
+ // 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
640
673
//
641
674
// Carrying over the balance ensures that Ether doesn't disappear.
642
675
func (s * StateDB ) CreateAccount (addr common.Address ) {
@@ -741,6 +774,8 @@ func (s *StateDB) Copy() *StateDB {
741
774
// to not blow up if we ever decide copy it in the middle of a transaction
742
775
state .accessList = s .accessList .Copy ()
743
776
777
+ state .transientStorage = s .transientStorage .Copy ()
778
+
744
779
// If there's a prefetcher running, make an inactive copy of it that can
745
780
// only access data but does not actively preload (since the user will not
746
781
// know that they need to explicitly terminate an active copy).
@@ -913,9 +948,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
913
948
return s .trie .Hash ()
914
949
}
915
950
916
- // Prepare sets the current transaction hash and index which are
917
- // used when the EVM emits new state logs.
918
- func (s * StateDB ) Prepare (thash common.Hash , ti int ) {
951
+ // SetTxContext sets the current transaction hash and index which are
952
+ // used when the EVM emits new state logs. It should be invoked before
953
+ // transaction execution.
954
+ func (s * StateDB ) SetTxContext (thash common.Hash , ti int ) {
919
955
s .thash = thash
920
956
s .txIndex = ti
921
957
s .accessList = newAccessList ()
@@ -1018,34 +1054,45 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
1018
1054
return root , err
1019
1055
}
1020
1056
1021
- // PrepareAccessList handles the preparatory steps for executing a state transition with
1022
- // regards to EIP-2929, EIP-2930 and EIP-3651:
1057
+ // Prepare handles the preparatory steps for executing a state transition with.
1058
+ // This method must be invoked before state transition.
1023
1059
//
1060
+ // Berlin fork:
1024
1061
// - Add sender to access list (2929)
1025
1062
// - Add destination to access list (2929)
1026
1063
// - Add precompiles to access list (2929)
1027
1064
// - Add the contents of the optional tx access list (2930)
1028
- // - Add coinbase to access list (3651)
1029
1065
//
1030
- // This method should only be called if Berlin/2929+2930 is applicable at the current number.
1031
- func (s * StateDB ) PrepareAccessList (rules params.Rules , sender , coinbase common.Address , dst * common.Address , precompiles []common.Address , list types.AccessList ) {
1032
- s .AddAddressToAccessList (sender )
1033
- if dst != nil {
1034
- s .AddAddressToAccessList (* dst )
1035
- // If it's a create-tx, the destination will be added inside evm.create
1036
- }
1037
- for _ , addr := range precompiles {
1038
- s .AddAddressToAccessList (addr )
1039
- }
1040
- for _ , el := range list {
1041
- s .AddAddressToAccessList (el .Address )
1042
- for _ , key := range el .StorageKeys {
1043
- s .AddSlotToAccessList (el .Address , key )
1066
+ // Potential EIPs:
1067
+ // - Reset access list (Berlin)
1068
+ // - Add coinbase to access list (EIP-3651)
1069
+ // - Reset transient storage (EIP-1153)
1070
+ func (s * StateDB ) Prepare (rules params.Rules , sender , coinbase common.Address , dst * common.Address , precompiles []common.Address , list types.AccessList ) {
1071
+ if rules .IsBerlin {
1072
+ // Clear out any leftover from previous executions
1073
+ al := newAccessList ()
1074
+ s .accessList = al
1075
+
1076
+ al .AddAddress (sender )
1077
+ if dst != nil {
1078
+ al .AddAddress (* dst )
1079
+ // If it's a create-tx, the destination will be added inside evm.create
1080
+ }
1081
+ for _ , addr := range precompiles {
1082
+ al .AddAddress (addr )
1083
+ }
1084
+ for _ , el := range list {
1085
+ al .AddAddress (el .Address )
1086
+ for _ , key := range el .StorageKeys {
1087
+ al .AddSlot (el .Address , key )
1088
+ }
1089
+ }
1090
+ if rules .IsShanghai { // EIP-3651: warm coinbase
1091
+ al .AddAddress (coinbase )
1044
1092
}
1045
1093
}
1046
- if rules .IsShanghai { // EIP-3651: warm coinbase
1047
- s .AddAddressToAccessList (coinbase )
1048
- }
1094
+ // Reset transient storage at the beginning of transaction execution
1095
+ s .transientStorage = newTransientStorage ()
1049
1096
}
1050
1097
1051
1098
// AddAddressToAccessList adds the given address to the access list
0 commit comments