forked from cerc-io/plugeth
merge upstream
This commit is contained in:
commit
1e4af85a38
@ -6,7 +6,7 @@ Ethereum
|
|||||||
Ethereum Go Development package (C) Jeffrey Wilcke
|
Ethereum Go Development package (C) Jeffrey Wilcke
|
||||||
|
|
||||||
Ethereum is currently in its testing phase. The current state is "Proof
|
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
|
Ethereum Go is split up in several sub packages Please refer to each
|
||||||
individual package for more information.
|
individual package for more information.
|
||||||
|
@ -17,10 +17,16 @@ var powlogger = ethlog.NewLogger("POW")
|
|||||||
type PoW interface {
|
type PoW interface {
|
||||||
Search(block *Block, reactChan chan ethreact.Event) []byte
|
Search(block *Block, reactChan chan ethreact.Event) []byte
|
||||||
Verify(hash []byte, diff *big.Int, nonce []byte) bool
|
Verify(hash []byte, diff *big.Int, nonce []byte) bool
|
||||||
|
GetHashrate() int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type EasyPow struct {
|
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 {
|
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 {
|
if i%1234567 == 0 {
|
||||||
elapsed := time.Now().UnixNano() - start
|
elapsed := time.Now().UnixNano() - start
|
||||||
hashes := ((float64(1e9) / float64(elapsed)) * float64(i)) / 1000
|
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())
|
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
|
// Retrieve a state object given my the address. Nil if not found
|
||||||
func (self *State) GetStateObject(addr []byte) *StateObject {
|
func (self *State) GetStateObject(addr []byte) *StateObject {
|
||||||
|
addr = ethutil.Address(addr)
|
||||||
|
|
||||||
stateObject := self.stateObjects[string(addr)]
|
stateObject := self.stateObjects[string(addr)]
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
return stateObject
|
return stateObject
|
||||||
@ -145,7 +147,6 @@ func (self *State) Set(state *State) {
|
|||||||
|
|
||||||
self.trie = state.trie
|
self.trie = state.trie
|
||||||
self.stateObjects = state.stateObjects
|
self.stateObjects = state.stateObjects
|
||||||
//*self = *state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) Root() interface{} {
|
func (s *State) Root() interface{} {
|
||||||
@ -173,7 +174,7 @@ func (s *State) Reset() {
|
|||||||
func (s *State) Sync() {
|
func (s *State) Sync() {
|
||||||
// Sync all nested states
|
// Sync all nested states
|
||||||
for _, stateObject := range s.stateObjects {
|
for _, stateObject := range s.stateObjects {
|
||||||
s.UpdateStateObject(stateObject)
|
//s.UpdateStateObject(stateObject)
|
||||||
|
|
||||||
if stateObject.state == nil {
|
if stateObject.state == nil {
|
||||||
continue
|
continue
|
||||||
@ -205,6 +206,8 @@ func (self *State) Update() {
|
|||||||
// FIXME trie delete is broken
|
// FIXME trie delete is broken
|
||||||
valid, t2 := ethtrie.ParanoiaCheck(self.trie)
|
valid, t2 := ethtrie.ParanoiaCheck(self.trie)
|
||||||
if !valid {
|
if !valid {
|
||||||
|
statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root, t2.Root)
|
||||||
|
|
||||||
self.trie = t2
|
self.trie = t2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,9 +215,9 @@ func (self *State) Update() {
|
|||||||
// Debug stuff
|
// Debug stuff
|
||||||
func (self *State) CreateOutputForDiff() {
|
func (self *State) CreateOutputForDiff() {
|
||||||
for addr, stateObject := range self.stateObjects {
|
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) {
|
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/ethcrypto"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethreact"
|
"github.com/ethereum/eth-go/ethreact"
|
||||||
"github.com/ethereum/eth-go/ethtrie"
|
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -121,7 +120,10 @@ func (self *StateManager) ProcessTransactions(coinbase *StateObject, state *Stat
|
|||||||
done:
|
done:
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
txGas := new(big.Int).Set(tx.Gas)
|
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()
|
err = st.TransitionState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch {
|
switch {
|
||||||
@ -149,10 +151,17 @@ done:
|
|||||||
accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
|
accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
|
||||||
receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
|
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)
|
receipts = append(receipts, receipt)
|
||||||
handled = append(handled, tx)
|
handled = append(handled, tx)
|
||||||
|
|
||||||
if ethutil.Config.Diff {
|
if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
|
||||||
state.CreateOutputForDiff()
|
state.CreateOutputForDiff()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,36 +197,11 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
|||||||
// before that.
|
// before that.
|
||||||
defer state.Reset()
|
defer state.Reset()
|
||||||
|
|
||||||
if ethutil.Config.Diff {
|
if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
|
||||||
fmt.Printf("## 0x%x 0x%x ##\n", block.Hash(), block.Number)
|
fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
|
||||||
}
|
}
|
||||||
|
|
||||||
receipts, err := sm.ApplyDiff(state, parent, block)
|
_, 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())
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -235,12 +219,14 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if ethutil.Config.Paranoia {
|
if ethutil.Config.Paranoia {
|
||||||
valid, _ := ethtrie.ParanoiaCheck(state.trie)
|
valid, _ := ethtrie.ParanoiaCheck(state.trie)
|
||||||
if !valid {
|
if !valid {
|
||||||
err = fmt.Errorf("PARANOIA: World state trie corruption")
|
err = fmt.Errorf("PARANOIA: World state trie corruption")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if !block.State().Cmp(state) {
|
if !block.State().Cmp(state) {
|
||||||
|
|
||||||
|
@ -15,6 +15,18 @@ func (self Code) String() string {
|
|||||||
return strings.Join(Disassemble(self), " ")
|
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 {
|
type StateObject struct {
|
||||||
// Address of the object
|
// Address of the object
|
||||||
address []byte
|
address []byte
|
||||||
@ -27,7 +39,7 @@ type StateObject struct {
|
|||||||
script Code
|
script Code
|
||||||
initScript Code
|
initScript Code
|
||||||
|
|
||||||
storage map[string]*ethutil.Value
|
storage Storage
|
||||||
|
|
||||||
// Total gas pool is the total amount of gas currently
|
// Total gas pool is the total amount of gas currently
|
||||||
// left if this object is the coinbase. Gas is directly
|
// left if this object is the coinbase. Gas is directly
|
||||||
@ -41,7 +53,8 @@ type StateObject struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) Reset() {
|
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
|
// Converts an transaction in to a state object
|
||||||
@ -62,11 +75,12 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
|
|||||||
|
|
||||||
func NewStateObject(addr []byte) *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.
|
// 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 := &StateObject{address: address, Amount: new(big.Int), gasPool: new(big.Int)}
|
||||||
object.state = NewState(ethtrie.NewTrie(ethutil.Config.Db, ""))
|
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
|
return object
|
||||||
}
|
}
|
||||||
@ -79,13 +93,6 @@ func NewContract(address []byte, Amount *big.Int, root []byte) *StateObject {
|
|||||||
return contract
|
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 {
|
func NewStateObjectFromBytes(address, data []byte) *StateObject {
|
||||||
object := &StateObject{address: address}
|
object := &StateObject{address: address}
|
||||||
object.RlpDecode(data)
|
object.RlpDecode(data)
|
||||||
@ -95,7 +102,7 @@ func NewStateObjectFromBytes(address, data []byte) *StateObject {
|
|||||||
|
|
||||||
func (self *StateObject) MarkForDeletion() {
|
func (self *StateObject) MarkForDeletion() {
|
||||||
self.remove = true
|
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 {
|
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)
|
self.setStorage(key.Bytes(), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) getStorage(key []byte) *ethutil.Value {
|
func (self *StateObject) getStorage(k []byte) *ethutil.Value {
|
||||||
k := ethutil.LeftPadBytes(key, 32)
|
key := ethutil.LeftPadBytes(k, 32)
|
||||||
|
|
||||||
value := self.storage[string(k)]
|
value := self.storage[string(key)]
|
||||||
if value == nil {
|
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 value
|
||||||
|
|
||||||
|
//return self.GetAddr(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) setStorage(key []byte, value *ethutil.Value) {
|
func (self *StateObject) setStorage(k []byte, value *ethutil.Value) {
|
||||||
k := ethutil.LeftPadBytes(key, 32)
|
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() {
|
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 {
|
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))
|
self.state.trie.Delete(string(key))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
self.SetAddr([]byte(key), value)
|
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 {
|
func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
|
||||||
if int64(len(c.script)-1) < pc.Int64() {
|
if int64(len(c.script)-1) < pc.Int64() {
|
||||||
return ethutil.NewValue(0)
|
return ethutil.NewValue(0)
|
||||||
@ -154,13 +198,13 @@ func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
|
|||||||
func (c *StateObject) AddAmount(amount *big.Int) {
|
func (c *StateObject) AddAmount(amount *big.Int) {
|
||||||
c.SetAmount(new(big.Int).Add(c.Amount, amount))
|
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) {
|
func (c *StateObject) SubAmount(amount *big.Int) {
|
||||||
c.SetAmount(new(big.Int).Sub(c.Amount, amount))
|
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) {
|
func (c *StateObject) SetAmount(amount *big.Int) {
|
||||||
@ -222,6 +266,8 @@ func (self *StateObject) Copy() *StateObject {
|
|||||||
}
|
}
|
||||||
stateObject.script = ethutil.CopyBytes(self.script)
|
stateObject.script = ethutil.CopyBytes(self.script)
|
||||||
stateObject.initScript = ethutil.CopyBytes(self.initScript)
|
stateObject.initScript = ethutil.CopyBytes(self.initScript)
|
||||||
|
stateObject.storage = self.storage.Copy()
|
||||||
|
stateObject.gasPool.Set(self.gasPool)
|
||||||
|
|
||||||
return stateObject
|
return stateObject
|
||||||
}
|
}
|
||||||
@ -280,6 +326,7 @@ func (c *StateObject) RlpDecode(data []byte) {
|
|||||||
c.Amount = decoder.Get(1).BigInt()
|
c.Amount = decoder.Get(1).BigInt()
|
||||||
c.state = NewState(ethtrie.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()))
|
c.state = NewState(ethtrie.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()))
|
||||||
c.storage = make(map[string]*ethutil.Value)
|
c.storage = make(map[string]*ethutil.Value)
|
||||||
|
c.gasPool = new(big.Int)
|
||||||
|
|
||||||
c.ScriptHash = decoder.Get(3).Bytes()
|
c.ScriptHash = decoder.Get(3).Bytes()
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ package ethchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethtrie"
|
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,7 +42,7 @@ func (self *StateTransition) Coinbase() *StateObject {
|
|||||||
return self.cb
|
return self.cb
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cb = self.state.GetAccount(self.coinbase)
|
self.cb = self.state.GetOrNewStateObject(self.coinbase)
|
||||||
return self.cb
|
return self.cb
|
||||||
}
|
}
|
||||||
func (self *StateTransition) Sender() *StateObject {
|
func (self *StateTransition) Sender() *StateObject {
|
||||||
@ -52,7 +50,7 @@ func (self *StateTransition) Sender() *StateObject {
|
|||||||
return self.sen
|
return self.sen
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sen = self.state.GetAccount(self.tx.Sender())
|
self.sen = self.state.GetOrNewStateObject(self.tx.Sender())
|
||||||
|
|
||||||
return self.sen
|
return self.sen
|
||||||
}
|
}
|
||||||
@ -65,7 +63,7 @@ func (self *StateTransition) Receiver() *StateObject {
|
|||||||
return self.rec
|
return self.rec
|
||||||
}
|
}
|
||||||
|
|
||||||
self.rec = self.state.GetAccount(self.tx.Recipient)
|
self.rec = self.state.GetOrNewStateObject(self.tx.Recipient)
|
||||||
return self.rec
|
return self.rec
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,13 +174,16 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME
|
if sender.Amount.Cmp(self.value) < 0 {
|
||||||
* If tx goes TO "0", goes OOG during init, reverse changes, but initial endowment should happen. The ether is lost forever
|
return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount)
|
||||||
*/
|
}
|
||||||
var snapshot *State
|
|
||||||
|
|
||||||
|
var snapshot *State
|
||||||
// If the receiver is nil it's a contract (\0*32).
|
// If the receiver is nil it's a contract (\0*32).
|
||||||
if tx.CreatesContract() {
|
if tx.CreatesContract() {
|
||||||
|
// Subtract the (irreversible) amount from the senders account
|
||||||
|
sender.SubAmount(self.value)
|
||||||
|
|
||||||
snapshot = self.state.Copy()
|
snapshot = self.state.Copy()
|
||||||
|
|
||||||
// Create a new state object for the contract
|
// Create a new state object for the contract
|
||||||
@ -191,16 +192,17 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
if receiver == nil {
|
if receiver == nil {
|
||||||
return fmt.Errorf("Unable to create contract")
|
return fmt.Errorf("Unable to create contract")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the amount to receivers account which should conclude this transaction
|
||||||
|
receiver.AddAmount(self.value)
|
||||||
} else {
|
} else {
|
||||||
receiver = self.Receiver()
|
receiver = self.Receiver()
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer value from sender to receiver
|
// Subtract the amount from the senders account
|
||||||
if err = self.transferValue(sender, receiver); err != nil {
|
sender.SubAmount(self.value)
|
||||||
return
|
// Add the amount to receivers account which should conclude this transaction
|
||||||
}
|
receiver.AddAmount(self.value)
|
||||||
|
|
||||||
if snapshot == nil {
|
|
||||||
snapshot = self.state.Copy()
|
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) {
|
func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) {
|
||||||
ret, _, err = closure.Call(vm, data)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,14 @@ func (self *Receipt) String() string {
|
|||||||
self.CumulativeGasUsed)
|
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
|
// Transaction slice type for basic sorting
|
||||||
type Transactions []*Transaction
|
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.
|
// XXX Leave this Println intact. Don't change this to the log system.
|
||||||
// Used for creating diffs between implementations
|
// Used for creating diffs between implementations
|
||||||
if vm.logTy == LogTyDiff {
|
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()
|
b := pc.Bytes()
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
b = []byte{0}
|
b = []byte{0}
|
||||||
@ -184,9 +193,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
var mult *big.Int
|
var mult *big.Int
|
||||||
y, x := stack.Peekn()
|
y, x := stack.Peekn()
|
||||||
val := closure.GetStorage(x)
|
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
|
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
|
mult = ethutil.Big0
|
||||||
} else {
|
} else {
|
||||||
mult = ethutil.Big1
|
mult = ethutil.Big1
|
||||||
@ -447,7 +456,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
case BYTE:
|
case BYTE:
|
||||||
require(2)
|
require(2)
|
||||||
val, th := stack.Popn()
|
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()]))
|
byt := big.NewInt(int64(val.Bytes()[th.Int64()]))
|
||||||
stack.Push(byt)
|
stack.Push(byt)
|
||||||
|
|
||||||
@ -482,7 +491,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
case ORIGIN:
|
case ORIGIN:
|
||||||
stack.Push(ethutil.BigD(vm.vars.Origin))
|
stack.Push(ethutil.BigD(vm.vars.Origin))
|
||||||
|
|
||||||
vm.Printf(" => %v", vm.vars.Origin)
|
vm.Printf(" => %x", vm.vars.Origin)
|
||||||
case CALLER:
|
case CALLER:
|
||||||
caller := closure.caller.Address()
|
caller := closure.caller.Address()
|
||||||
stack.Push(ethutil.BigD(caller))
|
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]
|
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)
|
mem.Set(mOff, l, code)
|
||||||
fmt.Println(Code(mem.Get(mOff, l)))
|
//fmt.Println(Code(mem.Get(mOff, l)))
|
||||||
case GASPRICE:
|
case GASPRICE:
|
||||||
stack.Push(closure.Price)
|
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 {
|
if closure.object.Amount.Cmp(value) < 0 {
|
||||||
vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
|
vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
|
||||||
|
|
||||||
closure.ReturnGas(gas, nil, nil)
|
closure.ReturnGas(gas, nil, nil)
|
||||||
|
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
@ -6,30 +6,35 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitWords() []string {
|
func InitWords(wordsPath string) {
|
||||||
_, thisfile, _, _ := runtime.Caller(1)
|
filename := path.Join(wordsPath, "mnemonic.words.lst")
|
||||||
filename := path.Join(path.Dir(thisfile), "mnemonic.words.lst")
|
|
||||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
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.")
|
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]))
|
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("problem getting current folder: ", err))
|
panic(fmt.Errorf("problem getting current folder: ", err))
|
||||||
}
|
}
|
||||||
filename = path.Join(dir, "mnemonic.words.lst")
|
filename = path.Join(dir, "mnemonic.words.lst")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
content, err := ioutil.ReadFile(filename)
|
content, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
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
|
// 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 {
|
func IndexOf(slice []string, value string) int64 {
|
||||||
|
26
ethereum.go
26
ethereum.go
@ -81,6 +81,8 @@ type Ethereum struct {
|
|||||||
keyManager *ethcrypto.KeyManager
|
keyManager *ethcrypto.KeyManager
|
||||||
|
|
||||||
clientIdentity ethwire.ClientIdentity
|
clientIdentity ethwire.ClientIdentity
|
||||||
|
|
||||||
|
isUpToDate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(db ethutil.Database, clientIdentity ethwire.ClientIdentity, keyManager *ethcrypto.KeyManager, caps Caps, usePnp bool) (*Ethereum, error) {
|
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,
|
nat: nat,
|
||||||
keyManager: keyManager,
|
keyManager: keyManager,
|
||||||
clientIdentity: clientIdentity,
|
clientIdentity: clientIdentity,
|
||||||
|
isUpToDate: true,
|
||||||
}
|
}
|
||||||
ethereum.reactor = ethreact.New()
|
ethereum.reactor = ethreact.New()
|
||||||
|
|
||||||
@ -158,7 +161,7 @@ func (s *Ethereum) IsUpToDate() bool {
|
|||||||
upToDate := true
|
upToDate := true
|
||||||
eachPeer(s.peers, func(peer *Peer, e *list.Element) {
|
eachPeer(s.peers, func(peer *Peer, e *list.Element) {
|
||||||
if atomic.LoadInt32(&peer.connected) == 1 {
|
if atomic.LoadInt32(&peer.connected) == 1 {
|
||||||
if peer.catchingUp == true {
|
if peer.catchingUp == true && peer.versionKnown {
|
||||||
upToDate = false
|
upToDate = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -373,6 +376,7 @@ func (s *Ethereum) Start(seed bool) {
|
|||||||
|
|
||||||
// Start the reaping processes
|
// Start the reaping processes
|
||||||
go s.ReapDeadPeerHandler()
|
go s.ReapDeadPeerHandler()
|
||||||
|
go s.update()
|
||||||
|
|
||||||
if seed {
|
if seed {
|
||||||
s.Seed()
|
s.Seed()
|
||||||
@ -514,3 +518,23 @@ out:
|
|||||||
ethlogger.Debugln("succesfully disestablished UPnP port mapping")
|
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()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
if logSystems == nil {
|
if logSystems == nil {
|
||||||
logMessages = make(chan *logMessage, 5)
|
logMessages = make(chan *logMessage, 10)
|
||||||
quit = make(chan chan error, 1)
|
quit = make(chan chan error, 1)
|
||||||
drained = make(chan bool, 1)
|
drained = make(chan bool, 1)
|
||||||
go start()
|
go start()
|
||||||
|
@ -21,28 +21,32 @@ type Miner struct {
|
|||||||
block *ethchain.Block
|
block *ethchain.Block
|
||||||
powChan chan []byte
|
powChan chan []byte
|
||||||
powQuitChan chan ethreact.Event
|
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{
|
miner := Miner{
|
||||||
pow: ðchain.EasyPow{},
|
pow: ðchain.EasyPow{},
|
||||||
ethereum: ethereum,
|
ethereum: ethereum,
|
||||||
coinbase: coinbase,
|
coinbase: coinbase,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert initial TXs in our little miner 'pool'
|
return &miner
|
||||||
miner.txs = ethereum.TxPool().Flush()
|
|
||||||
miner.block = ethereum.BlockChain().NewBlock(miner.coinbase)
|
|
||||||
|
|
||||||
return miner
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (miner *Miner) Start() {
|
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.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.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.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
|
// Prepare inital block
|
||||||
//miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
|
//miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
|
||||||
@ -61,15 +65,17 @@ func (miner *Miner) Start() {
|
|||||||
reactor.Subscribe("newTx:pre", miner.powQuitChan)
|
reactor.Subscribe("newTx:pre", miner.powQuitChan)
|
||||||
|
|
||||||
logger.Infoln("Started")
|
logger.Infoln("Started")
|
||||||
|
|
||||||
|
reactor.Post("miner:start", miner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (miner *Miner) listener() {
|
func (miner *Miner) listener() {
|
||||||
out:
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-miner.quitChan:
|
case status := <-miner.quitChan:
|
||||||
logger.Infoln("Stopped")
|
logger.Infoln("Stopped")
|
||||||
break out
|
status <- nil
|
||||||
|
return
|
||||||
case chanMessage := <-miner.reactChan:
|
case chanMessage := <-miner.reactChan:
|
||||||
|
|
||||||
if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
|
if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
|
||||||
@ -127,7 +133,9 @@ out:
|
|||||||
|
|
||||||
func (miner *Miner) Stop() {
|
func (miner *Miner) Stop() {
|
||||||
logger.Infoln("Stopping...")
|
logger.Infoln("Stopping...")
|
||||||
miner.quitChan <- true
|
status := make(chan error)
|
||||||
|
miner.quitChan <- status
|
||||||
|
<-status
|
||||||
|
|
||||||
reactor := miner.ethereum.Reactor()
|
reactor := miner.ethereum.Reactor()
|
||||||
reactor.Unsubscribe("newBlock", miner.powQuitChan)
|
reactor.Unsubscribe("newBlock", miner.powQuitChan)
|
||||||
@ -137,6 +145,8 @@ func (miner *Miner) Stop() {
|
|||||||
|
|
||||||
close(miner.powQuitChan)
|
close(miner.powQuitChan)
|
||||||
close(miner.quitChan)
|
close(miner.quitChan)
|
||||||
|
|
||||||
|
reactor.Post("miner:stop", miner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) mineNewBlock() {
|
func (self *Miner) mineNewBlock() {
|
||||||
|
@ -179,6 +179,19 @@ func FindAddressInNameReg(stateManager *ethchain.StateManager, name string) []by
|
|||||||
return nil
|
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) {
|
func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, scriptStr string) (*PReceipt, error) {
|
||||||
var hash []byte
|
var hash []byte
|
||||||
var contractCreation bool
|
var contractCreation bool
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethcrypto"
|
"github.com/ethereum/eth-go/ethcrypto"
|
||||||
|
"github.com/ethereum/eth-go/ethtrie"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -46,6 +47,7 @@ type PBlock struct {
|
|||||||
Transactions string `json:"transactions"`
|
Transactions string `json:"transactions"`
|
||||||
Time int64 `json:"time"`
|
Time int64 `json:"time"`
|
||||||
Coinbase string `json:"coinbase"`
|
Coinbase string `json:"coinbase"`
|
||||||
|
Name string `json:"name"`
|
||||||
GasLimit string `json:"gasLimit"`
|
GasLimit string `json:"gasLimit"`
|
||||||
GasUsed string `json:"gasUsed"`
|
GasUsed string `json:"gasUsed"`
|
||||||
}
|
}
|
||||||
@ -212,6 +214,10 @@ func (c *PStateObject) IsContract() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *PStateObject) EachStorage(cb ethtrie.EachCallback) {
|
||||||
|
self.object.State().EachStorage(cb)
|
||||||
|
}
|
||||||
|
|
||||||
type KeyVal struct {
|
type KeyVal struct {
|
||||||
Key string
|
Key string
|
||||||
Value string
|
Value string
|
||||||
|
@ -5,10 +5,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethcrypto"
|
"github.com/ethereum/eth-go/ethcrypto"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"reflect"
|
_ "reflect"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func __ignore() { fmt.Println("") }
|
||||||
|
|
||||||
func ParanoiaCheck(t1 *Trie) (bool, *Trie) {
|
func ParanoiaCheck(t1 *Trie) (bool, *Trie) {
|
||||||
t2 := NewTrie(ethutil.Config.Db, "")
|
t2 := NewTrie(ethutil.Config.Db, "")
|
||||||
|
|
||||||
@ -269,8 +271,7 @@ func (t *Trie) getState(node interface{}, key []int) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// It shouldn't come this far
|
// It shouldn't come this far
|
||||||
fmt.Println("getState unexpected return")
|
panic("unexpected return")
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trie) getNode(node interface{}) *ethutil.Value {
|
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 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{} {
|
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
|
// New node
|
||||||
n := ethutil.NewValue(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}
|
newNode := []interface{}{CompactEncode(key), value}
|
||||||
|
|
||||||
return t.Put(newNode)
|
return t.Put(newNode)
|
||||||
@ -385,17 +389,22 @@ func (t *Trie) InsertState(node interface{}, key []int, value interface{}) inter
|
|||||||
return t.Put(newNode)
|
return t.Put(newNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
panic("unexpected end")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
|
println("<empty ret>")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// New node
|
// New node
|
||||||
n := ethutil.NewValue(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 ""
|
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)
|
// Matching key pair (ie. there's already an object with this key)
|
||||||
if CompareIntSlice(k, key) {
|
if CompareIntSlice(k, key) {
|
||||||
|
//fmt.Printf("<delete ret> %x\n", v)
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
} else if CompareIntSlice(key[:len(k)], k) {
|
} else if CompareIntSlice(key[:len(k)], k) {
|
||||||
hash := t.deleteState(v, key[len(k):])
|
hash := t.deleteState(v, key[len(k):])
|
||||||
child := t.getNode(hash)
|
child := t.getNode(hash)
|
||||||
|
/*
|
||||||
|
if child.IsNil() {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
var newNode []interface{}
|
var newNode []interface{}
|
||||||
if child.Len() == 2 {
|
if child.Len() == 2 {
|
||||||
@ -421,6 +437,8 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
|||||||
newNode = []interface{}{currentNode.Get(0).Str(), hash}
|
newNode = []interface{}{currentNode.Get(0).Str(), hash}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fmt.Printf("%x\n", newNode)
|
||||||
|
|
||||||
return t.Put(newNode)
|
return t.Put(newNode)
|
||||||
} else {
|
} else {
|
||||||
return node
|
return node
|
||||||
@ -463,10 +481,11 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
|
|||||||
newNode = n
|
newNode = n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fmt.Printf("%x\n", newNode)
|
||||||
return t.Put(newNode)
|
return t.Put(newNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
panic("unexpected return")
|
||||||
}
|
}
|
||||||
|
|
||||||
type TrieIterator struct {
|
type TrieIterator struct {
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package ethtrie
|
package ethtrie
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
_ "bytes"
|
||||||
"encoding/hex"
|
_ "encoding/hex"
|
||||||
"encoding/json"
|
_ "encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"math/rand"
|
_ "io/ioutil"
|
||||||
"net/http"
|
_ "math/rand"
|
||||||
"reflect"
|
_ "net/http"
|
||||||
|
_ "reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
_ "time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const LONG_WORD = "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ"
|
const LONG_WORD = "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
@ -42,6 +43,7 @@ func New() (*MemDatabase, *Trie) {
|
|||||||
return db, NewTrie(db, "")
|
return db, NewTrie(db, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func TestTrieSync(t *testing.T) {
|
func TestTrieSync(t *testing.T) {
|
||||||
db, trie := New()
|
db, trie := New()
|
||||||
|
|
||||||
@ -251,8 +253,8 @@ func TestRemote(t *testing.T) {
|
|||||||
trie.Update(get(key), get(value))
|
trie.Update(get(key), get(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
a := NewValue(h(test.Root)).Bytes()
|
a := ethutil.NewValue(h(test.Root)).Bytes()
|
||||||
b := NewValue(trie.Root).Bytes()
|
b := ethutil.NewValue(trie.Root).Bytes()
|
||||||
if bytes.Compare(a, b) != 0 {
|
if bytes.Compare(a, b) != 0 {
|
||||||
t.Errorf("%-10s: %x %x", test.Name, a, b)
|
t.Errorf("%-10s: %x %x", test.Name, a, b)
|
||||||
}
|
}
|
||||||
@ -267,12 +269,12 @@ func TestTrieReplay(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, trie2 := New()
|
_, trie2 := New()
|
||||||
trie.NewIterator().Each(func(key string, v *Value) {
|
trie.NewIterator().Each(func(key string, v *ethutil.Value) {
|
||||||
trie2.Update(key, v.Str())
|
trie2.Update(key, v.Str())
|
||||||
})
|
})
|
||||||
|
|
||||||
a := NewValue(trie.Root).Bytes()
|
a := ethutil.NewValue(trie.Root).Bytes()
|
||||||
b := NewValue(trie2.Root).Bytes()
|
b := ethutil.NewValue(trie2.Root).Bytes()
|
||||||
if bytes.Compare(a, b) != 0 {
|
if bytes.Compare(a, b) != 0 {
|
||||||
t.Errorf("%s %x %x\n", test.Name, trie.Root, trie2.Root)
|
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
|
// Simple stupid
|
||||||
d := new(big.Int)
|
d := new(big.Int)
|
||||||
if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
|
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" {
|
} else if len(data) > 1 && data[:2] == "0x" {
|
||||||
d.SetBytes(Hex2Bytes(data[2:]))
|
d.SetBytes(Hex2Bytes(data[2:]))
|
||||||
} else {
|
} else {
|
||||||
@ -149,3 +149,17 @@ func LeftPadBytes(slice []byte, l int) []byte {
|
|||||||
|
|
||||||
return padded
|
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
|
ExecPath string
|
||||||
Debug bool
|
Debug bool
|
||||||
Diff bool
|
Diff bool
|
||||||
|
DiffType string
|
||||||
Paranoia bool
|
Paranoia bool
|
||||||
|
|
||||||
conf *globalconf.GlobalConf
|
conf *globalconf.GlobalConf
|
||||||
|
@ -40,13 +40,9 @@ func (val *Value) Len() int {
|
|||||||
//return val.kind.Len()
|
//return val.kind.Len()
|
||||||
if data, ok := val.Val.([]interface{}); ok {
|
if data, ok := val.Val.([]interface{}); ok {
|
||||||
return len(data)
|
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{} {
|
func (val *Value) Raw() interface{} {
|
||||||
@ -118,6 +114,8 @@ func (val *Value) Bytes() []byte {
|
|||||||
return []byte{s}
|
return []byte{s}
|
||||||
} else if s, ok := val.Val.(string); ok {
|
} else if s, ok := val.Val.(string); ok {
|
||||||
return []byte(s)
|
return []byte(s)
|
||||||
|
} else if s, ok := val.Val.(*big.Int); ok {
|
||||||
|
return s.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
return []byte{}
|
return []byte{}
|
||||||
@ -190,6 +188,19 @@ func (val *Value) Get(idx int) *Value {
|
|||||||
return NewValue(nil)
|
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 {
|
func (val *Value) Cmp(o *Value) bool {
|
||||||
return reflect.DeepEqual(val.Val, o.Val)
|
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 {
|
for atomic.LoadInt32(&p.disconnect) == 0 {
|
||||||
|
|
||||||
// HMM?
|
// HMM?
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(50 * time.Millisecond)
|
||||||
// Wait for a message from the peer
|
// Wait for a message from the peer
|
||||||
msgs, err := ethwire.ReadMessages(p.conn)
|
msgs, err := ethwire.ReadMessages(p.conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -328,6 +328,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
peerlogger.DebugDetailf("(%v) => %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data)
|
peerlogger.DebugDetailf("(%v) => %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data)
|
||||||
|
|
||||||
|
nextMsg:
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case ethwire.MsgHandshakeTy:
|
case ethwire.MsgHandshakeTy:
|
||||||
// Version message
|
// Version message
|
||||||
@ -373,6 +374,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
p.diverted = false
|
p.diverted = false
|
||||||
if !p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) {
|
if !p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) {
|
||||||
p.SyncWithPeerToLastKnown()
|
p.SyncWithPeerToLastKnown()
|
||||||
|
break nextMsg
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -385,10 +387,11 @@ func (p *Peer) HandleInbound() {
|
|||||||
p.blocksRequested = p.blocksRequested * 2
|
p.blocksRequested = p.blocksRequested * 2
|
||||||
|
|
||||||
peerlogger.Infof("No common ancestor found, requesting %d more blocks.\n", p.blocksRequested)
|
peerlogger.Infof("No common ancestor found, requesting %d more blocks.\n", p.blocksRequested)
|
||||||
p.catchingUp = false
|
|
||||||
p.FindCommonParentBlock()
|
p.FindCommonParentBlock()
|
||||||
break
|
break nextMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.catchingUp = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := msg.Data.Len() - 1; i >= 0; i-- {
|
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
|
// Set catching up to false if
|
||||||
// the peer has nothing left to give
|
// the peer has nothing left to give
|
||||||
p.catchingUp = false
|
p.catchingUp = false
|
||||||
@ -754,7 +757,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) {
|
|||||||
if !p.catchingUp {
|
if !p.catchingUp {
|
||||||
// Make sure nobody else is catching up when you want to do this
|
// Make sure nobody else is catching up when you want to do this
|
||||||
p.catchingUp = true
|
p.catchingUp = true
|
||||||
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(10)})
|
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(30)})
|
||||||
p.QueueMessage(msg)
|
p.QueueMessage(msg)
|
||||||
|
|
||||||
peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr())
|
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