forked from cerc-io/plugeth
No longer store script directly in the state tree
This commit is contained in:
parent
a2fb265563
commit
fd19142c0d
@ -122,7 +122,7 @@ func (block *Block) Transactions() []*Transaction {
|
||||
}
|
||||
|
||||
func (block *Block) PayFee(addr []byte, fee *big.Int) bool {
|
||||
contract := block.state.GetContract(addr)
|
||||
contract := block.state.GetStateObject(addr)
|
||||
// If we can't pay the fee return
|
||||
if contract == nil || contract.Amount.Cmp(fee) < 0 /* amount < fee */ {
|
||||
fmt.Println("Contract has insufficient funds", contract.Amount, fee)
|
||||
|
@ -260,7 +260,7 @@ func AddTestNetFunds(block *Block) {
|
||||
"e6716f9544a56c530d868e4bfbacb172315bdead", // Jeffrey
|
||||
"1e12515ce3e0f817a4ddef9ca55788a1d66bd2df", // Vit
|
||||
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4", // Alex
|
||||
"2ef47100e0787b915105fd5e3f4ff6752079d5cb", // Maran
|
||||
//"2ef47100e0787b915105fd5e3f4ff6752079d5cb", // Maran
|
||||
} {
|
||||
//log.Println("2^200 Wei to", addr)
|
||||
codedAddr := ethutil.FromHex(addr)
|
||||
|
@ -49,28 +49,6 @@ func (s *State) Purge() int {
|
||||
return s.trie.NewIterator().Purge()
|
||||
}
|
||||
|
||||
// XXX Deprecated
|
||||
func (s *State) GetContract(addr []byte) *StateObject {
|
||||
data := s.trie.Get(string(addr))
|
||||
if data == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// build contract
|
||||
contract := NewStateObjectFromBytes(addr, []byte(data))
|
||||
|
||||
// Check if there's a cached state for this contract
|
||||
cachedState := s.states[string(addr)]
|
||||
if cachedState != nil {
|
||||
contract.state = cachedState
|
||||
} else {
|
||||
// If it isn't cached, cache the state
|
||||
s.states[string(addr)] = contract.state
|
||||
}
|
||||
|
||||
return contract
|
||||
}
|
||||
|
||||
func (s *State) GetStateObject(addr []byte) *StateObject {
|
||||
data := s.trie.Get(string(addr))
|
||||
if data == "" {
|
||||
@ -91,6 +69,21 @@ func (s *State) GetStateObject(addr []byte) *StateObject {
|
||||
return stateObject
|
||||
}
|
||||
|
||||
// Updates any given state object
|
||||
func (s *State) UpdateStateObject(object *StateObject) {
|
||||
addr := object.Address()
|
||||
|
||||
if object.state != nil {
|
||||
s.states[string(addr)] = object.state
|
||||
}
|
||||
|
||||
ethutil.Config.Db.Put(ethutil.Sha3Bin(object.Script()), object.Script())
|
||||
|
||||
s.trie.Update(string(addr), string(object.RlpEncode()))
|
||||
|
||||
s.manifest.AddObjectChange(object)
|
||||
}
|
||||
|
||||
func (s *State) SetStateObject(stateObject *StateObject) {
|
||||
s.states[string(stateObject.address)] = stateObject.state
|
||||
|
||||
@ -116,18 +109,6 @@ func (s *State) Copy() *State {
|
||||
return NewState(s.trie.Copy())
|
||||
}
|
||||
|
||||
// Updates any given state object
|
||||
func (s *State) UpdateStateObject(object *StateObject) {
|
||||
addr := object.Address()
|
||||
|
||||
if object.state != nil {
|
||||
s.states[string(addr)] = object.state
|
||||
}
|
||||
|
||||
s.trie.Update(string(addr), string(object.RlpEncode()))
|
||||
s.manifest.AddObjectChange(object)
|
||||
}
|
||||
|
||||
func (s *State) Put(key, object []byte) {
|
||||
s.trie.Update(string(key), string(object))
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func (sm *StateManager) BlockChain() *BlockChain {
|
||||
func (sm *StateManager) MakeContract(state *State, tx *Transaction) *StateObject {
|
||||
contract := MakeContract(tx, state)
|
||||
if contract != nil {
|
||||
state.states[string(tx.Hash()[12:])] = contract.state
|
||||
state.states[string(tx.CreationAddress())] = contract.state
|
||||
|
||||
return contract
|
||||
}
|
||||
@ -117,7 +117,8 @@ func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Tra
|
||||
}
|
||||
} else {
|
||||
err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
|
||||
contract := state.GetContract(tx.Recipient)
|
||||
contract := state.GetStateObject(tx.Recipient)
|
||||
ethutil.Config.Log.Debugf("contract recip %x\n", tx.Recipient)
|
||||
if err == nil && len(contract.Script()) > 0 {
|
||||
sm.EvalScript(state, contract.Script(), contract, tx, block)
|
||||
} else if err != nil {
|
||||
|
@ -10,8 +10,9 @@ type StateObject struct {
|
||||
// Address of the object
|
||||
address []byte
|
||||
// Shared attributes
|
||||
Amount *big.Int
|
||||
Nonce uint64
|
||||
Amount *big.Int
|
||||
ScriptHash []byte
|
||||
Nonce uint64
|
||||
// Contract related attributes
|
||||
state *State
|
||||
script []byte
|
||||
@ -22,12 +23,10 @@ type StateObject struct {
|
||||
func MakeContract(tx *Transaction, state *State) *StateObject {
|
||||
// Create contract if there's no recipient
|
||||
if tx.IsContract() {
|
||||
// FIXME
|
||||
addr := tx.Hash()[12:]
|
||||
addr := tx.CreationAddress()
|
||||
|
||||
value := tx.Value
|
||||
contract := NewContract(addr, value, []byte(""))
|
||||
state.UpdateStateObject(contract)
|
||||
contract := NewContract(addr, value, ZeroHash256)
|
||||
|
||||
contract.script = tx.Data
|
||||
contract.initScript = tx.Init
|
||||
@ -146,9 +145,10 @@ func (c *StateObject) RlpEncode() []byte {
|
||||
if c.state != nil {
|
||||
root = c.state.trie.Root
|
||||
} else {
|
||||
root = nil
|
||||
root = ZeroHash256
|
||||
}
|
||||
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, root, c.script})
|
||||
|
||||
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, root, ethutil.Sha3Bin(c.script)})
|
||||
}
|
||||
|
||||
func (c *StateObject) RlpDecode(data []byte) {
|
||||
@ -157,7 +157,10 @@ func (c *StateObject) RlpDecode(data []byte) {
|
||||
c.Amount = decoder.Get(0).BigInt()
|
||||
c.Nonce = decoder.Get(1).Uint()
|
||||
c.state = NewState(ethutil.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()))
|
||||
c.script = decoder.Get(3).Bytes()
|
||||
|
||||
c.ScriptHash = decoder.Get(3).Bytes()
|
||||
|
||||
c.script, _ = ethutil.Config.Db.Get(c.ScriptHash)
|
||||
}
|
||||
|
||||
// Storage change object. Used by the manifest for notifying changes to
|
||||
|
25
ethchain/state_object_test.go
Normal file
25
ethchain/state_object_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
package ethchain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go/ethdb"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSync(t *testing.T) {
|
||||
ethutil.ReadConfig("", ethutil.LogStd)
|
||||
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
state := NewState(ethutil.NewTrie(db, ""))
|
||||
|
||||
contract := NewContract([]byte("aa"), ethutil.Big1, ZeroHash256)
|
||||
|
||||
contract.script = []byte{42}
|
||||
|
||||
state.UpdateStateObject(contract)
|
||||
state.Sync()
|
||||
|
||||
object := state.GetStateObject([]byte("aa"))
|
||||
fmt.Printf("%x\n", object.Script())
|
||||
}
|
@ -60,7 +60,7 @@ func (tx *Transaction) IsContract() bool {
|
||||
}
|
||||
|
||||
func (tx *Transaction) CreationAddress() []byte {
|
||||
return tx.Hash()[12:]
|
||||
return ethutil.Sha3Bin(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:]
|
||||
}
|
||||
|
||||
func (tx *Transaction) Signature(key []byte) []byte {
|
||||
|
@ -471,7 +471,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
||||
|
||||
// Fetch the contract which will serve as the closure body
|
||||
contract := vm.state.GetContract(addr.Bytes())
|
||||
contract := vm.state.GetStateObject(addr.Bytes())
|
||||
|
||||
if contract != nil {
|
||||
// Prepay for the gas
|
||||
|
@ -45,7 +45,7 @@ func (lib *PEthereum) GetKey() *PKey {
|
||||
}
|
||||
|
||||
func (lib *PEthereum) GetStateObject(address string) *PStateObject {
|
||||
stateObject := lib.stateManager.CurrentState().GetContract(ethutil.FromHex(address))
|
||||
stateObject := lib.stateManager.CurrentState().GetStateObject(ethutil.FromHex(address))
|
||||
if stateObject != nil {
|
||||
return NewPStateObject(stateObject)
|
||||
}
|
||||
@ -160,7 +160,6 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
|
||||
}
|
||||
|
||||
acc := lib.stateManager.TransState().GetStateObject(keyPair.Address())
|
||||
//acc := lib.stateManager.GetAddrState(keyPair.Address())
|
||||
tx.Nonce = acc.Nonce
|
||||
acc.Nonce += 1
|
||||
lib.stateManager.TransState().SetStateObject(acc)
|
||||
|
@ -2,6 +2,7 @@ package ethpub
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go/ethchain"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
)
|
||||
@ -112,6 +113,14 @@ func (c *PStateObject) IsContract() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *PStateObject) Script() string {
|
||||
if c.object != nil {
|
||||
return ethutil.Hex(c.object.Script())
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
type PStorageState struct {
|
||||
StateAddress string
|
||||
Address string
|
||||
|
Loading…
Reference in New Issue
Block a user