merge upstream
This commit is contained in:
commit
1e4af85a38
@ -6,7 +6,7 @@ Ethereum
|
||||
Ethereum Go Development package (C) Jeffrey Wilcke
|
||||
|
||||
Ethereum is currently in its testing phase. The current state is "Proof
|
||||
of Concept 0.5.16". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
|
||||
of Concept 0.5.20". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
|
||||
|
||||
Ethereum Go is split up in several sub packages Please refer to each
|
||||
individual package for more information.
|
||||
|
@ -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)
|
||||
|
@ -6,30 +6,35 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func InitWords() []string {
|
||||
_, thisfile, _, _ := runtime.Caller(1)
|
||||
filename := path.Join(path.Dir(thisfile), "mnemonic.words.lst")
|
||||
func InitWords(wordsPath string) {
|
||||
filename := path.Join(wordsPath, "mnemonic.words.lst")
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
fmt.Printf("reading mnemonic word list file 'mnemonic.words.lst' from source folder failed, looking in current folder.")
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("problem getting current folder: ", err))
|
||||
}
|
||||
fmt.Printf("reading mnemonic word list file from supplied path not found. Looked in %s. Trying next option.\n", filename)
|
||||
|
||||
dir := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "eth-go", "ethcrypto")
|
||||
filename = path.Join(dir, "mnemonic.words.lst")
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
fmt.Printf("reading mnemonic word list file 'mnemonic.words.lst' from source folder failed: %s.\n", filename)
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("problem getting current folder: ", err))
|
||||
}
|
||||
filename = path.Join(dir, "mnemonic.words.lst")
|
||||
}
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("reading mnemonic word list file 'mnemonic.words.lst' failed: ", err))
|
||||
panic(fmt.Errorf("All options for finding the mnemonic word list file 'mnemonic.words.lst' failed: ", err))
|
||||
}
|
||||
return strings.Split(string(content), "\n")
|
||||
words = strings.Split(string(content), "\n")
|
||||
}
|
||||
|
||||
var words = InitWords()
|
||||
var words []string
|
||||
|
||||
// TODO: See if we can refactor this into a shared util lib if we need it multiple times
|
||||
func IndexOf(slice []string, value string) int64 {
|
||||
|
26
ethereum.go
26
ethereum.go
@ -81,6 +81,8 @@ type Ethereum struct {
|
||||
keyManager *ethcrypto.KeyManager
|
||||
|
||||
clientIdentity ethwire.ClientIdentity
|
||||
|
||||
isUpToDate bool
|
||||
}
|
||||
|
||||
func New(db ethutil.Database, clientIdentity ethwire.ClientIdentity, keyManager *ethcrypto.KeyManager, caps Caps, usePnp bool) (*Ethereum, error) {
|
||||
@ -108,6 +110,7 @@ func New(db ethutil.Database, clientIdentity ethwire.ClientIdentity, keyManager
|
||||
nat: nat,
|
||||
keyManager: keyManager,
|
||||
clientIdentity: clientIdentity,
|
||||
isUpToDate: true,
|
||||
}
|
||||
ethereum.reactor = ethreact.New()
|
||||
|
||||
@ -158,7 +161,7 @@ func (s *Ethereum) IsUpToDate() bool {
|
||||
upToDate := true
|
||||
eachPeer(s.peers, func(peer *Peer, e *list.Element) {
|
||||
if atomic.LoadInt32(&peer.connected) == 1 {
|
||||
if peer.catchingUp == true {
|
||||
if peer.catchingUp == true && peer.versionKnown {
|
||||
upToDate = false
|
||||
}
|
||||
}
|
||||
@ -373,6 +376,7 @@ func (s *Ethereum) Start(seed bool) {
|
||||
|
||||
// Start the reaping processes
|
||||
go s.ReapDeadPeerHandler()
|
||||
go s.update()
|
||||
|
||||
if seed {
|
||||
s.Seed()
|
||||
@ -514,3 +518,23 @@ out:
|
||||
ethlogger.Debugln("succesfully disestablished UPnP port mapping")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Ethereum) update() {
|
||||
upToDateTimer := time.NewTicker(1 * time.Second)
|
||||
|
||||
out:
|
||||
for {
|
||||
select {
|
||||
case <-upToDateTimer.C:
|
||||
if self.IsUpToDate() && !self.isUpToDate {
|
||||
self.reactor.Post("chainSync", false)
|
||||
self.isUpToDate = true
|
||||
} else if !self.IsUpToDate() && self.isUpToDate {
|
||||
self.reactor.Post("chainSync", true)
|
||||
self.isUpToDate = false
|
||||
}
|
||||
case <-self.quit:
|
||||
break out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ func AddLogSystem(logSystem LogSystem) {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
if logSystems == nil {
|
||||
logMessages = make(chan *logMessage, 5)
|
||||
logMessages = make(chan *logMessage, 10)
|
||||
quit = make(chan chan error, 1)
|
||||
drained = make(chan bool, 1)
|
||||
go start()
|
||||
|
@ -21,28 +21,32 @@ type Miner struct {
|
||||
block *ethchain.Block
|
||||
powChan chan []byte
|
||||
powQuitChan chan ethreact.Event
|
||||
quitChan chan bool
|
||||
quitChan chan chan error
|
||||
}
|
||||
|
||||
func NewDefaultMiner(coinbase []byte, ethereum ethchain.EthManager) Miner {
|
||||
func (self *Miner) GetPow() ethchain.PoW {
|
||||
return self.pow
|
||||
}
|
||||
|
||||
func NewDefaultMiner(coinbase []byte, ethereum ethchain.EthManager) *Miner {
|
||||
miner := Miner{
|
||||
pow: ðchain.EasyPow{},
|
||||
ethereum: ethereum,
|
||||
coinbase: coinbase,
|
||||
}
|
||||
|
||||
// Insert initial TXs in our little miner 'pool'
|
||||
miner.txs = ethereum.TxPool().Flush()
|
||||
miner.block = ethereum.BlockChain().NewBlock(miner.coinbase)
|
||||
|
||||
return miner
|
||||
return &miner
|
||||
}
|
||||
|
||||
func (miner *Miner) Start() {
|
||||
miner.reactChan = make(chan ethreact.Event, 1) // This is the channel that receives 'updates' when ever a new transaction or block comes in
|
||||
miner.powChan = make(chan []byte, 1) // This is the channel that receives valid sha hashes for a given block
|
||||
miner.powQuitChan = make(chan ethreact.Event, 1) // This is the channel that can exit the miner thread
|
||||
miner.quitChan = make(chan bool, 1)
|
||||
miner.quitChan = make(chan chan error, 1)
|
||||
|
||||
// Insert initial TXs in our little miner 'pool'
|
||||
miner.txs = miner.ethereum.TxPool().Flush()
|
||||
miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase)
|
||||
|
||||
// Prepare inital block
|
||||
//miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
|
||||
@ -61,15 +65,17 @@ func (miner *Miner) Start() {
|
||||
reactor.Subscribe("newTx:pre", miner.powQuitChan)
|
||||
|
||||
logger.Infoln("Started")
|
||||
|
||||
reactor.Post("miner:start", miner)
|
||||
}
|
||||
|
||||
func (miner *Miner) listener() {
|
||||
out:
|
||||
for {
|
||||
select {
|
||||
case <-miner.quitChan:
|
||||
case status := <-miner.quitChan:
|
||||
logger.Infoln("Stopped")
|
||||
break out
|
||||
status <- nil
|
||||
return
|
||||
case chanMessage := <-miner.reactChan:
|
||||
|
||||
if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
|
||||
@ -127,7 +133,9 @@ out:
|
||||
|
||||
func (miner *Miner) Stop() {
|
||||
logger.Infoln("Stopping...")
|
||||
miner.quitChan <- true
|
||||
status := make(chan error)
|
||||
miner.quitChan <- status
|
||||
<-status
|
||||
|
||||
reactor := miner.ethereum.Reactor()
|
||||
reactor.Unsubscribe("newBlock", miner.powQuitChan)
|
||||
@ -137,6 +145,8 @@ func (miner *Miner) Stop() {
|
||||
|
||||
close(miner.powQuitChan)
|
||||
close(miner.quitChan)
|
||||
|
||||
reactor.Post("miner:stop", miner)
|
||||
}
|
||||
|
||||
func (self *Miner) mineNewBlock() {
|
||||
|
@ -179,6 +179,19 @@ func FindAddressInNameReg(stateManager *ethchain.StateManager, name string) []by
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindNameInNameReg(stateManager *ethchain.StateManager, addr []byte) string {
|
||||
nameReg := EthereumConfig(stateManager).NameReg()
|
||||
if nameReg != nil {
|
||||
addr = ethutil.LeftPadBytes(addr, 32)
|
||||
|
||||
reg := nameReg.GetStorage(ethutil.BigD(addr))
|
||||
|
||||
return strings.TrimRight(reg.Str(), "\x00")
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, scriptStr string) (*PReceipt, error) {
|
||||
var hash []byte
|
||||
var contractCreation bool
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go/ethchain"
|
||||
"github.com/ethereum/eth-go/ethcrypto"
|
||||
"github.com/ethereum/eth-go/ethtrie"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
"strings"
|
||||
)
|
||||
@ -46,6 +47,7 @@ type PBlock struct {
|
||||
Transactions string `json:"transactions"`
|
||||
Time int64 `json:"time"`
|
||||
Coinbase string `json:"coinbase"`
|
||||
Name string `json:"name"`
|
||||
GasLimit string `json:"gasLimit"`
|
||||
GasUsed string `json:"gasUsed"`
|
||||
}
|
||||
@ -212,6 +214,10 @@ func (c *PStateObject) IsContract() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *PStateObject) EachStorage(cb ethtrie.EachCallback) {
|
||||
self.object.State().EachStorage(cb)
|
||||
}
|
||||
|
||||
type KeyVal struct {
|
||||
Key string
|
||||
Value string
|
||||
|
@ -5,10 +5,12 @@ import (
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go/ethcrypto"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
"reflect"
|
||||
_ "reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func __ignore() { fmt.Println("") }
|
||||
|
||||
func ParanoiaCheck(t1 *Trie) (bool, *Trie) {
|
||||
t2 := NewTrie(ethutil.Config.Db, "")
|
||||
|
||||
@ -269,8 +271,7 @@ func (t *Trie) getState(node interface{}, key []int) interface{} {
|
||||
}
|
||||
|
||||
// It shouldn't come this far
|
||||
fmt.Println("getState unexpected return")
|
||||
return ""
|
||||
panic("unexpected return")
|
||||
}
|
||||
|
||||
func (t *Trie) getNode(node interface{}) *ethutil.Value {
|
||||
@ -287,7 +288,9 @@ func (t *Trie) getNode(node interface{}) *ethutil.Value {
|
||||
return ethutil.NewValueFromBytes([]byte(str))
|
||||
}
|
||||
|
||||
return t.cache.Get(n.Bytes())
|
||||
data := t.cache.Get(n.Bytes())
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func (t *Trie) UpdateState(node interface{}, key []int, value string) interface{} {
|
||||
@ -323,7 +326,8 @@ func (t *Trie) InsertState(node interface{}, key []int, value interface{}) inter
|
||||
|
||||
// New node
|
||||
n := ethutil.NewValue(node)
|
||||
if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
|
||||
if node == nil || n.Len() == 0 {
|
||||
//if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
|
||||
newNode := []interface{}{CompactEncode(key), value}
|
||||
|
||||
return t.Put(newNode)
|
||||
@ -385,17 +389,22 @@ func (t *Trie) InsertState(node interface{}, key []int, value interface{}) inter
|
||||
return t.Put(newNode)
|
||||
}
|
||||
|
||||
return ""
|
||||
panic("unexpected end")
|
||||
}
|
||||
|
||||
func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
||||
if len(key) == 0 {
|
||||
println("<empty ret>")
|
||||
return ""
|
||||
}
|
||||
|
||||
// New node
|
||||
n := ethutil.NewValue(node)
|
||||
if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
|
||||
//if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
|
||||
if node == nil || n.Len() == 0 {
|
||||
//return nil
|
||||
//fmt.Printf("<empty ret> %x %d\n", n, len(n.Bytes()))
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -408,10 +417,17 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
||||
|
||||
// Matching key pair (ie. there's already an object with this key)
|
||||
if CompareIntSlice(k, key) {
|
||||
//fmt.Printf("<delete ret> %x\n", v)
|
||||
|
||||
return ""
|
||||
} else if CompareIntSlice(key[:len(k)], k) {
|
||||
hash := t.deleteState(v, key[len(k):])
|
||||
child := t.getNode(hash)
|
||||
/*
|
||||
if child.IsNil() {
|
||||
return node
|
||||
}
|
||||
*/
|
||||
|
||||
var newNode []interface{}
|
||||
if child.Len() == 2 {
|
||||
@ -421,6 +437,8 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
||||
newNode = []interface{}{currentNode.Get(0).Str(), hash}
|
||||
}
|
||||
|
||||
//fmt.Printf("%x\n", newNode)
|
||||
|
||||
return t.Put(newNode)
|
||||
} else {
|
||||
return node
|
||||
@ -463,10 +481,11 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
||||
newNode = n
|
||||
}
|
||||
|
||||
//fmt.Printf("%x\n", newNode)
|
||||
return t.Put(newNode)
|
||||
}
|
||||
|
||||
return ""
|
||||
panic("unexpected return")
|
||||
}
|
||||
|
||||
type TrieIterator struct {
|
||||
|
@ -1,16 +1,17 @@
|
||||
package ethtrie
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
_ "bytes"
|
||||
_ "encoding/hex"
|
||||
_ "encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
_ "io/ioutil"
|
||||
_ "math/rand"
|
||||
_ "net/http"
|
||||
_ "reflect"
|
||||
"testing"
|
||||
"time"
|
||||
_ "time"
|
||||
)
|
||||
|
||||
const LONG_WORD = "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
@ -42,6 +43,7 @@ func New() (*MemDatabase, *Trie) {
|
||||
return db, NewTrie(db, "")
|
||||
}
|
||||
|
||||
/*
|
||||
func TestTrieSync(t *testing.T) {
|
||||
db, trie := New()
|
||||
|
||||
@ -251,8 +253,8 @@ func TestRemote(t *testing.T) {
|
||||
trie.Update(get(key), get(value))
|
||||
}
|
||||
|
||||
a := NewValue(h(test.Root)).Bytes()
|
||||
b := NewValue(trie.Root).Bytes()
|
||||
a := ethutil.NewValue(h(test.Root)).Bytes()
|
||||
b := ethutil.NewValue(trie.Root).Bytes()
|
||||
if bytes.Compare(a, b) != 0 {
|
||||
t.Errorf("%-10s: %x %x", test.Name, a, b)
|
||||
}
|
||||
@ -267,12 +269,12 @@ func TestTrieReplay(t *testing.T) {
|
||||
}
|
||||
|
||||
_, trie2 := New()
|
||||
trie.NewIterator().Each(func(key string, v *Value) {
|
||||
trie.NewIterator().Each(func(key string, v *ethutil.Value) {
|
||||
trie2.Update(key, v.Str())
|
||||
})
|
||||
|
||||
a := NewValue(trie.Root).Bytes()
|
||||
b := NewValue(trie2.Root).Bytes()
|
||||
a := ethutil.NewValue(trie.Root).Bytes()
|
||||
b := ethutil.NewValue(trie2.Root).Bytes()
|
||||
if bytes.Compare(a, b) != 0 {
|
||||
t.Errorf("%s %x %x\n", test.Name, trie.Root, trie2.Root)
|
||||
}
|
||||
@ -329,3 +331,90 @@ func TestRegression(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
_, trie := New()
|
||||
|
||||
trie.Update("a", "jeffreytestlongstring")
|
||||
trie.Update("aa", "otherstring")
|
||||
trie.Update("aaa", "othermorestring")
|
||||
trie.Update("aabbbbccc", "hithere")
|
||||
trie.Update("abbcccdd", "hstanoehutnaheoustnh")
|
||||
trie.Update("rnthaoeuabbcccdd", "hstanoehutnaheoustnh")
|
||||
trie.Update("rneuabbcccdd", "hstanoehutnaheoustnh")
|
||||
trie.Update("rneuabboeusntahoeucccdd", "hstanoehutnaheoustnh")
|
||||
trie.Update("rnxabboeusntahoeucccdd", "hstanoehutnaheoustnh")
|
||||
trie.Delete("aaboaestnuhbccc")
|
||||
trie.Delete("a")
|
||||
trie.Update("a", "nthaonethaosentuh")
|
||||
trie.Update("c", "shtaosntehua")
|
||||
trie.Delete("a")
|
||||
trie.Update("aaaa", "testmegood")
|
||||
|
||||
fmt.Println("aa =>", trie.Get("aa"))
|
||||
_, t2 := New()
|
||||
trie.NewIterator().Each(func(key string, v *ethutil.Value) {
|
||||
if key == "aaaa" {
|
||||
t2.Update(key, v.Str())
|
||||
} else {
|
||||
t2.Update(key, v.Str())
|
||||
}
|
||||
})
|
||||
|
||||
a := ethutil.NewValue(trie.Root).Bytes()
|
||||
b := ethutil.NewValue(t2.Root).Bytes()
|
||||
|
||||
fmt.Printf("o: %x\nc: %x\n", a, b)
|
||||
}
|
||||
*/
|
||||
|
||||
func TestRndCase(t *testing.T) {
|
||||
_, trie := New()
|
||||
|
||||
data := []struct{ k, v string }{
|
||||
{"0000000000000000000000000000000000000000000000000000000000000001", "a07573657264617461000000000000000000000000000000000000000000000000"},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000003", "8453bb5b31"},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000004", "850218711a00"},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000005", "9462d7705bd0b3ecbc51a8026a25597cb28a650c79"},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000010", "947e70f9460402290a3e487dae01f610a1a8218fda"},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000111", "01"},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000112", "a053656e6174650000000000000000000000000000000000000000000000000000"},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000113", "a053656e6174650000000000000000000000000000000000000000000000000000"},
|
||||
{"53656e6174650000000000000000000000000000000000000000000000000000", "94977e3f62f5e1ed7953697430303a3cfa2b5b736e"},
|
||||
}
|
||||
for _, e := range data {
|
||||
trie.Update(string(ethutil.Hex2Bytes(e.k)), string(ethutil.Hex2Bytes(e.v)))
|
||||
}
|
||||
|
||||
fmt.Printf("root after update %x\n", trie.Root)
|
||||
trie.NewIterator().Each(func(k string, v *ethutil.Value) {
|
||||
fmt.Printf("%x %x\n", k, v.Bytes())
|
||||
})
|
||||
|
||||
data = []struct{ k, v string }{
|
||||
{"0000000000000000000000000000000000000000000000000000000000000112", ""},
|
||||
{"436974697a656e73000000000000000000000000000000000000000000000001", ""},
|
||||
{"436f757274000000000000000000000000000000000000000000000000000002", ""},
|
||||
{"53656e6174650000000000000000000000000000000000000000000000000000", ""},
|
||||
{"436f757274000000000000000000000000000000000000000000000000000000", ""},
|
||||
{"53656e6174650000000000000000000000000000000000000000000000000001", ""},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000113", ""},
|
||||
{"436974697a656e73000000000000000000000000000000000000000000000000", ""},
|
||||
{"436974697a656e73000000000000000000000000000000000000000000000002", ""},
|
||||
{"436f757274000000000000000000000000000000000000000000000000000001", ""},
|
||||
{"0000000000000000000000000000000000000000000000000000000000000111", ""},
|
||||
{"53656e6174650000000000000000000000000000000000000000000000000002", ""},
|
||||
}
|
||||
|
||||
for _, e := range data {
|
||||
trie.Delete(string(ethutil.Hex2Bytes(e.k)))
|
||||
}
|
||||
|
||||
fmt.Printf("root after delete %x\n", trie.Root)
|
||||
|
||||
trie.NewIterator().Each(func(k string, v *ethutil.Value) {
|
||||
fmt.Printf("%x %x\n", k, v.Bytes())
|
||||
})
|
||||
|
||||
fmt.Printf("%x\n", trie.Get(string(ethutil.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))))
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ func FormatData(data string) []byte {
|
||||
// Simple stupid
|
||||
d := new(big.Int)
|
||||
if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
|
||||
return RightPadBytes([]byte(data), 32)
|
||||
return RightPadBytes([]byte(data[1:len(data)-1]), 32)
|
||||
} else if len(data) > 1 && data[:2] == "0x" {
|
||||
d.SetBytes(Hex2Bytes(data[2:]))
|
||||
} else {
|
||||
@ -149,3 +149,17 @@ func LeftPadBytes(slice []byte, l int) []byte {
|
||||
|
||||
return padded
|
||||
}
|
||||
|
||||
func Address(slice []byte) (addr []byte) {
|
||||
if len(slice) < 20 {
|
||||
addr = LeftPadBytes(slice, 20)
|
||||
} else if len(slice) > 20 {
|
||||
addr = slice[len(slice)-20:]
|
||||
} else {
|
||||
addr = slice
|
||||
}
|
||||
|
||||
addr = CopyBytes(addr)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ type ConfigManager struct {
|
||||
ExecPath string
|
||||
Debug bool
|
||||
Diff bool
|
||||
DiffType string
|
||||
Paranoia bool
|
||||
|
||||
conf *globalconf.GlobalConf
|
||||
|
@ -40,13 +40,9 @@ func (val *Value) Len() int {
|
||||
//return val.kind.Len()
|
||||
if data, ok := val.Val.([]interface{}); ok {
|
||||
return len(data)
|
||||
} else if data, ok := val.Val.([]byte); ok {
|
||||
return len(data)
|
||||
} else if data, ok := val.Val.(string); ok {
|
||||
return len(data)
|
||||
}
|
||||
|
||||
return 0
|
||||
return len(val.Bytes())
|
||||
}
|
||||
|
||||
func (val *Value) Raw() interface{} {
|
||||
@ -118,6 +114,8 @@ func (val *Value) Bytes() []byte {
|
||||
return []byte{s}
|
||||
} else if s, ok := val.Val.(string); ok {
|
||||
return []byte(s)
|
||||
} else if s, ok := val.Val.(*big.Int); ok {
|
||||
return s.Bytes()
|
||||
}
|
||||
|
||||
return []byte{}
|
||||
@ -190,6 +188,19 @@ func (val *Value) Get(idx int) *Value {
|
||||
return NewValue(nil)
|
||||
}
|
||||
|
||||
func (self *Value) Copy() *Value {
|
||||
switch val := self.Val.(type) {
|
||||
case *big.Int:
|
||||
return NewValue(new(big.Int).Set(val))
|
||||
case []byte:
|
||||
return NewValue(CopyBytes(val))
|
||||
default:
|
||||
return NewValue(self.Val)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (val *Value) Cmp(o *Value) bool {
|
||||
return reflect.DeepEqual(val.Val, o.Val)
|
||||
}
|
||||
|
13
peer.go
13
peer.go
@ -319,7 +319,7 @@ func (p *Peer) HandleInbound() {
|
||||
for atomic.LoadInt32(&p.disconnect) == 0 {
|
||||
|
||||
// HMM?
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
// Wait for a message from the peer
|
||||
msgs, err := ethwire.ReadMessages(p.conn)
|
||||
if err != nil {
|
||||
@ -328,6 +328,7 @@ func (p *Peer) HandleInbound() {
|
||||
for _, msg := range msgs {
|
||||
peerlogger.DebugDetailf("(%v) => %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data)
|
||||
|
||||
nextMsg:
|
||||
switch msg.Type {
|
||||
case ethwire.MsgHandshakeTy:
|
||||
// Version message
|
||||
@ -373,6 +374,7 @@ func (p *Peer) HandleInbound() {
|
||||
p.diverted = false
|
||||
if !p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) {
|
||||
p.SyncWithPeerToLastKnown()
|
||||
break nextMsg
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -385,10 +387,11 @@ func (p *Peer) HandleInbound() {
|
||||
p.blocksRequested = p.blocksRequested * 2
|
||||
|
||||
peerlogger.Infof("No common ancestor found, requesting %d more blocks.\n", p.blocksRequested)
|
||||
p.catchingUp = false
|
||||
p.FindCommonParentBlock()
|
||||
break
|
||||
break nextMsg
|
||||
}
|
||||
|
||||
p.catchingUp = false
|
||||
}
|
||||
|
||||
for i := msg.Data.Len() - 1; i >= 0; i-- {
|
||||
@ -410,7 +413,7 @@ func (p *Peer) HandleInbound() {
|
||||
}
|
||||
}
|
||||
|
||||
if msg.Data.Len() == 0 {
|
||||
if msg.Data.Len() <= 1 {
|
||||
// Set catching up to false if
|
||||
// the peer has nothing left to give
|
||||
p.catchingUp = false
|
||||
@ -754,7 +757,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) {
|
||||
if !p.catchingUp {
|
||||
// Make sure nobody else is catching up when you want to do this
|
||||
p.catchingUp = true
|
||||
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(10)})
|
||||
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(30)})
|
||||
p.QueueMessage(msg)
|
||||
|
||||
peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr())
|
||||
|
Loading…
Reference in New Issue
Block a user