Skip to content

Commit

Permalink
Merge pull request #7 from trinhdn2/refactor/state-account
Browse files Browse the repository at this point in the history
Move statedb.Account struct to types.StateAccount
  • Loading branch information
trinhdn2 authored Jul 31, 2023
2 parents 7cb8b5e + a5ca630 commit 6a5f547
Show file tree
Hide file tree
Showing 16 changed files with 152 additions and 46 deletions.
8 changes: 4 additions & 4 deletions accounts/keystore/keystore_wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte
if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
return nil, accounts.ErrUnknownAccount
}
// Account seems valid, request the keystore to sign
// StateAccount seems valid, request the keystore to sign
return w.keystore.SignHash(account, hash)
}

Expand All @@ -106,7 +106,7 @@ func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction,
if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
return nil, accounts.ErrUnknownAccount
}
// Account seems valid, request the keystore to sign
// StateAccount seems valid, request the keystore to sign
return w.keystore.SignTx(account, tx, chainID)
}

Expand All @@ -120,7 +120,7 @@ func (w *keystoreWallet) SignHashWithPassphrase(account accounts.Account, passph
if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
return nil, accounts.ErrUnknownAccount
}
// Account seems valid, request the keystore to sign
// StateAccount seems valid, request the keystore to sign
return w.keystore.SignHashWithPassphrase(account, passphrase, hash)
}

Expand All @@ -134,6 +134,6 @@ func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphra
if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
return nil, accounts.ErrUnknownAccount
}
// Account seems valid, request the keystore to sign
// StateAccount seems valid, request the keystore to sign
return w.keystore.SignTxWithPassphrase(account, passphrase, tx, chainID)
}
2 changes: 1 addition & 1 deletion accounts/usbwallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ func (w *wallet) selfDerive() {
// Termination requested
continue
case reqc = <-w.deriveReq:
// Account discovery requested
// StateAccount discovery requested
}
// Derivation needs a chain and device access, skip if either unavailable
w.stateLock.RLock()
Expand Down
2 changes: 1 addition & 1 deletion cmd/faucet/faucet.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ type faucet struct {
index []byte // Index page to serve up on the web

keystore *keystore.KeyStore // Keystore containing the single signer
account accounts.Account // Account funding user faucet requests
account accounts.Account // StateAccount funding user faucet requests
nonce uint64 // Current pending nonce of the faucet
price *big.Int // Current gas price to issue funds with

Expand Down
12 changes: 6 additions & 6 deletions cmd/gc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ package main
import (
"flag"
"fmt"
"github.com/tomochain/tomochain/core/rawdb"
"github.com/tomochain/tomochain/ethdb"
"github.com/tomochain/tomochain/ethdb/leveldb"
"os"
"os/signal"
"runtime"
"sync"
"sync/atomic"
"time"

"github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru"
"github.com/tomochain/tomochain/cmd/utils"
"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core"
"github.com/tomochain/tomochain/core/state"
"github.com/tomochain/tomochain/core/rawdb"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/eth"
"github.com/tomochain/tomochain/ethdb"
"github.com/tomochain/tomochain/ethdb/leveldb"
"github.com/tomochain/tomochain/rlp"
"github.com/tomochain/tomochain/trie"
)
Expand Down Expand Up @@ -82,7 +82,7 @@ func main() {
if running {
for _, address := range cleanAddress {
enc := trieRoot.trie.Get(address.Bytes())
var data state.Account
var data types.StateAccount
rlp.DecodeBytes(enc, &data)
fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at block ", trieRoot.number)
signerRoot, err := resolveHash(data.Root[:], db)
Expand Down
2 changes: 1 addition & 1 deletion consensus/clique/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
type Vote struct {
Signer common.Address `json:"signer"` // Authorized signer that cast this vote
Block uint64 `json:"block"` // Block number the vote was cast in (expire old votes)
Address common.Address `json:"address"` // Account being voted on to change its authorization
Address common.Address `json:"address"` // StateAccount being voted on to change its authorization
Authorize bool `json:"authorize"` // Whether to authorize or deauthorize the voted account
}

Expand Down
2 changes: 1 addition & 1 deletion consensus/posv/posv.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ var (

// SignerFn is a signer callback function to request a hash to be signed by a
// backing account.
//type SignerFn func(accounts.Account, []byte) ([]byte, error)
//type SignerFn func(accounts.StateAccount, []byte) ([]byte, error)

// sigHash returns the hash which is used as input for the proof-of-stake-voting
// signing. It is the hash of the entire header apart from the 65 byte signature
Expand Down
2 changes: 1 addition & 1 deletion consensus/posv/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
//type Vote struct {
// Signer common.Address `json:"signer"` // Authorized signer that cast this vote
// Block uint64 `json:"block"` // Block number the vote was cast in (expire old votes)
// Address common.Address `json:"address"` // Account being voted on to change its authorization
// Address common.Address `json:"address"` // StateAccount being voted on to change its authorization
// Authorize bool `json:"authorize"` // Whether to authorize or deauthorize the voted account
//}

Expand Down
3 changes: 2 additions & 1 deletion core/state/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"

"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/rlp"
"github.com/tomochain/tomochain/trie"
)
Expand Down Expand Up @@ -48,7 +49,7 @@ func (self *StateDB) RawDump() Dump {
it := trie.NewIterator(self.trie.NodeIterator(nil))
for it.Next() {
addr := self.trie.GetKey(it.Key)
var data Account
var data types.StateAccount
if err := rlp.DecodeBytes(it.Value, &data); err != nil {
panic(err)
}
Expand Down
3 changes: 2 additions & 1 deletion core/state/iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"

"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/rlp"
"github.com/tomochain/tomochain/trie"
)
Expand Down Expand Up @@ -104,7 +105,7 @@ func (it *NodeIterator) step() error {
return nil
}
// Otherwise we've reached an account node, initiate data iteration
var account Account
var account types.StateAccount
if err := rlp.Decode(bytes.NewReader(it.stateIt.LeafBlob()), &account); err != nil {
return err
}
Expand Down
18 changes: 5 additions & 13 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"math/big"

"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/crypto"
"github.com/tomochain/tomochain/rlp"
)
Expand Down Expand Up @@ -58,12 +59,12 @@ func (self Storage) Copy() Storage {
//
// The usage pattern is as follows:
// First you need to obtain a state object.
// Account values can be accessed and modified through the object.
// StateAccount 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
data types.StateAccount
db *StateDB

// DB error.
Expand Down Expand Up @@ -95,17 +96,8 @@ 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
}

// newObject creates a state object.
func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject {
func newObject(db *StateDB, address common.Address, data types.StateAccount, onDirty func(addr common.Address)) *stateObject {
if data.Balance == nil {
data.Balance = new(big.Int)
}
Expand Down Expand Up @@ -397,7 +389,7 @@ func (self *stateObject) Nonce() uint64 {
}

// Never called, but must be present to allow stateObject to be used
// as a vm.Account interface that also satisfies the vm.ContractRef
// as a vm.StateAccount interface that also satisfies the vm.ContractRef
// interface. Interfaces are awesome.
func (self *stateObject) Value() *big.Int {
panic("Value on stateObject should never be called")
Expand Down
10 changes: 5 additions & 5 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObje
self.setError(err)
return nil
}
var data Account
var data types.StateAccount
if err := rlp.DecodeBytes(enc, &data); err != nil {
log.Error("Failed to decode state object", "addr", addr, "err", err)
return nil
Expand Down Expand Up @@ -432,7 +432,7 @@ func (self *StateDB) MarkStateObjectDirty(addr common.Address) {
// the given address, it is overwritten and returned as the second return value.
func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
prev = self.getStateObject(addr)
newobj = newObject(self, addr, Account{}, self.MarkStateObjectDirty)
newobj = newObject(self, addr, types.StateAccount{}, self.MarkStateObjectDirty)
newobj.setNonce(0) // sets the object to dirty
if prev == nil {
self.journal = append(self.journal, createObjectChange{account: &addr})
Expand All @@ -449,8 +449,8 @@ func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObjec
// CreateAccount is called during the EVM CREATE operation. The situation might arise that
// a contract does the following:
//
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
//
// Carrying over the balance ensures that Ether doesn't disappear.
func (self *StateDB) CreateAccount(addr common.Address) {
Expand Down Expand Up @@ -636,7 +636,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
}
// Write trie changes.
root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error {
var account Account
var account types.StateAccount
if err := rlp.DecodeBytes(leaf, &account); err != nil {
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion core/state/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"

"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/ethdb"
"github.com/tomochain/tomochain/rlp"
"github.com/tomochain/tomochain/trie"
Expand All @@ -29,7 +30,7 @@ import (
func NewStateSync(root common.Hash, database ethdb.KeyValueReader, bloom *trie.SyncBloom) *trie.Sync {
var syncer *trie.Sync
callback := func(leaf []byte, parent common.Hash) error {
var obj Account
var obj types.StateAccount
if err := rlp.Decode(bytes.NewReader(leaf), &obj); err != nil {
return err
}
Expand Down
5 changes: 0 additions & 5 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ import (
"github.com/tomochain/tomochain/rlp"
)

var (
EmptyRootHash = DeriveSha(Transactions{})
EmptyUncleHash = CalcUncleHash(nil)
)

// A BlockNonce is a 64-bit hash which proves (combined with the
// mix-hash) that a sufficient amount of computation has been carried
// out on a block.
Expand Down
13 changes: 13 additions & 0 deletions core/types/hashes.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,23 @@
package types

import (
"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/crypto"
)

var (
// EmptyRootHash is the known root hash of an empty trie.
EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")

// EmptyUncleHash is the known hash of the empty uncle set.
EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347

// EmptyCodeHash is the known hash of the empty EVM bytecode.
EmptyCodeHash = crypto.Keccak256Hash(nil) // c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

// EmptyTxsHash is the known hash of the empty transaction set.
EmptyTxsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")

// EmptyReceiptsHash is the known hash of the empty receipt set.
EmptyReceiptsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
)
103 changes: 103 additions & 0 deletions core/types/state_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package types

import (
"bytes"
"math/big"

"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/rlp"
)

// StateAccount is the Ethereum consensus representation of accounts.
// These objects are stored in the main account trie.
type StateAccount struct {
Nonce uint64
Balance *big.Int
Root common.Hash // merkle root of the storage trie
CodeHash []byte
}

// NewEmptyStateAccount constructs an empty state account.
func NewEmptyStateAccount() *StateAccount {
return &StateAccount{
Balance: new(big.Int),
Root: EmptyRootHash,
CodeHash: EmptyCodeHash.Bytes(),
}
}

// Copy returns a deep-copied state account object.
func (acct *StateAccount) Copy() *StateAccount {
var balance *big.Int
if acct.Balance != nil {
balance = new(big.Int).Set(acct.Balance)
}
return &StateAccount{
Nonce: acct.Nonce,
Balance: balance,
Root: acct.Root,
CodeHash: common.CopyBytes(acct.CodeHash),
}
}

// SlimAccount is a modified version of an Account, where the root is replaced
// with a byte slice. This format can be used to represent full-consensus format
// or slim format which replaces the empty root and code hash as nil byte slice.
type SlimAccount struct {
Nonce uint64
Balance *big.Int
Root []byte // Nil if root equals to types.EmptyRootHash
CodeHash []byte // Nil if hash equals to types.EmptyCodeHash
}

// SlimAccountRLP encodes the state account in 'slim RLP' format.
func SlimAccountRLP(account StateAccount) []byte {
slim := SlimAccount{
Nonce: account.Nonce,
Balance: account.Balance,
}
if account.Root != EmptyRootHash {
slim.Root = account.Root[:]
}
if !bytes.Equal(account.CodeHash, EmptyCodeHash[:]) {
slim.CodeHash = account.CodeHash
}
data, err := rlp.EncodeToBytes(slim)
if err != nil {
panic(err)
}
return data
}

// FullAccount decodes the data on the 'slim RLP' format and return
// the consensus format account.
func FullAccount(data []byte) (*StateAccount, error) {
var slim SlimAccount
if err := rlp.DecodeBytes(data, &slim); err != nil {
return nil, err
}
var account StateAccount
account.Nonce, account.Balance = slim.Nonce, slim.Balance

// Interpret the storage root and code hash in slim format.
if len(slim.Root) == 0 {
account.Root = EmptyRootHash
} else {
account.Root = common.BytesToHash(slim.Root)
}
if len(slim.CodeHash) == 0 {
account.CodeHash = EmptyCodeHash[:]
} else {
account.CodeHash = slim.CodeHash
}
return &account, nil
}

// FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
func FullAccountRLP(data []byte) ([]byte, error) {
account, err := FullAccount(data)
if err != nil {
return nil, err
}
return rlp.EncodeToBytes(account)
}
Loading

0 comments on commit 6a5f547

Please sign in to comment.