aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-05-20 17:19:07 +0800
committerobscuren <geffobscura@gmail.com>2014-05-20 17:19:07 +0800
commitfd19142c0db3d2b6651989f5389944f3e211d84f (patch)
tree96916597bc7366fad5043acb6df7a2711675f504 /ethchain
parenta2fb265563a3a6eb80efc5720bb0c6f3fec6f397 (diff)
downloaddexon-fd19142c0db3d2b6651989f5389944f3e211d84f.tar
dexon-fd19142c0db3d2b6651989f5389944f3e211d84f.tar.gz
dexon-fd19142c0db3d2b6651989f5389944f3e211d84f.tar.bz2
dexon-fd19142c0db3d2b6651989f5389944f3e211d84f.tar.lz
dexon-fd19142c0db3d2b6651989f5389944f3e211d84f.tar.xz
dexon-fd19142c0db3d2b6651989f5389944f3e211d84f.tar.zst
dexon-fd19142c0db3d2b6651989f5389944f3e211d84f.zip
No longer store script directly in the state tree
Diffstat (limited to 'ethchain')
-rw-r--r--ethchain/block.go2
-rw-r--r--ethchain/block_chain.go2
-rw-r--r--ethchain/state.go49
-rw-r--r--ethchain/state_manager.go5
-rw-r--r--ethchain/state_object.go21
-rw-r--r--ethchain/state_object_test.go25
-rw-r--r--ethchain/transaction.go2
-rw-r--r--ethchain/vm.go2
8 files changed, 59 insertions, 49 deletions
diff --git a/ethchain/block.go b/ethchain/block.go
index aac50ccb1..ca84dc19c 100644
--- a/ethchain/block.go
+++ b/ethchain/block.go
@@ -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)
diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go
index 6c3b15a6a..99e17727c 100644
--- a/ethchain/block_chain.go
+++ b/ethchain/block_chain.go
@@ -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)
diff --git a/ethchain/state.go b/ethchain/state.go
index d02584d67..63c4a32a6 100644
--- a/ethchain/state.go
+++ b/ethchain/state.go
@@ -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))
}
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 28570775b..098263e8a 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -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 {
diff --git a/ethchain/state_object.go b/ethchain/state_object.go
index 7a11a1152..cb6211ea6 100644
--- a/ethchain/state_object.go
+++ b/ethchain/state_object.go
@@ -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
diff --git a/ethchain/state_object_test.go b/ethchain/state_object_test.go
new file mode 100644
index 000000000..1db01a537
--- /dev/null
+++ b/ethchain/state_object_test.go
@@ -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())
+}
diff --git a/ethchain/transaction.go b/ethchain/transaction.go
index e93e610be..8ea4704cb 100644
--- a/ethchain/transaction.go
+++ b/ethchain/transaction.go
@@ -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 {
diff --git a/ethchain/vm.go b/ethchain/vm.go
index 6579830ec..e732d22a4 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -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