aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2014-06-23 20:07:43 +0800
committerzelig <viktor.tron@gmail.com>2014-06-23 20:07:43 +0800
commitf58c7ac5a6f5d77649c1c07dce94bf6d5c146c31 (patch)
tree31e286974108e02b29ed5eff0a73646f605998c2 /ethchain
parent63157c798d613f1ca638597515bb89768e2c1aad (diff)
parentd890258af6de8c5ef9701826fb4ee7c353788ad5 (diff)
downloadgo-tangerine-f58c7ac5a6f5d77649c1c07dce94bf6d5c146c31.tar
go-tangerine-f58c7ac5a6f5d77649c1c07dce94bf6d5c146c31.tar.gz
go-tangerine-f58c7ac5a6f5d77649c1c07dce94bf6d5c146c31.tar.bz2
go-tangerine-f58c7ac5a6f5d77649c1c07dce94bf6d5c146c31.tar.lz
go-tangerine-f58c7ac5a6f5d77649c1c07dce94bf6d5c146c31.tar.xz
go-tangerine-f58c7ac5a6f5d77649c1c07dce94bf6d5c146c31.tar.zst
go-tangerine-f58c7ac5a6f5d77649c1c07dce94bf6d5c146c31.zip
merge upstream
Diffstat (limited to 'ethchain')
-rw-r--r--ethchain/state_manager.go53
-rw-r--r--ethchain/state_object.go9
-rw-r--r--ethchain/transaction.go12
-rw-r--r--ethchain/vm.go34
4 files changed, 60 insertions, 48 deletions
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 20e0a13a2..e5941b165 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -145,45 +145,31 @@ done:
return receipts, handled, unhandled, err
}
-func (sm *StateManager) Process(block *Block, dontReact bool) error {
- if !sm.bc.HasBlock(block.PrevHash) {
- return ParentError(block.PrevHash)
- }
-
- parent := sm.bc.GetBlock(block.PrevHash)
-
- return sm.ProcessBlock(parent.State(), parent, block, dontReact)
-
-}
-
-// Block processing and validating with a given (temporarily) state
-func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontReact bool) (err error) {
+func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// Processing a blocks may never happen simultaneously
sm.mutex.Lock()
defer sm.mutex.Unlock()
- hash := block.Hash()
- if sm.bc.HasBlock(hash) {
+ if sm.bc.HasBlock(block.Hash()) {
return nil
}
+ if !sm.bc.HasBlock(block.PrevHash) {
+ return ParentError(block.PrevHash)
+ }
+
+ var (
+ parent = sm.bc.GetBlock(block.PrevHash)
+ state = parent.State()
+ )
+
// Defer the Undo on the Trie. If the block processing happened
// we don't want to undo but since undo only happens on dirty
// nodes this won't happen because Commit would have been called
// before that.
defer state.Reset()
- // Check if we have the parent hash, if it isn't known we discard it
- // Reasons might be catching up or simply an invalid block
- if !sm.bc.HasBlock(block.PrevHash) && sm.bc.CurrentBlock != nil {
- return ParentError(block.PrevHash)
- }
-
- coinbase := state.GetOrNewStateObject(block.Coinbase)
- coinbase.SetGasPool(block.CalcGasLimit(parent))
-
- // Process the transactions on to current block
- receipts, _, _, _ := sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
+ receipts, err := sm.ApplyDiff(state, parent, block)
defer func() {
if err != nil {
if len(receipts) == len(block.Receipts()) {
@@ -196,6 +182,10 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
}
}()
+ if err != nil {
+ return err
+ }
+
// Block validation
if err = sm.ValidateBlock(block); err != nil {
statelogger.Errorln("Error validating block:", err)
@@ -239,6 +229,17 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
return nil
}
+
+func (sm *StateManager) ApplyDiff(state *State, parent, block *Block) (receipts Receipts, err error) {
+ coinbase := state.GetOrNewStateObject(block.Coinbase)
+ coinbase.SetGasPool(block.CalcGasLimit(parent))
+
+ // Process the transactions on to current block
+ receipts, _, _, _ = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
+
+ return receipts, nil
+}
+
func (sm *StateManager) CalculateTD(block *Block) bool {
uncleDiff := new(big.Int)
for _, uncle := range block.Uncles {
diff --git a/ethchain/state_object.go b/ethchain/state_object.go
index f53f47d7e..7d7352af4 100644
--- a/ethchain/state_object.go
+++ b/ethchain/state_object.go
@@ -90,7 +90,14 @@ func (c *StateObject) SetAddr(addr []byte, value interface{}) {
func (c *StateObject) SetStorage(num *big.Int, val *ethutil.Value) {
addr := ethutil.BigToBytes(num, 256)
- //fmt.Printf("sstore %x => %v\n", addr, val)
+
+ // FIXME This should be handled in the Trie it self
+ if val.BigInt().Cmp(ethutil.Big0) == 0 {
+ c.state.trie.Delete(string(addr))
+
+ return
+ }
+
c.SetAddr(addr, val)
}
diff --git a/ethchain/transaction.go b/ethchain/transaction.go
index 34ab357a1..2ab681030 100644
--- a/ethchain/transaction.go
+++ b/ethchain/transaction.go
@@ -89,11 +89,12 @@ func (tx *Transaction) Signature(key []byte) []byte {
func (tx *Transaction) PublicKey() []byte {
hash := tx.Hash()
- // If we don't make a copy we will overwrite the existing underlying array
- dst := make([]byte, len(tx.r))
- copy(dst, tx.r)
+ r := make([]byte, 32-len(tx.r))
+ s := make([]byte, 32-len(tx.s))
+ r = append(r, ethutil.CopyBytes(tx.r)...)
+ s = append(s, ethutil.CopyBytes(tx.s)...)
- sig := append(dst, tx.s...)
+ sig := append(r, s...)
sig = append(sig, tx.v-27)
pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
@@ -127,6 +128,8 @@ func (tx *Transaction) Sign(privk []byte) error {
func (tx *Transaction) RlpData() interface{} {
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
+ // TODO Remove prefixing zero's
+
return append(data, tx.v, tx.r, tx.s)
}
@@ -150,6 +153,7 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx.Value = decoder.Get(4).BigInt()
tx.Data = decoder.Get(5).Bytes()
tx.v = byte(decoder.Get(6).Uint())
+
tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes()
diff --git a/ethchain/vm.go b/ethchain/vm.go
index 75bcfd782..3a999f0a4 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -328,21 +328,21 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
stack.Push(base)
case LT:
require(2)
- y, x := stack.Popn()
- vm.Printf(" %v < %v", x, y)
+ x, y := stack.Popn()
+ vm.Printf(" %v < %v", y, x)
// x < y
- if x.Cmp(y) < 0 {
+ if y.Cmp(x) < 0 {
stack.Push(ethutil.BigTrue)
} else {
stack.Push(ethutil.BigFalse)
}
case GT:
require(2)
- y, x := stack.Popn()
- vm.Printf(" %v > %v", x, y)
+ x, y := stack.Popn()
+ vm.Printf(" %v > %v", y, x)
// x > y
- if x.Cmp(y) > 0 {
+ if y.Cmp(x) > 0 {
stack.Push(ethutil.BigTrue)
} else {
stack.Push(ethutil.BigFalse)
@@ -361,10 +361,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case NOT:
require(1)
x := stack.Pop()
- if x.Cmp(ethutil.BigFalse) == 0 {
- stack.Push(ethutil.BigTrue)
- } else {
+ if x.Cmp(ethutil.BigFalse) > 0 {
stack.Push(ethutil.BigFalse)
+ } else {
+ stack.Push(ethutil.BigTrue)
}
// 0x10 range
@@ -523,7 +523,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case MLOAD:
require(1)
offset := stack.Pop()
- stack.Push(ethutil.BigD(mem.Get(offset.Int64(), 32)))
+ val := ethutil.BigD(mem.Get(offset.Int64(), 32))
+ stack.Push(val)
+
+ vm.Printf(" => 0x%x", val.Bytes())
case MSTORE: // Store the value at stack top-1 in to memory at location stack top
require(2)
// Pop value of the stack
@@ -542,17 +545,14 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
require(1)
loc := stack.Pop()
val := closure.GetMem(loc)
+
stack.Push(val.BigInt())
- vm.Printf(" {} 0x%x", val)
+ vm.Printf(" {0x%x} 0x%x", loc.Bytes(), val.Bytes())
case SSTORE:
require(2)
val, loc := stack.Popn()
-
- // FIXME This should be handled in the Trie it self
- if val.Cmp(big.NewInt(0)) != 0 {
- closure.SetStorage(loc, ethutil.NewValue(val))
- }
+ closure.SetStorage(loc, ethutil.NewValue(val))
// Add the change to manifest
vm.state.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val)
@@ -691,7 +691,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
fallthrough
case STOP: // Stop the closure
- vm.Printf(" (g) %v", closure.Gas).Endl()
+ vm.Endl()
return closure.Return(nil), nil
default: