Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
8fa24ff0
Commit
8fa24ff0
authored
Sep 20, 2021
by
George Hotz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add state object
parent
d01b4d7b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
182 additions
and
2 deletions
+182
-2
state_object.go
minigeth/core/state/state_object.go
+119
-0
statedb.go
minigeth/core/state/statedb.go
+63
-2
No files found.
minigeth/core/state/state_object.go
0 → 100644
View file @
8fa24ff0
package
state
import
(
"bytes"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
var
emptyRoot
=
common
.
HexToHash
(
"56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
)
var
emptyCodeHash
=
crypto
.
Keccak256
(
nil
)
type
Code
[]
byte
func
(
c
Code
)
String
()
string
{
return
string
(
c
)
//strings.Join(Disassemble(c), " ")
}
type
Storage
map
[
common
.
Hash
]
common
.
Hash
func
(
s
Storage
)
String
()
(
str
string
)
{
for
key
,
value
:=
range
s
{
str
+=
fmt
.
Sprintf
(
"%X : %X
\n
"
,
key
,
value
)
}
return
}
func
(
s
Storage
)
Copy
()
Storage
{
cpy
:=
make
(
Storage
)
for
key
,
value
:=
range
s
{
cpy
[
key
]
=
value
}
return
cpy
}
// stateObject represents an Ethereum account which is being modified.
//
// The usage pattern is as follows:
// First you need to obtain a state object.
// Account values can be accessed and modified through the object.
// Finally, call CommitTrie to write the modified storage trie into a database.
type
stateObject
struct
{
address
common
.
Address
addrHash
common
.
Hash
// hash of ethereum address of the account
data
Account
db
*
StateDB
// DB error.
// State objects are used by the consensus core and VM which are
// unable to deal with database-level errors. Any error that occurs
// during a database read is memoized here and will eventually be returned
// by StateDB.Commit.
dbErr
error
// Write caches.
//trie Trie // storage trie, which becomes non-nil on first access
code
Code
// contract bytecode, which gets set when code is loaded
originStorage
Storage
// Storage cache of original entries to dedup rewrites, reset for every transaction
pendingStorage
Storage
// Storage entries that need to be flushed to disk, at the end of an entire block
dirtyStorage
Storage
// Storage entries that have been modified in the current transaction execution
fakeStorage
Storage
// Fake storage which constructed by caller for debugging purpose.
// Cache flags.
// When an object is marked suicided it will be delete from the trie
// during the "update" phase of the state transition.
dirtyCode
bool
// true if the code was updated
suicided
bool
deleted
bool
}
// empty returns whether the account is considered empty.
func
(
s
*
stateObject
)
empty
()
bool
{
return
s
.
data
.
Nonce
==
0
&&
s
.
data
.
Balance
.
Sign
()
==
0
&&
bytes
.
Equal
(
s
.
data
.
CodeHash
,
emptyCodeHash
)
}
// Account is the Ethereum consensus representation of accounts.
// These objects are stored in the main account trie.
type
Account
struct
{
Nonce
uint64
Balance
*
big
.
Int
Root
common
.
Hash
// merkle root of the storage trie
CodeHash
[]
byte
}
func
(
s
*
stateObject
)
Nonce
()
uint64
{
return
s
.
data
.
Nonce
}
// Returns the address of the contract/account
func
(
s
*
stateObject
)
Address
()
common
.
Address
{
return
s
.
address
}
// newObject creates a state object.
func
newObject
(
db
*
StateDB
,
address
common
.
Address
,
data
Account
)
*
stateObject
{
if
data
.
Balance
==
nil
{
data
.
Balance
=
new
(
big
.
Int
)
}
if
data
.
CodeHash
==
nil
{
data
.
CodeHash
=
emptyCodeHash
}
if
data
.
Root
==
(
common
.
Hash
{})
{
data
.
Root
=
emptyRoot
}
return
&
stateObject
{
db
:
db
,
address
:
address
,
addrHash
:
crypto
.
Keccak256Hash
(
address
[
:
]),
data
:
data
,
originStorage
:
make
(
Storage
),
pendingStorage
:
make
(
Storage
),
dirtyStorage
:
make
(
Storage
),
}
}
minigeth/core/state/statedb.go
View file @
8fa24ff0
...
...
@@ -6,10 +6,13 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
)
type
StateDB
struct
{
// TODO: write stub StateDB
// This map holds 'live' objects, which will get modified while processing a state transition.
stateObjects
map
[
common
.
Address
]
*
stateObject
}
// AddAddressToAccessList adds the given address to the access list
...
...
@@ -48,15 +51,18 @@ func (s *StateDB) GetLogs(hash common.Hash, blockHash common.Hash) []*types.Log
// AddPreimage records a SHA3 preimage seen by the VM.
func
(
s
*
StateDB
)
AddPreimage
(
hash
common
.
Hash
,
preimage
[]
byte
)
{
fmt
.
Println
(
"AddPreimage"
,
hash
)
}
// AddRefund adds gas to the refund counter
func
(
s
*
StateDB
)
AddRefund
(
gas
uint64
)
{
fmt
.
Println
(
"AddRefund"
,
gas
)
}
// SubRefund removes gas from the refund counter.
// This method will panic if the refund counter goes below zero
func
(
s
*
StateDB
)
SubRefund
(
gas
uint64
)
{
fmt
.
Println
(
"SubRefund"
,
gas
)
}
// AddSlotToAccessList adds the given (address, slot)-tuple to the access list
...
...
@@ -133,7 +139,14 @@ func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
func
(
s
*
StateDB
)
GetNonce
(
addr
common
.
Address
)
uint64
{
fmt
.
Println
(
"GetNonce"
,
addr
)
return
2122
//return 2122
stateObject
:=
s
.
getStateObject
(
addr
)
if
stateObject
!=
nil
{
return
stateObject
.
Nonce
()
}
return
0
}
// GetRefund returns the current value of the refund counter.
...
...
@@ -184,3 +197,51 @@ func (s *StateDB) Snapshot() int {
// used when the EVM emits new state logs.
func
(
s
*
StateDB
)
Prepare
(
thash
common
.
Hash
,
ti
int
)
{
}
// lower level
func
(
s
*
StateDB
)
setStateObject
(
object
*
stateObject
)
{
s
.
stateObjects
[
object
.
Address
()]
=
object
}
// getStateObject retrieves a state object given by the address, returning nil if
// the object is not found or was deleted in this execution context. If you need
// to differentiate between non-existent/just-deleted, use getDeletedStateObject.
func
(
s
*
StateDB
)
getStateObject
(
addr
common
.
Address
)
*
stateObject
{
if
obj
:=
s
.
getDeletedStateObject
(
addr
);
obj
!=
nil
&&
!
obj
.
deleted
{
return
obj
}
return
nil
}
// getDeletedStateObject is similar to getStateObject, but instead of returning
// nil for a deleted state object, it returns the actual object with the deleted
// flag set. This is needed by the state journal to revert to the correct s-
// destructed object instead of wiping all knowledge about the state object.
func
(
s
*
StateDB
)
getDeletedStateObject
(
addr
common
.
Address
)
*
stateObject
{
// Prefer live objects if any is available
if
obj
:=
s
.
stateObjects
[
addr
];
obj
!=
nil
{
return
obj
}
fmt
.
Println
(
"getDeletedStateObject:"
,
addr
)
// If snapshot unavailable or reading from it failed, load from the database
/*enc, err := s.trie.TryGet(addr.Bytes())
if err != nil {
fmt.Printf("getDeleteStateObject (%x) error: %v\n", addr.Bytes(), err)
return nil
}*/
enc
:=
[]
byte
(
"12"
)
if
len
(
enc
)
==
0
{
return
nil
}
data
:=
new
(
Account
)
if
err
:=
rlp
.
DecodeBytes
(
enc
,
data
);
err
!=
nil
{
log
.
Error
(
"Failed to decode state object"
,
"addr"
,
addr
,
"err"
,
err
)
return
nil
}
// Insert into the live set
obj
:=
newObject
(
s
,
addr
,
*
data
)
s
.
setStateObject
(
obj
)
return
obj
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment