merge upstream
This commit is contained in:
@@ -17,10 +17,16 @@ var powlogger = ethlog.NewLogger("POW")
|
||||
type PoW interface {
|
||||
Search(block *Block, reactChan chan ethreact.Event) []byte
|
||||
Verify(hash []byte, diff *big.Int, nonce []byte) bool
|
||||
GetHashrate() int64
|
||||
}
|
||||
|
||||
type EasyPow struct {
|
||||
hash *big.Int
|
||||
hash *big.Int
|
||||
HashRate int64
|
||||
}
|
||||
|
||||
func (pow *EasyPow) GetHashrate() int64 {
|
||||
return pow.HashRate
|
||||
}
|
||||
|
||||
func (pow *EasyPow) Search(block *Block, reactChan chan ethreact.Event) []byte {
|
||||
@@ -40,7 +46,8 @@ func (pow *EasyPow) Search(block *Block, reactChan chan ethreact.Event) []byte {
|
||||
if i%1234567 == 0 {
|
||||
elapsed := time.Now().UnixNano() - start
|
||||
hashes := ((float64(1e9) / float64(elapsed)) * float64(i)) / 1000
|
||||
powlogger.Infoln("Hashing @", int64(hashes), "khash")
|
||||
pow.HashRate = int64(hashes)
|
||||
powlogger.Infoln("Hashing @", int64(pow.HashRate), "khash")
|
||||
}
|
||||
|
||||
sha := ethcrypto.Sha3Bin(big.NewInt(r.Int63()).Bytes())
|
||||
|
@@ -76,6 +76,8 @@ func (self *State) DeleteStateObject(stateObject *StateObject) {
|
||||
|
||||
// Retrieve a state object given my the address. Nil if not found
|
||||
func (self *State) GetStateObject(addr []byte) *StateObject {
|
||||
addr = ethutil.Address(addr)
|
||||
|
||||
stateObject := self.stateObjects[string(addr)]
|
||||
if stateObject != nil {
|
||||
return stateObject
|
||||
@@ -145,7 +147,6 @@ func (self *State) Set(state *State) {
|
||||
|
||||
self.trie = state.trie
|
||||
self.stateObjects = state.stateObjects
|
||||
//*self = *state
|
||||
}
|
||||
|
||||
func (s *State) Root() interface{} {
|
||||
@@ -173,7 +174,7 @@ func (s *State) Reset() {
|
||||
func (s *State) Sync() {
|
||||
// Sync all nested states
|
||||
for _, stateObject := range s.stateObjects {
|
||||
s.UpdateStateObject(stateObject)
|
||||
//s.UpdateStateObject(stateObject)
|
||||
|
||||
if stateObject.state == nil {
|
||||
continue
|
||||
@@ -205,6 +206,8 @@ func (self *State) Update() {
|
||||
// FIXME trie delete is broken
|
||||
valid, t2 := ethtrie.ParanoiaCheck(self.trie)
|
||||
if !valid {
|
||||
statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root, t2.Root)
|
||||
|
||||
self.trie = t2
|
||||
}
|
||||
}
|
||||
@@ -212,9 +215,9 @@ func (self *State) Update() {
|
||||
// Debug stuff
|
||||
func (self *State) CreateOutputForDiff() {
|
||||
for addr, stateObject := range self.stateObjects {
|
||||
fmt.Printf("0x%x 0x%x 0x%x 0x%x\n", addr, stateObject.state.Root(), stateObject.Amount.Bytes(), stateObject.Nonce)
|
||||
fmt.Printf("%x %x %x %x\n", addr, stateObject.state.Root(), stateObject.Amount.Bytes(), stateObject.Nonce)
|
||||
stateObject.state.EachStorage(func(addr string, value *ethutil.Value) {
|
||||
fmt.Printf("0x%x 0x%x\n", addr, value.Bytes())
|
||||
fmt.Printf("%x %x\n", addr, value.Bytes())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/ethereum/eth-go/ethcrypto"
|
||||
"github.com/ethereum/eth-go/ethlog"
|
||||
"github.com/ethereum/eth-go/ethreact"
|
||||
"github.com/ethereum/eth-go/ethtrie"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
"github.com/ethereum/eth-go/ethwire"
|
||||
"math/big"
|
||||
@@ -121,7 +120,10 @@ func (self *StateManager) ProcessTransactions(coinbase *StateObject, state *Stat
|
||||
done:
|
||||
for i, tx := range txs {
|
||||
txGas := new(big.Int).Set(tx.Gas)
|
||||
st := NewStateTransition(coinbase, tx, state, block)
|
||||
|
||||
cb := state.GetStateObject(coinbase.Address())
|
||||
st := NewStateTransition(cb, tx, state, block)
|
||||
//fmt.Printf("#%d\n", i+1)
|
||||
err = st.TransitionState()
|
||||
if err != nil {
|
||||
switch {
|
||||
@@ -149,10 +151,17 @@ done:
|
||||
accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
|
||||
receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
|
||||
|
||||
if i < len(block.Receipts()) {
|
||||
original := block.Receipts()[i]
|
||||
if !original.Cmp(receipt) {
|
||||
return nil, nil, nil, fmt.Errorf("err diff #%d (r) %v ~ %x <=> (c) %v ~ %x (%x)\n", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash())
|
||||
}
|
||||
}
|
||||
|
||||
receipts = append(receipts, receipt)
|
||||
handled = append(handled, tx)
|
||||
|
||||
if ethutil.Config.Diff {
|
||||
if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
|
||||
state.CreateOutputForDiff()
|
||||
}
|
||||
}
|
||||
@@ -188,36 +197,11 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
||||
// before that.
|
||||
defer state.Reset()
|
||||
|
||||
if ethutil.Config.Diff {
|
||||
fmt.Printf("## 0x%x 0x%x ##\n", block.Hash(), block.Number)
|
||||
if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
|
||||
fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
|
||||
}
|
||||
|
||||
receipts, err := sm.ApplyDiff(state, parent, block)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if len(receipts) == len(block.Receipts()) {
|
||||
for i, receipt := range block.Receipts() {
|
||||
statelogger.Infof("diff (r) %v ~ %x <=> (c) %v ~ %x (%x)\n", receipt.CumulativeGasUsed, receipt.PostState[0:4], receipts[i].CumulativeGasUsed, receipts[i].PostState[0:4], receipt.Tx.Hash())
|
||||
}
|
||||
} else {
|
||||
statelogger.Warnln("Unable to print receipt diff. Length didn't match", len(receipts), "for", len(block.Receipts()))
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
for i, receipt := range receipts {
|
||||
gu := new(big.Int)
|
||||
if i != 0 {
|
||||
gu.Sub(receipt.CumulativeGasUsed, receipts[i-1].CumulativeGasUsed)
|
||||
} else {
|
||||
gu.Set(receipt.CumulativeGasUsed)
|
||||
}
|
||||
|
||||
statelogger.Infof("[r] %v ~ %x (%x)\n", gu, receipt.PostState[0:4], receipt.Tx.Hash())
|
||||
}
|
||||
*/
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = sm.ApplyDiff(state, parent, block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -235,12 +219,14 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if ethutil.Config.Paranoia {
|
||||
valid, _ := ethtrie.ParanoiaCheck(state.trie)
|
||||
if !valid {
|
||||
err = fmt.Errorf("PARANOIA: World state trie corruption")
|
||||
/*
|
||||
if ethutil.Config.Paranoia {
|
||||
valid, _ := ethtrie.ParanoiaCheck(state.trie)
|
||||
if !valid {
|
||||
err = fmt.Errorf("PARANOIA: World state trie corruption")
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if !block.State().Cmp(state) {
|
||||
|
||||
|
@@ -15,6 +15,18 @@ func (self Code) String() string {
|
||||
return strings.Join(Disassemble(self), " ")
|
||||
}
|
||||
|
||||
type Storage map[string]*ethutil.Value
|
||||
|
||||
func (self Storage) Copy() Storage {
|
||||
cpy := make(Storage)
|
||||
for key, value := range self {
|
||||
// XXX Do we need a 'value' copy or is this sufficient?
|
||||
cpy[key] = value
|
||||
}
|
||||
|
||||
return cpy
|
||||
}
|
||||
|
||||
type StateObject struct {
|
||||
// Address of the object
|
||||
address []byte
|
||||
@@ -27,7 +39,7 @@ type StateObject struct {
|
||||
script Code
|
||||
initScript Code
|
||||
|
||||
storage map[string]*ethutil.Value
|
||||
storage Storage
|
||||
|
||||
// Total gas pool is the total amount of gas currently
|
||||
// left if this object is the coinbase. Gas is directly
|
||||
@@ -41,7 +53,8 @@ type StateObject struct {
|
||||
}
|
||||
|
||||
func (self *StateObject) Reset() {
|
||||
self.storage = make(map[string]*ethutil.Value)
|
||||
self.storage = make(Storage)
|
||||
self.state.Reset()
|
||||
}
|
||||
|
||||
// Converts an transaction in to a state object
|
||||
@@ -62,11 +75,12 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
|
||||
|
||||
func NewStateObject(addr []byte) *StateObject {
|
||||
// This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter.
|
||||
address := ethutil.LeftPadBytes(addr, 20)
|
||||
address := ethutil.Address(addr)
|
||||
|
||||
object := &StateObject{address: address, Amount: new(big.Int), gasPool: new(big.Int)}
|
||||
object.state = NewState(ethtrie.NewTrie(ethutil.Config.Db, ""))
|
||||
object.storage = make(map[string]*ethutil.Value)
|
||||
object.storage = make(Storage)
|
||||
object.gasPool = new(big.Int)
|
||||
|
||||
return object
|
||||
}
|
||||
@@ -79,13 +93,6 @@ func NewContract(address []byte, Amount *big.Int, root []byte) *StateObject {
|
||||
return contract
|
||||
}
|
||||
|
||||
// Returns a newly created account
|
||||
func NewAccount(address []byte, amount *big.Int) *StateObject {
|
||||
account := &StateObject{address: address, Amount: amount, Nonce: 0}
|
||||
|
||||
return account
|
||||
}
|
||||
|
||||
func NewStateObjectFromBytes(address, data []byte) *StateObject {
|
||||
object := &StateObject{address: address}
|
||||
object.RlpDecode(data)
|
||||
@@ -95,7 +102,7 @@ func NewStateObjectFromBytes(address, data []byte) *StateObject {
|
||||
|
||||
func (self *StateObject) MarkForDeletion() {
|
||||
self.remove = true
|
||||
statelogger.Infof("%x: #%d %v (deletion)\n", self.Address(), self.Nonce, self.Amount)
|
||||
statelogger.DebugDetailf("%x: #%d %v (deletion)\n", self.Address(), self.Nonce, self.Amount)
|
||||
}
|
||||
|
||||
func (c *StateObject) GetAddr(addr []byte) *ethutil.Value {
|
||||
@@ -113,36 +120,73 @@ func (self *StateObject) SetStorage(key *big.Int, value *ethutil.Value) {
|
||||
self.setStorage(key.Bytes(), value)
|
||||
}
|
||||
|
||||
func (self *StateObject) getStorage(key []byte) *ethutil.Value {
|
||||
k := ethutil.LeftPadBytes(key, 32)
|
||||
func (self *StateObject) getStorage(k []byte) *ethutil.Value {
|
||||
key := ethutil.LeftPadBytes(k, 32)
|
||||
|
||||
value := self.storage[string(k)]
|
||||
value := self.storage[string(key)]
|
||||
if value == nil {
|
||||
value = self.GetAddr(k)
|
||||
value = self.GetAddr(key)
|
||||
|
||||
self.storage[string(k)] = value
|
||||
if !value.IsNil() {
|
||||
self.storage[string(key)] = value
|
||||
}
|
||||
}
|
||||
|
||||
return value
|
||||
|
||||
//return self.GetAddr(key)
|
||||
}
|
||||
|
||||
func (self *StateObject) setStorage(key []byte, value *ethutil.Value) {
|
||||
k := ethutil.LeftPadBytes(key, 32)
|
||||
func (self *StateObject) setStorage(k []byte, value *ethutil.Value) {
|
||||
key := ethutil.LeftPadBytes(k, 32)
|
||||
self.storage[string(key)] = value.Copy()
|
||||
|
||||
self.storage[string(k)] = value
|
||||
/*
|
||||
if value.BigInt().Cmp(ethutil.Big0) == 0 {
|
||||
self.state.trie.Delete(string(key))
|
||||
return
|
||||
}
|
||||
|
||||
self.SetAddr(key, value)
|
||||
*/
|
||||
}
|
||||
|
||||
func (self *StateObject) Sync() {
|
||||
/*
|
||||
fmt.Println("############# BEFORE ################")
|
||||
self.state.EachStorage(func(key string, value *ethutil.Value) {
|
||||
fmt.Printf("%x %x %x\n", self.Address(), []byte(key), value.Bytes())
|
||||
})
|
||||
fmt.Printf("%x @:%x\n", self.Address(), self.state.Root())
|
||||
fmt.Println("#####################################")
|
||||
*/
|
||||
for key, value := range self.storage {
|
||||
if value.BigInt().Cmp(ethutil.Big0) == 0 {
|
||||
if value.Len() == 0 { // value.BigInt().Cmp(ethutil.Big0) == 0 {
|
||||
//data := self.getStorage([]byte(key))
|
||||
//fmt.Printf("deleting %x %x 0x%x\n", self.Address(), []byte(key), data)
|
||||
self.state.trie.Delete(string(key))
|
||||
continue
|
||||
}
|
||||
|
||||
self.SetAddr([]byte(key), value)
|
||||
|
||||
}
|
||||
|
||||
valid, t2 := ethtrie.ParanoiaCheck(self.state.trie)
|
||||
if !valid {
|
||||
statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.state.trie.Root, t2.Root)
|
||||
|
||||
self.state.trie = t2
|
||||
}
|
||||
|
||||
/*
|
||||
fmt.Println("############# AFTER ################")
|
||||
self.state.EachStorage(func(key string, value *ethutil.Value) {
|
||||
fmt.Printf("%x %x %x\n", self.Address(), []byte(key), value.Bytes())
|
||||
})
|
||||
*/
|
||||
//fmt.Printf("%x @:%x\n", self.Address(), self.state.Root())
|
||||
}
|
||||
|
||||
func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
|
||||
if int64(len(c.script)-1) < pc.Int64() {
|
||||
return ethutil.NewValue(0)
|
||||
@@ -154,13 +198,13 @@ func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
|
||||
func (c *StateObject) AddAmount(amount *big.Int) {
|
||||
c.SetAmount(new(big.Int).Add(c.Amount, amount))
|
||||
|
||||
statelogger.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.Amount, amount)
|
||||
statelogger.Debugf("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.Amount, amount)
|
||||
}
|
||||
|
||||
func (c *StateObject) SubAmount(amount *big.Int) {
|
||||
c.SetAmount(new(big.Int).Sub(c.Amount, amount))
|
||||
|
||||
statelogger.Infof("%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.Amount, amount)
|
||||
statelogger.Debugf("%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.Amount, amount)
|
||||
}
|
||||
|
||||
func (c *StateObject) SetAmount(amount *big.Int) {
|
||||
@@ -222,6 +266,8 @@ func (self *StateObject) Copy() *StateObject {
|
||||
}
|
||||
stateObject.script = ethutil.CopyBytes(self.script)
|
||||
stateObject.initScript = ethutil.CopyBytes(self.initScript)
|
||||
stateObject.storage = self.storage.Copy()
|
||||
stateObject.gasPool.Set(self.gasPool)
|
||||
|
||||
return stateObject
|
||||
}
|
||||
@@ -280,6 +326,7 @@ func (c *StateObject) RlpDecode(data []byte) {
|
||||
c.Amount = decoder.Get(1).BigInt()
|
||||
c.state = NewState(ethtrie.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()))
|
||||
c.storage = make(map[string]*ethutil.Value)
|
||||
c.gasPool = new(big.Int)
|
||||
|
||||
c.ScriptHash = decoder.Get(3).Bytes()
|
||||
|
||||
|
@@ -2,8 +2,6 @@ package ethchain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go/ethtrie"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
@@ -44,7 +42,7 @@ func (self *StateTransition) Coinbase() *StateObject {
|
||||
return self.cb
|
||||
}
|
||||
|
||||
self.cb = self.state.GetAccount(self.coinbase)
|
||||
self.cb = self.state.GetOrNewStateObject(self.coinbase)
|
||||
return self.cb
|
||||
}
|
||||
func (self *StateTransition) Sender() *StateObject {
|
||||
@@ -52,7 +50,7 @@ func (self *StateTransition) Sender() *StateObject {
|
||||
return self.sen
|
||||
}
|
||||
|
||||
self.sen = self.state.GetAccount(self.tx.Sender())
|
||||
self.sen = self.state.GetOrNewStateObject(self.tx.Sender())
|
||||
|
||||
return self.sen
|
||||
}
|
||||
@@ -65,7 +63,7 @@ func (self *StateTransition) Receiver() *StateObject {
|
||||
return self.rec
|
||||
}
|
||||
|
||||
self.rec = self.state.GetAccount(self.tx.Recipient)
|
||||
self.rec = self.state.GetOrNewStateObject(self.tx.Recipient)
|
||||
return self.rec
|
||||
}
|
||||
|
||||
@@ -176,13 +174,16 @@ func (self *StateTransition) TransitionState() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
* If tx goes TO "0", goes OOG during init, reverse changes, but initial endowment should happen. The ether is lost forever
|
||||
*/
|
||||
var snapshot *State
|
||||
if sender.Amount.Cmp(self.value) < 0 {
|
||||
return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount)
|
||||
}
|
||||
|
||||
var snapshot *State
|
||||
// If the receiver is nil it's a contract (\0*32).
|
||||
if tx.CreatesContract() {
|
||||
// Subtract the (irreversible) amount from the senders account
|
||||
sender.SubAmount(self.value)
|
||||
|
||||
snapshot = self.state.Copy()
|
||||
|
||||
// Create a new state object for the contract
|
||||
@@ -191,16 +192,17 @@ func (self *StateTransition) TransitionState() (err error) {
|
||||
if receiver == nil {
|
||||
return fmt.Errorf("Unable to create contract")
|
||||
}
|
||||
|
||||
// Add the amount to receivers account which should conclude this transaction
|
||||
receiver.AddAmount(self.value)
|
||||
} else {
|
||||
receiver = self.Receiver()
|
||||
}
|
||||
|
||||
// Transfer value from sender to receiver
|
||||
if err = self.transferValue(sender, receiver); err != nil {
|
||||
return
|
||||
}
|
||||
// Subtract the amount from the senders account
|
||||
sender.SubAmount(self.value)
|
||||
// Add the amount to receivers account which should conclude this transaction
|
||||
receiver.AddAmount(self.value)
|
||||
|
||||
if snapshot == nil {
|
||||
snapshot = self.state.Copy()
|
||||
}
|
||||
|
||||
@@ -275,20 +277,5 @@ func (self *StateTransition) Eval(script []byte, context *StateObject, typ strin
|
||||
func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) {
|
||||
ret, _, err = closure.Call(vm, data)
|
||||
|
||||
if ethutil.Config.Paranoia {
|
||||
var (
|
||||
context = closure.object
|
||||
trie = context.state.trie
|
||||
)
|
||||
|
||||
valid, t2 := ethtrie.ParanoiaCheck(trie)
|
||||
if !valid {
|
||||
// TODO FIXME ASAP
|
||||
context.state.trie = t2
|
||||
|
||||
statelogger.Infoln("Warn: PARANOIA: Different state object roots during copy")
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
@@ -227,6 +227,14 @@ func (self *Receipt) String() string {
|
||||
self.CumulativeGasUsed)
|
||||
}
|
||||
|
||||
func (self *Receipt) Cmp(other *Receipt) bool {
|
||||
if bytes.Compare(self.PostState, other.PostState) != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Transaction slice type for basic sorting
|
||||
type Transactions []*Transaction
|
||||
|
||||
|
@@ -155,6 +155,15 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
// XXX Leave this Println intact. Don't change this to the log system.
|
||||
// Used for creating diffs between implementations
|
||||
if vm.logTy == LogTyDiff {
|
||||
switch op {
|
||||
case STOP, RETURN, SUICIDE:
|
||||
closure.object.Sync()
|
||||
closure.object.state.EachStorage(func(key string, value *ethutil.Value) {
|
||||
value.Decode()
|
||||
fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
|
||||
})
|
||||
}
|
||||
|
||||
b := pc.Bytes()
|
||||
if len(b) == 0 {
|
||||
b = []byte{0}
|
||||
@@ -184,9 +193,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
var mult *big.Int
|
||||
y, x := stack.Peekn()
|
||||
val := closure.GetStorage(x)
|
||||
if val.IsEmpty() && len(y.Bytes()) > 0 {
|
||||
if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
|
||||
mult = ethutil.Big2
|
||||
} else if !val.IsEmpty() && len(y.Bytes()) == 0 {
|
||||
} else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
|
||||
mult = ethutil.Big0
|
||||
} else {
|
||||
mult = ethutil.Big1
|
||||
@@ -447,7 +456,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
case BYTE:
|
||||
require(2)
|
||||
val, th := stack.Popn()
|
||||
if th.Cmp(big.NewInt(32)) < 0 {
|
||||
if th.Cmp(big.NewInt(32)) < 0 && th.Cmp(big.NewInt(int64(len(val.Bytes())))) < 0 {
|
||||
byt := big.NewInt(int64(val.Bytes()[th.Int64()]))
|
||||
stack.Push(byt)
|
||||
|
||||
@@ -482,7 +491,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
case ORIGIN:
|
||||
stack.Push(ethutil.BigD(vm.vars.Origin))
|
||||
|
||||
vm.Printf(" => %v", vm.vars.Origin)
|
||||
vm.Printf(" => %x", vm.vars.Origin)
|
||||
case CALLER:
|
||||
caller := closure.caller.Address()
|
||||
stack.Push(ethutil.BigD(caller))
|
||||
@@ -550,10 +559,10 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
}
|
||||
|
||||
code := closure.Script[cOff : cOff+l]
|
||||
fmt.Println("len:", l, "code off:", cOff, "mem off:", mOff)
|
||||
//fmt.Println("len:", l, "code off:", cOff, "mem off:", mOff)
|
||||
|
||||
mem.Set(mOff, l, code)
|
||||
fmt.Println(Code(mem.Get(mOff, l)))
|
||||
//fmt.Println(Code(mem.Get(mOff, l)))
|
||||
case GASPRICE:
|
||||
stack.Push(closure.Price)
|
||||
|
||||
@@ -743,6 +752,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
|
||||
if closure.object.Amount.Cmp(value) < 0 {
|
||||
vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
|
||||
|
||||
closure.ReturnGas(gas, nil, nil)
|
||||
|
||||
stack.Push(ethutil.BigFalse)
|
||||
|
Reference in New Issue
Block a user