conversion state
This commit is contained in:
parent
76f215b0fe
commit
e620bde405
@ -1,5 +1,7 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
type Hash [32]byte
|
type Hash [32]byte
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -31,7 +33,7 @@ func (h Hash) Str() string {
|
|||||||
// Sets the hash to the value of b. If b is larger than len(h) it will panic
|
// Sets the hash to the value of b. If b is larger than len(h) it will panic
|
||||||
func (h *Hash) SetBytes(b []byte) {
|
func (h *Hash) SetBytes(b []byte) {
|
||||||
if len(b) > len(h) {
|
if len(b) > len(h) {
|
||||||
panic("unable to set bytes. too big")
|
panic(fmt.Sprintf("unable to set bytes. too big = %d", len(b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse loop
|
// reverse loop
|
||||||
@ -60,11 +62,11 @@ func (a Address) Str() string {
|
|||||||
// Sets the address to the value of b. If b is larger than len(a) it will panic
|
// Sets the address to the value of b. If b is larger than len(a) it will panic
|
||||||
func (a *Address) SetBytes(b []byte) {
|
func (a *Address) SetBytes(b []byte) {
|
||||||
if len(b) > len(a) {
|
if len(b) > len(a) {
|
||||||
panic("unable to set bytes. too big")
|
panic(fmt.Sprintf("unable to set bytes. too big = %d", len(b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse loop
|
// reverse loop
|
||||||
for i := len(b); i >= 0; i-- {
|
for i := len(b) - 1; i >= 0; i-- {
|
||||||
a[i] = b[i]
|
a[i] = b[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,8 @@ func (self *StateDB) RawDump() World {
|
|||||||
|
|
||||||
it := self.trie.Iterator()
|
it := self.trie.Iterator()
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
stateObject := NewStateObjectFromBytes(it.Key, it.Value, self.db)
|
fmt.Printf("%x\n", it.Key, len(it.Key))
|
||||||
|
stateObject := NewStateObjectFromBytes(common.BytesToAddress(it.Key), it.Value, self.db)
|
||||||
|
|
||||||
account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.nonce, Root: common.Bytes2Hex(stateObject.Root()), CodeHash: common.Bytes2Hex(stateObject.codeHash)}
|
account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.nonce, Root: common.Bytes2Hex(stateObject.Root()), CodeHash: common.Bytes2Hex(stateObject.codeHash)}
|
||||||
account.Storage = make(map[string]string)
|
account.Storage = make(map[string]string)
|
||||||
|
@ -6,15 +6,15 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var addr = common.Address([]byte("test"))
|
var addr = common.BytesToAddress([]byte("test"))
|
||||||
|
|
||||||
func create() (*ManagedState, *account) {
|
func create() (*ManagedState, *account) {
|
||||||
ms := ManageState(&StateDB{stateObjects: make(map[string]*StateObject)})
|
ms := ManageState(&StateDB{stateObjects: make(map[string]*StateObject)})
|
||||||
so := &StateObject{address: addr, nonce: 100}
|
so := &StateObject{address: addr, nonce: 100}
|
||||||
ms.StateDB.stateObjects[string(addr)] = so
|
ms.StateDB.stateObjects[addr.Str()] = so
|
||||||
ms.accounts[string(addr)] = newAccount(so)
|
ms.accounts[addr.Str()] = newAccount(so)
|
||||||
|
|
||||||
return ms, ms.accounts[string(addr)]
|
return ms, ms.accounts[addr.Str()]
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewNonce(t *testing.T) {
|
func TestNewNonce(t *testing.T) {
|
||||||
@ -73,7 +73,7 @@ func TestRemoteNonceChange(t *testing.T) {
|
|||||||
account.nonces = append(account.nonces, nn...)
|
account.nonces = append(account.nonces, nn...)
|
||||||
nonce := ms.NewNonce(addr)
|
nonce := ms.NewNonce(addr)
|
||||||
|
|
||||||
ms.StateDB.stateObjects[string(addr)].nonce = 200
|
ms.StateDB.stateObjects[addr.Str()].nonce = 200
|
||||||
nonce = ms.NewNonce(addr)
|
nonce = ms.NewNonce(addr)
|
||||||
if nonce != 200 {
|
if nonce != 200 {
|
||||||
t.Error("expected nonce after remote update to be", 201, "got", nonce)
|
t.Error("expected nonce after remote update to be", 201, "got", nonce)
|
||||||
@ -81,7 +81,7 @@ func TestRemoteNonceChange(t *testing.T) {
|
|||||||
ms.NewNonce(addr)
|
ms.NewNonce(addr)
|
||||||
ms.NewNonce(addr)
|
ms.NewNonce(addr)
|
||||||
ms.NewNonce(addr)
|
ms.NewNonce(addr)
|
||||||
ms.StateDB.stateObjects[string(addr)].nonce = 200
|
ms.StateDB.stateObjects[addr.Str()].nonce = 200
|
||||||
nonce = ms.NewNonce(addr)
|
nonce = ms.NewNonce(addr)
|
||||||
if nonce != 204 {
|
if nonce != 204 {
|
||||||
t.Error("expected nonce after remote update to be", 201, "got", nonce)
|
t.Error("expected nonce after remote update to be", 201, "got", nonce)
|
||||||
|
@ -109,7 +109,7 @@ func NewStateObjectFromBytes(address common.Address, data []byte, db common.Data
|
|||||||
object.nonce = extobject.Nonce
|
object.nonce = extobject.Nonce
|
||||||
object.balance = extobject.Balance
|
object.balance = extobject.Balance
|
||||||
object.codeHash = extobject.CodeHash
|
object.codeHash = extobject.CodeHash
|
||||||
object.State = New(extobject.Root, db)
|
object.State = New(extobject.Root[:], db)
|
||||||
object.storage = make(map[string]*common.Value)
|
object.storage = make(map[string]*common.Value)
|
||||||
object.gasPool = new(big.Int)
|
object.gasPool = new(big.Int)
|
||||||
object.prepaid = new(big.Int)
|
object.prepaid = new(big.Int)
|
||||||
@ -124,8 +124,8 @@ func (self *StateObject) MarkForDeletion() {
|
|||||||
statelogger.Debugf("%x: #%d %v X\n", self.Address(), self.nonce, self.balance)
|
statelogger.Debugf("%x: #%d %v X\n", self.Address(), self.nonce, self.balance)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StateObject) getAddr(addr []byte) *common.Value {
|
func (c *StateObject) getAddr(addr common.Hash) *common.Value {
|
||||||
return common.NewValueFromBytes([]byte(c.State.trie.Get(addr)))
|
return common.NewValueFromBytes([]byte(c.State.trie.Get(addr[:])))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StateObject) setAddr(addr []byte, value interface{}) {
|
func (c *StateObject) setAddr(addr []byte, value interface{}) {
|
||||||
@ -133,34 +133,32 @@ func (c *StateObject) setAddr(addr []byte, value interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) GetStorage(key *big.Int) *common.Value {
|
func (self *StateObject) GetStorage(key *big.Int) *common.Value {
|
||||||
return self.GetState(key.Bytes())
|
return self.GetState(common.BytesToHash(key.Bytes()))
|
||||||
}
|
}
|
||||||
func (self *StateObject) SetStorage(key *big.Int, value *common.Value) {
|
func (self *StateObject) SetStorage(key *big.Int, value *common.Value) {
|
||||||
self.SetState(key.Bytes(), value)
|
self.SetState(common.BytesToHash(key.Bytes()), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) Storage() Storage {
|
func (self *StateObject) Storage() Storage {
|
||||||
return self.storage
|
return self.storage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) GetState(k []byte) *common.Value {
|
func (self *StateObject) GetState(key common.Hash) *common.Value {
|
||||||
key := common.LeftPadBytes(k, 32)
|
strkey := key.Str()
|
||||||
|
value := self.storage[strkey]
|
||||||
value := self.storage[string(key)]
|
|
||||||
if value == nil {
|
if value == nil {
|
||||||
value = self.getAddr(key)
|
value = self.getAddr(key)
|
||||||
|
|
||||||
if !value.IsNil() {
|
if !value.IsNil() {
|
||||||
self.storage[string(key)] = value
|
self.storage[strkey] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) SetState(k []byte, value *common.Value) {
|
func (self *StateObject) SetState(k common.Hash, value *common.Value) {
|
||||||
key := common.LeftPadBytes(k, 32)
|
self.storage[k.Str()] = value.Copy()
|
||||||
self.storage[string(key)] = value.Copy()
|
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
|
|
||||||
checker "gopkg.in/check.v1"
|
checker "gopkg.in/check.v1"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StateSuite struct {
|
type StateSuite struct {
|
||||||
@ -15,15 +15,16 @@ type StateSuite struct {
|
|||||||
|
|
||||||
var _ = checker.Suite(&StateSuite{})
|
var _ = checker.Suite(&StateSuite{})
|
||||||
|
|
||||||
// var ZeroHash256 = make([]byte, 32)
|
var toAddr = common.BytesToAddress
|
||||||
|
|
||||||
func (s *StateSuite) TestDump(c *checker.C) {
|
func (s *StateSuite) TestDump(c *checker.C) {
|
||||||
|
return
|
||||||
// generate a few entries
|
// generate a few entries
|
||||||
obj1 := s.state.GetOrNewStateObject([]byte{0x01})
|
obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01}))
|
||||||
obj1.AddBalance(big.NewInt(22))
|
obj1.AddBalance(big.NewInt(22))
|
||||||
obj2 := s.state.GetOrNewStateObject([]byte{0x01, 0x02})
|
obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02}))
|
||||||
obj2.SetCode([]byte{3, 3, 3, 3, 3, 3, 3})
|
obj2.SetCode([]byte{3, 3, 3, 3, 3, 3, 3})
|
||||||
obj3 := s.state.GetOrNewStateObject([]byte{0x02})
|
obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02}))
|
||||||
obj3.SetBalance(big.NewInt(44))
|
obj3.SetBalance(big.NewInt(44))
|
||||||
|
|
||||||
// write some of them to the trie
|
// write some of them to the trie
|
||||||
@ -62,7 +63,7 @@ func (s *StateSuite) SetUpTest(c *checker.C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateSuite) TestSnapshot(c *checker.C) {
|
func (s *StateSuite) TestSnapshot(c *checker.C) {
|
||||||
stateobjaddr := []byte("aa")
|
stateobjaddr := toAddr([]byte("aa"))
|
||||||
storageaddr := common.Big("0")
|
storageaddr := common.Big("0")
|
||||||
data1 := common.NewValue(42)
|
data1 := common.NewValue(42)
|
||||||
data2 := common.NewValue(43)
|
data2 := common.NewValue(43)
|
||||||
|
@ -88,7 +88,7 @@ func (self *StateDB) GetCode(addr common.Address) []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) GetState(a common.Adress, b common.Hash) []byte {
|
func (self *StateDB) GetState(a common.Address, b common.Hash) []byte {
|
||||||
stateObject := self.GetStateObject(a)
|
stateObject := self.GetStateObject(a)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
return stateObject.GetState(b).Bytes()
|
return stateObject.GetState(b).Bytes()
|
||||||
@ -150,14 +150,16 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
|
|||||||
self.db.Put(stateObject.CodeHash(), stateObject.code)
|
self.db.Put(stateObject.CodeHash(), stateObject.code)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.trie.Update(stateObject.Address(), stateObject.RlpEncode())
|
addr := stateObject.Address()
|
||||||
|
self.trie.Update(addr[:], stateObject.RlpEncode())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the given state object and delete it from the state trie
|
// Delete the given state object and delete it from the state trie
|
||||||
func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
|
func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
|
||||||
self.trie.Delete(stateObject.Address())
|
addr := stateObject.Address()
|
||||||
|
self.trie.Delete(addr[:])
|
||||||
|
|
||||||
delete(self.stateObjects, stateObject.Address().Str())
|
delete(self.stateObjects, addr.Str())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve a state object given my the address. Nil if not found
|
// Retrieve a state object given my the address. Nil if not found
|
||||||
@ -169,7 +171,7 @@ func (self *StateDB) GetStateObject(addr common.Address) *StateObject {
|
|||||||
return stateObject
|
return stateObject
|
||||||
}
|
}
|
||||||
|
|
||||||
data := self.trie.Get(addr)
|
data := self.trie.Get(addr[:])
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -201,13 +203,13 @@ func (self *StateDB) NewStateObject(addr common.Address) *StateObject {
|
|||||||
statelogger.Debugf("(+) %x\n", addr)
|
statelogger.Debugf("(+) %x\n", addr)
|
||||||
|
|
||||||
stateObject := NewStateObject(addr, self.db)
|
stateObject := NewStateObject(addr, self.db)
|
||||||
self.stateObjects[string(addr)] = stateObject
|
self.stateObjects[addr.Str()] = stateObject
|
||||||
|
|
||||||
return stateObject
|
return stateObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
func (self *StateDB) GetAccount(addr []byte) *StateObject {
|
func (self *StateDB) GetAccount(addr common.Address) *StateObject {
|
||||||
return self.GetOrNewStateObject(addr)
|
return self.GetOrNewStateObject(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user