Merge branch 'release/0.5.15'
This commit is contained in:
commit
9d5a3f0131
@ -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 5.0 RC14". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
|
of Concept 0.5.15". 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.
|
||||||
|
@ -18,7 +18,7 @@ func Disassemble(script []byte) (asm []string) {
|
|||||||
// Get the opcode (it must be an opcode!)
|
// Get the opcode (it must be an opcode!)
|
||||||
op := OpCode(val)
|
op := OpCode(val)
|
||||||
|
|
||||||
asm = append(asm, fmt.Sprintf("%v", op))
|
asm = append(asm, fmt.Sprintf("%04v: %v", pc, op))
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
|
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
|
||||||
@ -28,7 +28,7 @@ func Disassemble(script []byte) (asm []string) {
|
|||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
data = []byte{0}
|
data = []byte{0}
|
||||||
}
|
}
|
||||||
asm = append(asm, fmt.Sprintf("0x%x", data))
|
asm = append(asm, fmt.Sprintf("%04v: 0x%x", pc, data))
|
||||||
|
|
||||||
pc.Add(pc, big.NewInt(a-1))
|
pc.Add(pc, big.NewInt(a-1))
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@ package ethchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var chainlogger = ethlog.NewLogger("CHAIN")
|
||||||
|
|
||||||
type BlockChain struct {
|
type BlockChain struct {
|
||||||
Ethereum EthManager
|
Ethereum EthManager
|
||||||
// The famous, the fabulous Mister GENESIIIIIIS (block)
|
// The famous, the fabulous Mister GENESIIIIIIS (block)
|
||||||
@ -129,38 +131,38 @@ func (bc *BlockChain) FindCanonicalChain(blocks []*Block, commonBlockHash []byte
|
|||||||
// Start with the newest block we got, all the way back to the common block we both know
|
// Start with the newest block we got, all the way back to the common block we both know
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
if bytes.Compare(block.Hash(), commonBlockHash) == 0 {
|
if bytes.Compare(block.Hash(), commonBlockHash) == 0 {
|
||||||
log.Println("[CHAIN] We have found the common parent block, breaking")
|
chainlogger.Infoln("[CHAIN] We have found the common parent block, breaking")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
chainDifficulty.Add(chainDifficulty, bc.CalculateBlockTD(block))
|
chainDifficulty.Add(chainDifficulty, bc.CalculateBlockTD(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("[CHAIN] Incoming chain difficulty:", chainDifficulty)
|
chainlogger.Infoln("Incoming chain difficulty:", chainDifficulty)
|
||||||
|
|
||||||
curChainDifficulty := new(big.Int)
|
curChainDifficulty := new(big.Int)
|
||||||
block := bc.CurrentBlock
|
block := bc.CurrentBlock
|
||||||
for i := 0; block != nil; block = bc.GetBlock(block.PrevHash) {
|
for i := 0; block != nil; block = bc.GetBlock(block.PrevHash) {
|
||||||
i++
|
i++
|
||||||
if bytes.Compare(block.Hash(), commonBlockHash) == 0 {
|
if bytes.Compare(block.Hash(), commonBlockHash) == 0 {
|
||||||
log.Println("[CHAIN] We have found the common parent block, breaking")
|
chainlogger.Infoln("We have found the common parent block, breaking")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
anOtherBlock := bc.GetBlock(block.PrevHash)
|
anOtherBlock := bc.GetBlock(block.PrevHash)
|
||||||
if anOtherBlock == nil {
|
if anOtherBlock == nil {
|
||||||
// We do not want to count the genesis block for difficulty since that's not being sent
|
// We do not want to count the genesis block for difficulty since that's not being sent
|
||||||
log.Println("[CHAIN] At genesis block, breaking")
|
chainlogger.Infoln("At genesis block, breaking")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
curChainDifficulty.Add(curChainDifficulty, bc.CalculateBlockTD(block))
|
curChainDifficulty.Add(curChainDifficulty, bc.CalculateBlockTD(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("[CHAIN] Current chain difficulty:", curChainDifficulty)
|
chainlogger.Infoln("Current chain difficulty:", curChainDifficulty)
|
||||||
if chainDifficulty.Cmp(curChainDifficulty) == 1 {
|
if chainDifficulty.Cmp(curChainDifficulty) == 1 {
|
||||||
log.Printf("[CHAIN] The incoming Chain beat our asses, resetting to block: %x", commonBlockHash)
|
chainlogger.Infof("The incoming Chain beat our asses, resetting to block: %x", commonBlockHash)
|
||||||
bc.ResetTillBlockHash(commonBlockHash)
|
bc.ResetTillBlockHash(commonBlockHash)
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
log.Println("[CHAIN] Our chain showed the incoming chain who is boss. Ignoring.")
|
chainlogger.Infoln("Our chain showed the incoming chain who is boss. Ignoring.")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,18 +176,12 @@ func (bc *BlockChain) ResetTillBlockHash(hash []byte) error {
|
|||||||
bc.LastBlockHash = bc.genesisBlock.Hash()
|
bc.LastBlockHash = bc.genesisBlock.Hash()
|
||||||
bc.LastBlockNumber = 1
|
bc.LastBlockNumber = 1
|
||||||
} else {
|
} else {
|
||||||
// TODO: Somehow this doesn't really give the right numbers, double check.
|
|
||||||
// TODO: Change logs into debug lines
|
|
||||||
returnTo = bc.GetBlock(hash)
|
returnTo = bc.GetBlock(hash)
|
||||||
bc.CurrentBlock = returnTo
|
bc.CurrentBlock = returnTo
|
||||||
bc.LastBlockHash = returnTo.Hash()
|
bc.LastBlockHash = returnTo.Hash()
|
||||||
//info := bc.BlockInfo(returnTo)
|
|
||||||
bc.LastBlockNumber = returnTo.Number.Uint64()
|
bc.LastBlockNumber = returnTo.Number.Uint64()
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Why are we resetting? This is the block chain, it has nothing to do with states
|
|
||||||
//bc.Ethereum.StateManager().PrepareDefault(returnTo)
|
|
||||||
|
|
||||||
// Manually reset the last sync block
|
// Manually reset the last sync block
|
||||||
err := ethutil.Config.Db.Delete(lastBlock.Hash())
|
err := ethutil.Config.Db.Delete(lastBlock.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -195,7 +191,7 @@ func (bc *BlockChain) ResetTillBlockHash(hash []byte) error {
|
|||||||
var block *Block
|
var block *Block
|
||||||
for ; block != nil; block = bc.GetBlock(block.PrevHash) {
|
for ; block != nil; block = bc.GetBlock(block.PrevHash) {
|
||||||
if bytes.Compare(block.Hash(), hash) == 0 {
|
if bytes.Compare(block.Hash(), hash) == 0 {
|
||||||
log.Println("[CHAIN] We have arrived at the the common parent block, breaking")
|
chainlogger.Infoln("We have arrived at the the common parent block, breaking")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = ethutil.Config.Db.Delete(block.Hash())
|
err = ethutil.Config.Db.Delete(block.Hash())
|
||||||
@ -203,7 +199,7 @@ func (bc *BlockChain) ResetTillBlockHash(hash []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Println("[CHAIN] Split chain deleted and reverted to common parent block.")
|
chainlogger.Infoln("Split chain deleted and reverted to common parent block.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,6 +227,11 @@ func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} {
|
|||||||
for i := uint64(0); bytes.Compare(currentHash, hash) != 0 && num >= parentNumber && i < count; i++ {
|
for i := uint64(0); bytes.Compare(currentHash, hash) != 0 && num >= parentNumber && i < count; i++ {
|
||||||
// Get the block of the chain
|
// Get the block of the chain
|
||||||
block := bc.GetBlock(currentHash)
|
block := bc.GetBlock(currentHash)
|
||||||
|
if block == nil {
|
||||||
|
chainlogger.Debugf("Unexpected error during GetChainFromHash: Unable to find %x\n", currentHash)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
currentHash = block.PrevHash
|
currentHash = block.PrevHash
|
||||||
|
|
||||||
chain = append(chain, block.Value().Val)
|
chain = append(chain, block.Value().Val)
|
||||||
@ -286,7 +287,7 @@ func (bc *BlockChain) setLastBlock() {
|
|||||||
bc.LastBlockHash = block.Hash()
|
bc.LastBlockHash = block.Hash()
|
||||||
bc.LastBlockNumber = block.Number.Uint64()
|
bc.LastBlockNumber = block.Number.Uint64()
|
||||||
|
|
||||||
ethutil.Config.Log.Infof("[CHAIN] Last known block height #%d\n", bc.LastBlockNumber)
|
chainlogger.Infof("Last known block height #%d\n", bc.LastBlockNumber)
|
||||||
} else {
|
} else {
|
||||||
AddTestNetFunds(bc.genesisBlock)
|
AddTestNetFunds(bc.genesisBlock)
|
||||||
|
|
||||||
@ -294,14 +295,14 @@ func (bc *BlockChain) setLastBlock() {
|
|||||||
// Prepare the genesis block
|
// Prepare the genesis block
|
||||||
bc.Add(bc.genesisBlock)
|
bc.Add(bc.genesisBlock)
|
||||||
|
|
||||||
//log.Printf("root %x\n", bm.bc.genesisBlock.State().Root)
|
//chainlogger.Infof("root %x\n", bm.bc.genesisBlock.State().Root)
|
||||||
//bm.bc.genesisBlock.PrintHash()
|
//bm.bc.genesisBlock.PrintHash()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
|
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
|
||||||
bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
|
bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
|
||||||
|
|
||||||
ethutil.Config.Log.Infof("Last block: %x\n", bc.CurrentBlock.Hash())
|
chainlogger.Infof("Last block: %x\n", bc.CurrentBlock.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BlockChain) SetTotalDifficulty(td *big.Int) {
|
func (bc *BlockChain) SetTotalDifficulty(td *big.Int) {
|
||||||
@ -358,6 +359,6 @@ func (bc *BlockChain) writeBlockInfo(block *Block) {
|
|||||||
|
|
||||||
func (bc *BlockChain) Stop() {
|
func (bc *BlockChain) Stop() {
|
||||||
if bc.CurrentBlock != nil {
|
if bc.CurrentBlock != nil {
|
||||||
log.Println("[CHAIN] Stopped")
|
chainlogger.Infoln("Stopped")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
package ethchain
|
package ethchain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/obscuren/sha3"
|
"github.com/obscuren/sha3"
|
||||||
"hash"
|
"hash"
|
||||||
"log"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var powlogger = ethlog.NewLogger("POW")
|
||||||
|
|
||||||
type PoW interface {
|
type PoW interface {
|
||||||
Search(block *Block, reactChan chan ethutil.React) []byte
|
Search(block *Block, reactChan chan ethutil.React) []byte
|
||||||
Verify(hash []byte, diff *big.Int, nonce []byte) bool
|
Verify(hash []byte, diff *big.Int, nonce []byte) bool
|
||||||
@ -29,14 +31,13 @@ func (pow *EasyPow) Search(block *Block, reactChan chan ethutil.React) []byte {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-reactChan:
|
case <-reactChan:
|
||||||
//ethutil.Config.Log.Infoln("[POW] Received reactor event; breaking out.")
|
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
i++
|
i++
|
||||||
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
|
||||||
ethutil.Config.Log.Infoln("[POW] Hashing @", int64(hashes), "khash")
|
powlogger.Infoln("Hashing @", int64(hashes), "khash")
|
||||||
}
|
}
|
||||||
|
|
||||||
sha := ethutil.Sha3Bin(big.NewInt(r.Int63()).Bytes())
|
sha := ethutil.Sha3Bin(big.NewInt(r.Int63()).Bytes())
|
||||||
@ -81,7 +82,7 @@ func (dag *Dagger) Find(obj *big.Int, resChan chan int64) {
|
|||||||
rnd := r.Int63()
|
rnd := r.Int63()
|
||||||
|
|
||||||
res := dag.Eval(big.NewInt(rnd))
|
res := dag.Eval(big.NewInt(rnd))
|
||||||
log.Printf("rnd %v\nres %v\nobj %v\n", rnd, res, obj)
|
powlogger.Infof("rnd %v\nres %v\nobj %v\n", rnd, res, obj)
|
||||||
if res.Cmp(obj) < 0 {
|
if res.Cmp(obj) < 0 {
|
||||||
// Post back result on the channel
|
// Post back result on the channel
|
||||||
resChan <- rnd
|
resChan <- rnd
|
||||||
|
@ -125,7 +125,7 @@ func (self *State) GetOrNewStateObject(addr []byte) *StateObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *State) NewStateObject(addr []byte) *StateObject {
|
func (self *State) NewStateObject(addr []byte) *StateObject {
|
||||||
ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(+) %x\n", addr)
|
statelogger.Infof("(+) %x\n", addr)
|
||||||
|
|
||||||
stateObject := NewStateObject(addr)
|
stateObject := NewStateObject(addr)
|
||||||
self.stateObjects[string(addr)] = stateObject
|
self.stateObjects[string(addr)] = stateObject
|
||||||
|
@ -3,7 +3,7 @@ package ethchain
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"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"
|
||||||
@ -11,6 +11,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var statelogger = ethlog.NewLogger("STATE")
|
||||||
|
|
||||||
type BlockProcessor interface {
|
type BlockProcessor interface {
|
||||||
ProcessBlock(block *Block)
|
ProcessBlock(block *Block)
|
||||||
}
|
}
|
||||||
@ -120,7 +122,7 @@ done:
|
|||||||
|
|
||||||
break done
|
break done
|
||||||
default:
|
default:
|
||||||
ethutil.Config.Log.Infoln(err)
|
statelogger.Infoln(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,27 +145,23 @@ done:
|
|||||||
return receipts, handled, unhandled, err
|
return receipts, handled, unhandled, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) Process(block *Block, dontReact bool) error {
|
func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
||||||
|
// Processing a blocks may never happen simultaneously
|
||||||
|
sm.mutex.Lock()
|
||||||
|
defer sm.mutex.Unlock()
|
||||||
|
|
||||||
|
if sm.bc.HasBlock(block.Hash()) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if !sm.bc.HasBlock(block.PrevHash) {
|
if !sm.bc.HasBlock(block.PrevHash) {
|
||||||
return ParentError(block.PrevHash)
|
return ParentError(block.PrevHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
parent := sm.bc.GetBlock(block.PrevHash)
|
var (
|
||||||
|
parent = sm.bc.GetBlock(block.PrevHash)
|
||||||
return sm.ProcessBlock(parent.State(), parent, block, dontReact)
|
state = parent.State()
|
||||||
|
)
|
||||||
}
|
|
||||||
|
|
||||||
// Block processing and validating with a given (temporarily) state
|
|
||||||
func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontReact bool) (err error) {
|
|
||||||
// Processing a blocks may never happen simultaneously
|
|
||||||
sm.mutex.Lock()
|
|
||||||
defer sm.mutex.Unlock()
|
|
||||||
hash := block.Hash()
|
|
||||||
|
|
||||||
if sm.bc.HasBlock(hash) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defer the Undo on the Trie. If the block processing happened
|
// Defer the Undo on the Trie. If the block processing happened
|
||||||
// we don't want to undo but since undo only happens on dirty
|
// we don't want to undo but since undo only happens on dirty
|
||||||
@ -171,44 +169,38 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
|
|||||||
// before that.
|
// before that.
|
||||||
defer state.Reset()
|
defer state.Reset()
|
||||||
|
|
||||||
// Check if we have the parent hash, if it isn't known we discard it
|
receipts, err := sm.ApplyDiff(state, parent, block)
|
||||||
// Reasons might be catching up or simply an invalid block
|
|
||||||
if !sm.bc.HasBlock(block.PrevHash) && sm.bc.CurrentBlock != nil {
|
|
||||||
return ParentError(block.PrevHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
coinbase := state.GetOrNewStateObject(block.Coinbase)
|
|
||||||
coinbase.SetGasPool(block.CalcGasLimit(parent))
|
|
||||||
|
|
||||||
// Process the transactions on to current block
|
|
||||||
receipts, _, _, _ := sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if len(receipts) == len(block.Receipts()) {
|
if len(receipts) == len(block.Receipts()) {
|
||||||
for i, receipt := range block.Receipts() {
|
for i, receipt := range block.Receipts() {
|
||||||
ethutil.Config.Log.Debugf("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())
|
statelogger.Debugf("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 {
|
} else {
|
||||||
ethutil.Config.Log.Debugln("Unable to print receipt diff. Length didn't match", len(receipts), "for", len(block.Receipts()))
|
statelogger.Warnln("Unable to print receipt diff. Length didn't match", len(receipts), "for", len(block.Receipts()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Block validation
|
// Block validation
|
||||||
if err = sm.ValidateBlock(block); err != nil {
|
if err = sm.ValidateBlock(block); err != nil {
|
||||||
fmt.Println("[SM] Error validating block:", err)
|
statelogger.Errorln("Error validating block:", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// I'm not sure, but I don't know if there should be thrown
|
// I'm not sure, but I don't know if there should be thrown
|
||||||
// any errors at this time.
|
// any errors at this time.
|
||||||
if err = sm.AccumelateRewards(state, block); err != nil {
|
if err = sm.AccumelateRewards(state, block); err != nil {
|
||||||
fmt.Println("[SM] Error accumulating reward", err)
|
statelogger.Errorln("Error accumulating reward", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !block.State().Cmp(state) {
|
if !block.State().Cmp(state) {
|
||||||
err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root)
|
statelogger.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +213,7 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
|
|||||||
sm.bc.Add(block)
|
sm.bc.Add(block)
|
||||||
sm.notifyChanges(state)
|
sm.notifyChanges(state)
|
||||||
|
|
||||||
ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.Number, block.Hash())
|
statelogger.Infof("Added block #%d (%x)\n", block.Number, block.Hash())
|
||||||
if dontReact == false {
|
if dontReact == false {
|
||||||
sm.Ethereum.Reactor().Post("newBlock", block)
|
sm.Ethereum.Reactor().Post("newBlock", block)
|
||||||
|
|
||||||
@ -232,11 +224,22 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
|
|||||||
|
|
||||||
sm.Ethereum.TxPool().RemoveInvalid(state)
|
sm.Ethereum.TxPool().RemoveInvalid(state)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("total diff failed")
|
statelogger.Errorln("total diff failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sm *StateManager) ApplyDiff(state *State, parent, block *Block) (receipts Receipts, err error) {
|
||||||
|
coinbase := state.GetOrNewStateObject(block.Coinbase)
|
||||||
|
coinbase.SetGasPool(block.CalcGasLimit(parent))
|
||||||
|
|
||||||
|
// Process the transactions on to current block
|
||||||
|
receipts, _, _, _ = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
|
||||||
|
|
||||||
|
return receipts, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (sm *StateManager) CalculateTD(block *Block) bool {
|
func (sm *StateManager) CalculateTD(block *Block) bool {
|
||||||
uncleDiff := new(big.Int)
|
uncleDiff := new(big.Int)
|
||||||
for _, uncle := range block.Uncles {
|
for _, uncle := range block.Uncles {
|
||||||
|
@ -90,7 +90,13 @@ func (c *StateObject) SetAddr(addr []byte, value interface{}) {
|
|||||||
|
|
||||||
func (c *StateObject) SetStorage(num *big.Int, val *ethutil.Value) {
|
func (c *StateObject) SetStorage(num *big.Int, val *ethutil.Value) {
|
||||||
addr := ethutil.BigToBytes(num, 256)
|
addr := ethutil.BigToBytes(num, 256)
|
||||||
//fmt.Printf("sstore %x => %v\n", addr, val)
|
|
||||||
|
if val.BigInt().Cmp(ethutil.Big0) == 0 {
|
||||||
|
c.state.trie.Delete(string(addr))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.SetAddr(addr, val)
|
c.SetAddr(addr, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +130,13 @@ func (c *StateObject) ReturnGas(gas, price *big.Int, state *State) {
|
|||||||
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))
|
||||||
|
|
||||||
ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.Amount, amount)
|
statelogger.Infof("%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))
|
||||||
|
|
||||||
ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.Amount, amount)
|
statelogger.Infof("%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) {
|
||||||
@ -151,7 +157,7 @@ func (c *StateObject) ConvertGas(gas, price *big.Int) error {
|
|||||||
func (self *StateObject) SetGasPool(gasLimit *big.Int) {
|
func (self *StateObject) SetGasPool(gasLimit *big.Int) {
|
||||||
self.gasPool = new(big.Int).Set(gasLimit)
|
self.gasPool = new(big.Int).Set(gasLimit)
|
||||||
|
|
||||||
ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "%x: fuel (+ %v)", self.Address(), self.gasPool)
|
statelogger.DebugDetailf("%x: fuel (+ %v)", self.Address(), self.gasPool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) BuyGas(gas, price *big.Int) error {
|
func (self *StateObject) BuyGas(gas, price *big.Int) error {
|
||||||
|
@ -2,7 +2,6 @@ package ethchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -135,12 +134,12 @@ func (self *StateTransition) preCheck() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) TransitionState() (err error) {
|
func (self *StateTransition) TransitionState() (err error) {
|
||||||
ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", self.tx.Hash())
|
statelogger.Infof("(~) %x\n", self.tx.Hash())
|
||||||
|
|
||||||
/*
|
/*
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
ethutil.Config.Log.Infoln(r)
|
logger.Infoln(r)
|
||||||
err = fmt.Errorf("state transition err %v", r)
|
err = fmt.Errorf("state transition err %v", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -231,7 +230,7 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error
|
|||||||
// Add the amount to receivers account which should conclude this transaction
|
// Add the amount to receivers account which should conclude this transaction
|
||||||
receiver.AddAmount(self.value)
|
receiver.AddAmount(self.value)
|
||||||
|
|
||||||
//ethutil.Config.Log.Debugf("%x => %x (%v)\n", sender.Address()[:4], receiver.Address()[:4], self.value)
|
//statelogger.Debugf("%x => %x (%v)\n", sender.Address()[:4], receiver.Address()[:4], self.value)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -89,11 +89,12 @@ func (tx *Transaction) Signature(key []byte) []byte {
|
|||||||
func (tx *Transaction) PublicKey() []byte {
|
func (tx *Transaction) PublicKey() []byte {
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
|
|
||||||
// If we don't make a copy we will overwrite the existing underlying array
|
r := make([]byte, 32-len(tx.r))
|
||||||
dst := make([]byte, len(tx.r))
|
s := make([]byte, 32-len(tx.s))
|
||||||
copy(dst, tx.r)
|
r = append(r, ethutil.CopyBytes(tx.r)...)
|
||||||
|
s = append(s, ethutil.CopyBytes(tx.s)...)
|
||||||
|
|
||||||
sig := append(dst, tx.s...)
|
sig := append(r, s...)
|
||||||
sig = append(sig, tx.v-27)
|
sig = append(sig, tx.v-27)
|
||||||
|
|
||||||
pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
|
pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
|
||||||
@ -127,6 +128,8 @@ func (tx *Transaction) Sign(privk []byte) error {
|
|||||||
func (tx *Transaction) RlpData() interface{} {
|
func (tx *Transaction) RlpData() interface{} {
|
||||||
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
|
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
|
||||||
|
|
||||||
|
// TODO Remove prefixing zero's
|
||||||
|
|
||||||
return append(data, tx.v, tx.r, tx.s)
|
return append(data, tx.v, tx.r, tx.s)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +153,7 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
|
|||||||
tx.Value = decoder.Get(4).BigInt()
|
tx.Value = decoder.Get(4).BigInt()
|
||||||
tx.Data = decoder.Get(5).Bytes()
|
tx.Data = decoder.Get(5).Bytes()
|
||||||
tx.v = byte(decoder.Get(6).Uint())
|
tx.v = byte(decoder.Get(6).Uint())
|
||||||
|
|
||||||
tx.r = decoder.Get(7).Bytes()
|
tx.r = decoder.Get(7).Bytes()
|
||||||
tx.s = decoder.Get(8).Bytes()
|
tx.s = decoder.Get(8).Bytes()
|
||||||
|
|
||||||
|
@ -3,15 +3,15 @@ package ethchain
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"log"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var txplogger = ethlog.NewLogger("TXP")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
txPoolQueueSize = 50
|
txPoolQueueSize = 50
|
||||||
)
|
)
|
||||||
@ -97,7 +97,7 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, state *State, toContract
|
|||||||
fmt.Printf("state root before update %x\n", state.Root())
|
fmt.Printf("state root before update %x\n", state.Root())
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
ethutil.Config.Log.Infoln(r)
|
txplogger.Infoln(r)
|
||||||
err = fmt.Errorf("%v", r)
|
err = fmt.Errorf("%v", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -156,7 +156,7 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, state *State, toContract
|
|||||||
fmt.Printf("state root after receiver update %x\n", state.Root())
|
fmt.Printf("state root after receiver update %x\n", state.Root())
|
||||||
}
|
}
|
||||||
|
|
||||||
ethutil.Config.Log.Infof("[TXPL] Processed Tx %x\n", tx.Hash())
|
txplogger.Infof("[TXPL] Processed Tx %x\n", tx.Hash())
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error {
|
|||||||
block := pool.Ethereum.BlockChain().CurrentBlock
|
block := pool.Ethereum.BlockChain().CurrentBlock
|
||||||
// Something has gone horribly wrong if this happens
|
// Something has gone horribly wrong if this happens
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return errors.New("[TXPL] No last block on the block chain")
|
return fmt.Errorf("[TXPL] No last block on the block chain")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tx.Recipient) != 20 {
|
if len(tx.Recipient) != 20 {
|
||||||
@ -188,7 +188,7 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error {
|
|||||||
|
|
||||||
if tx.IsContract() {
|
if tx.IsContract() {
|
||||||
if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 {
|
if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 {
|
||||||
return fmt.Errorf("[TXPL] Gasprice to low, %s given should be at least %d.", tx.GasPrice, minGasPrice)
|
return fmt.Errorf("[TXPL] Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,12 +215,12 @@ out:
|
|||||||
// Validate the transaction
|
// Validate the transaction
|
||||||
err := pool.ValidateTransaction(tx)
|
err := pool.ValidateTransaction(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("Validating Tx failed", err)
|
txplogger.Debugln("Validating Tx failed", err)
|
||||||
} else {
|
} else {
|
||||||
// Call blocking version.
|
// Call blocking version.
|
||||||
pool.addTransaction(tx)
|
pool.addTransaction(tx)
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tx.Recipient[:4], tx.Value, tx.Hash())
|
txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tx.Recipient[:4], tx.Value, tx.Hash())
|
||||||
|
|
||||||
// Notify the subscribers
|
// Notify the subscribers
|
||||||
pool.Ethereum.Reactor().Post("newTx:pre", tx)
|
pool.Ethereum.Reactor().Post("newTx:pre", tx)
|
||||||
@ -282,5 +282,5 @@ func (pool *TxPool) Stop() {
|
|||||||
|
|
||||||
pool.Flush()
|
pool.Flush()
|
||||||
|
|
||||||
log.Println("[TXP] Stopped")
|
txplogger.Infoln("Stopped")
|
||||||
}
|
}
|
||||||
|
114
ethchain/vm.go
114
ethchain/vm.go
@ -2,11 +2,14 @@ package ethchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var vmlogger = ethlog.NewLogger("VM")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
GasStep = big.NewInt(1)
|
GasStep = big.NewInt(1)
|
||||||
GasSha = big.NewInt(20)
|
GasSha = big.NewInt(20)
|
||||||
@ -72,7 +75,7 @@ func (self *Vm) Printf(format string, v ...interface{}) *Vm {
|
|||||||
|
|
||||||
func (self *Vm) Endl() *Vm {
|
func (self *Vm) Endl() *Vm {
|
||||||
if self.Verbose {
|
if self.Verbose {
|
||||||
ethutil.Config.Log.Infoln(self.logStr)
|
vmlogger.Infoln(self.logStr)
|
||||||
self.logStr = ""
|
self.logStr = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,28 +96,27 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
ret = closure.Return(nil)
|
ret = closure.Return(nil)
|
||||||
err = fmt.Errorf("%v", r)
|
err = fmt.Errorf("%v", r)
|
||||||
fmt.Println("vm err", err)
|
vmlogger.Errorln("vm err", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("[VM] (~) %x gas: %v (d) %x\n", closure.object.Address(), closure.Gas, closure.Args)
|
vmlogger.Debugf("(~) %x gas: %v (d) %x\n", closure.object.Address(), closure.Gas, closure.Args)
|
||||||
|
|
||||||
// Memory for the current closure
|
var (
|
||||||
mem := &Memory{}
|
op OpCode
|
||||||
// New stack (should this be shared?)
|
|
||||||
stack := NewStack()
|
mem = &Memory{}
|
||||||
require := func(m int) {
|
stack = NewStack()
|
||||||
if stack.Len() < m {
|
pc = big.NewInt(0)
|
||||||
isRequireError = true
|
step = 0
|
||||||
panic(fmt.Sprintf("stack = %d, req = %d", stack.Len(), m))
|
prevStep = 0
|
||||||
|
require = func(m int) {
|
||||||
|
if stack.Len() < m {
|
||||||
|
isRequireError = true
|
||||||
|
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
|
||||||
// Instruction pointer
|
|
||||||
pc := big.NewInt(0)
|
|
||||||
// Current step count
|
|
||||||
step := 0
|
|
||||||
prevStep := 0
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
prevStep = step
|
prevStep = step
|
||||||
@ -125,7 +127,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
// Get the memory location of pc
|
// Get the memory location of pc
|
||||||
val := closure.Get(pc)
|
val := closure.Get(pc)
|
||||||
// Get the opcode (it must be an opcode!)
|
// Get the opcode (it must be an opcode!)
|
||||||
op := OpCode(val.Uint())
|
op = OpCode(val.Uint())
|
||||||
|
|
||||||
gas := new(big.Int)
|
gas := new(big.Int)
|
||||||
addStepGasUsage := func(amount *big.Int) {
|
addStepGasUsage := func(amount *big.Int) {
|
||||||
@ -325,21 +327,21 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case LT:
|
case LT:
|
||||||
require(2)
|
require(2)
|
||||||
y, x := stack.Popn()
|
x, y := stack.Popn()
|
||||||
vm.Printf(" %v < %v", x, y)
|
vm.Printf(" %v < %v", y, x)
|
||||||
// x < y
|
// x < y
|
||||||
if x.Cmp(y) < 0 {
|
if y.Cmp(x) < 0 {
|
||||||
stack.Push(ethutil.BigTrue)
|
stack.Push(ethutil.BigTrue)
|
||||||
} else {
|
} else {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
}
|
}
|
||||||
case GT:
|
case GT:
|
||||||
require(2)
|
require(2)
|
||||||
y, x := stack.Popn()
|
x, y := stack.Popn()
|
||||||
vm.Printf(" %v > %v", x, y)
|
vm.Printf(" %v > %v", y, x)
|
||||||
|
|
||||||
// x > y
|
// x > y
|
||||||
if x.Cmp(y) > 0 {
|
if y.Cmp(x) > 0 {
|
||||||
stack.Push(ethutil.BigTrue)
|
stack.Push(ethutil.BigTrue)
|
||||||
} else {
|
} else {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
@ -358,10 +360,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
case NOT:
|
case NOT:
|
||||||
require(1)
|
require(1)
|
||||||
x := stack.Pop()
|
x := stack.Pop()
|
||||||
if x.Cmp(ethutil.BigFalse) == 0 {
|
if x.Cmp(ethutil.BigFalse) > 0 {
|
||||||
stack.Push(ethutil.BigTrue)
|
|
||||||
} else {
|
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
} else {
|
||||||
|
stack.Push(ethutil.BigTrue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x10 range
|
// 0x10 range
|
||||||
@ -433,9 +435,28 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
|
|
||||||
vm.Printf(" => %d", l)
|
vm.Printf(" => %d", l)
|
||||||
case CALLDATACOPY:
|
case CALLDATACOPY:
|
||||||
panic("not implemented")
|
var (
|
||||||
|
size = int64(len(closure.Args))
|
||||||
|
mOff = stack.Pop().Int64()
|
||||||
|
cOff = stack.Pop().Int64()
|
||||||
|
l = stack.Pop().Int64()
|
||||||
|
)
|
||||||
|
|
||||||
|
if cOff > size {
|
||||||
|
cOff = 0
|
||||||
|
l = 0
|
||||||
|
} else if cOff+l > size {
|
||||||
|
l = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
code := closure.Args[cOff : cOff+l]
|
||||||
|
|
||||||
|
mem.Set(mOff, l, code)
|
||||||
case CODESIZE:
|
case CODESIZE:
|
||||||
stack.Push(big.NewInt(int64(len(closure.Script))))
|
l := big.NewInt(int64(len(closure.Script)))
|
||||||
|
stack.Push(l)
|
||||||
|
|
||||||
|
vm.Printf(" => %d", l)
|
||||||
case CODECOPY:
|
case CODECOPY:
|
||||||
var (
|
var (
|
||||||
size = int64(len(closure.Script))
|
size = int64(len(closure.Script))
|
||||||
@ -501,7 +522,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
case MLOAD:
|
case MLOAD:
|
||||||
require(1)
|
require(1)
|
||||||
offset := stack.Pop()
|
offset := stack.Pop()
|
||||||
stack.Push(ethutil.BigD(mem.Get(offset.Int64(), 32)))
|
val := ethutil.BigD(mem.Get(offset.Int64(), 32))
|
||||||
|
stack.Push(val)
|
||||||
|
|
||||||
|
vm.Printf(" => 0x%x", val.Bytes())
|
||||||
case MSTORE: // Store the value at stack top-1 in to memory at location stack top
|
case MSTORE: // Store the value at stack top-1 in to memory at location stack top
|
||||||
require(2)
|
require(2)
|
||||||
// Pop value of the stack
|
// Pop value of the stack
|
||||||
@ -520,17 +544,14 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
require(1)
|
require(1)
|
||||||
loc := stack.Pop()
|
loc := stack.Pop()
|
||||||
val := closure.GetMem(loc)
|
val := closure.GetMem(loc)
|
||||||
|
|
||||||
stack.Push(val.BigInt())
|
stack.Push(val.BigInt())
|
||||||
|
|
||||||
vm.Printf(" {} 0x%x", val)
|
vm.Printf(" {0x%x} 0x%x", loc.Bytes(), val.Bytes())
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
require(2)
|
require(2)
|
||||||
val, loc := stack.Popn()
|
val, loc := stack.Popn()
|
||||||
|
closure.SetStorage(loc, ethutil.NewValue(val))
|
||||||
// FIXME This should be handled in the Trie it self
|
|
||||||
if val.Cmp(big.NewInt(0)) != 0 {
|
|
||||||
closure.SetStorage(loc, ethutil.NewValue(val))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the change to manifest
|
// Add the change to manifest
|
||||||
vm.state.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val)
|
vm.state.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val)
|
||||||
@ -574,14 +595,18 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
|
|
||||||
// Generate a new address
|
// Generate a new address
|
||||||
addr := ethutil.CreateAddress(closure.caller.Address(), closure.caller.N())
|
addr := ethutil.CreateAddress(closure.caller.Address(), closure.caller.N())
|
||||||
|
|
||||||
|
vm.Printf(" (*) %x", addr).Endl()
|
||||||
|
|
||||||
// Create a new contract
|
// Create a new contract
|
||||||
contract := NewContract(addr, value, []byte(""))
|
contract := vm.state.NewStateObject(addr)
|
||||||
|
contract.Amount = value
|
||||||
|
|
||||||
// Set the init script
|
// Set the init script
|
||||||
contract.initScript = mem.Get(offset.Int64(), size.Int64())
|
contract.initScript = ethutil.BigD(mem.Get(offset.Int64(), size.Int64())).Bytes()
|
||||||
// Transfer all remaining gas to the new
|
// Transfer all remaining gas to the new
|
||||||
// contract so it may run the init script
|
// contract so it may run the init script
|
||||||
gas := new(big.Int).Set(closure.Gas)
|
gas := new(big.Int).Set(closure.Gas)
|
||||||
//closure.UseGas(gas)
|
|
||||||
|
|
||||||
// Create the closure
|
// Create the closure
|
||||||
c := NewClosure(closure.caller,
|
c := NewClosure(closure.caller,
|
||||||
@ -592,6 +617,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
closure.Price)
|
closure.Price)
|
||||||
// Call the closure and set the return value as
|
// Call the closure and set the return value as
|
||||||
// main script.
|
// main script.
|
||||||
|
var err error
|
||||||
c.Script, gas, err = c.Call(vm, nil, hook)
|
c.Script, gas, err = c.Call(vm, nil, hook)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -619,7 +645,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
||||||
|
|
||||||
if closure.object.Amount.Cmp(value) < 0 {
|
if closure.object.Amount.Cmp(value) < 0 {
|
||||||
ethutil.Config.Log.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)
|
||||||
|
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
} else {
|
} else {
|
||||||
@ -638,7 +664,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("Closure execution failed. %v\n", err)
|
vmlogger.Debugf("Closure execution failed. %v\n", err)
|
||||||
|
|
||||||
vm.err = err
|
vm.err = err
|
||||||
vm.state.Set(snapshot)
|
vm.state.Set(snapshot)
|
||||||
@ -669,11 +695,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case STOP: // Stop the closure
|
case STOP: // Stop the closure
|
||||||
vm.Printf(" (g) %v", closure.Gas).Endl()
|
vm.Endl()
|
||||||
|
|
||||||
return closure.Return(nil), nil
|
return closure.Return(nil), nil
|
||||||
default:
|
default:
|
||||||
ethutil.Config.Log.Debugf("Invalid opcode %x\n", op)
|
vmlogger.Debugf("Invalid opcode %x\n", op)
|
||||||
|
|
||||||
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
|
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
|
||||||
}
|
}
|
||||||
|
38
ethereum.go
38
ethereum.go
@ -5,11 +5,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethdb"
|
"github.com/ethereum/eth-go/ethdb"
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethrpc"
|
"github.com/ethereum/eth-go/ethrpc"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -20,6 +20,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ethlogger = ethlog.NewLogger("SERV")
|
||||||
|
|
||||||
func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) {
|
func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) {
|
||||||
// Loop thru the peers and close them (if we had them)
|
// Loop thru the peers and close them (if we had them)
|
||||||
for e := peers.Front(); e != nil; e = e.Next() {
|
for e := peers.Front(); e != nil; e = e.Next() {
|
||||||
@ -85,7 +87,7 @@ func New(caps Caps, usePnp bool) (*Ethereum, error) {
|
|||||||
if usePnp {
|
if usePnp {
|
||||||
nat, err = Discover()
|
nat, err = Discover()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("UPnP failed", err)
|
ethlogger.Debugln("UPnP failed", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +165,7 @@ func (s *Ethereum) AddPeer(conn net.Conn) {
|
|||||||
if s.peers.Len() < s.MaxPeers {
|
if s.peers.Len() < s.MaxPeers {
|
||||||
peer.Start()
|
peer.Start()
|
||||||
} else {
|
} else {
|
||||||
ethutil.Config.Log.Debugf("[SERV] Max connected peers reached. Not adding incoming peer.")
|
ethlogger.Debugf("Max connected peers reached. Not adding incoming peer.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +225,7 @@ func (s *Ethereum) ConnectToPeer(addr string) error {
|
|||||||
|
|
||||||
if phost == chost {
|
if phost == chost {
|
||||||
alreadyConnected = true
|
alreadyConnected = true
|
||||||
//ethutil.Config.Log.Debugf("[SERV] Peer %s already added.\n", chost)
|
//ethlogger.Debugf("Peer %s already added.\n", chost)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -340,12 +342,12 @@ func (s *Ethereum) Start(seed bool) {
|
|||||||
// Bind to addr and port
|
// Bind to addr and port
|
||||||
ln, err := net.Listen("tcp", ":"+s.Port)
|
ln, err := net.Listen("tcp", ":"+s.Port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Connection listening disabled. Acting as client")
|
ethlogger.Warnf("Port %s in use. Connection listening disabled. Acting as client", s.Port)
|
||||||
s.listening = false
|
s.listening = false
|
||||||
} else {
|
} else {
|
||||||
s.listening = true
|
s.listening = true
|
||||||
// Starting accepting connections
|
// Starting accepting connections
|
||||||
ethutil.Config.Log.Infoln("Ready and accepting connections")
|
ethlogger.Infoln("Ready and accepting connections")
|
||||||
// Start the peer handler
|
// Start the peer handler
|
||||||
go s.peerHandler(ln)
|
go s.peerHandler(ln)
|
||||||
}
|
}
|
||||||
@ -360,10 +362,11 @@ func (s *Ethereum) Start(seed bool) {
|
|||||||
if seed {
|
if seed {
|
||||||
s.Seed()
|
s.Seed()
|
||||||
}
|
}
|
||||||
|
ethlogger.Infoln("Server started")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Ethereum) Seed() {
|
func (s *Ethereum) Seed() {
|
||||||
ethutil.Config.Log.Debugln("[SERV] Retrieving seed nodes")
|
ethlogger.Debugln("Retrieving seed nodes")
|
||||||
|
|
||||||
// Eth-Go Bootstrapping
|
// Eth-Go Bootstrapping
|
||||||
ips, er := net.LookupIP("seed.bysh.me")
|
ips, er := net.LookupIP("seed.bysh.me")
|
||||||
@ -371,7 +374,7 @@ func (s *Ethereum) Seed() {
|
|||||||
peers := []string{}
|
peers := []string{}
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
node := fmt.Sprintf("%s:%d", ip.String(), 30303)
|
node := fmt.Sprintf("%s:%d", ip.String(), 30303)
|
||||||
ethutil.Config.Log.Debugln("[SERV] Found DNS Go Peer:", node)
|
ethlogger.Debugln("Found DNS Go Peer:", node)
|
||||||
peers = append(peers, node)
|
peers = append(peers, node)
|
||||||
}
|
}
|
||||||
s.ProcessPeerList(peers)
|
s.ProcessPeerList(peers)
|
||||||
@ -391,11 +394,11 @@ func (s *Ethereum) Seed() {
|
|||||||
for _, a := range addr {
|
for _, a := range addr {
|
||||||
// Build string out of SRV port and Resolved IP
|
// Build string out of SRV port and Resolved IP
|
||||||
peer := net.JoinHostPort(a, port)
|
peer := net.JoinHostPort(a, port)
|
||||||
ethutil.Config.Log.Debugln("[SERV] Found DNS Bootstrap Peer:", peer)
|
ethlogger.Debugln("Found DNS Bootstrap Peer:", peer)
|
||||||
peers = append(peers, peer)
|
peers = append(peers, peer)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ethutil.Config.Log.Debugln("[SERV} Couldn't resolve :", target)
|
ethlogger.Debugln("Couldn't resolve :", target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Connect to Peer list
|
// Connect to Peer list
|
||||||
@ -404,13 +407,13 @@ func (s *Ethereum) Seed() {
|
|||||||
// Fallback to servers.poc3.txt
|
// Fallback to servers.poc3.txt
|
||||||
resp, err := http.Get("http://www.ethereum.org/servers.poc3.txt")
|
resp, err := http.Get("http://www.ethereum.org/servers.poc3.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Fetching seed failed:", err)
|
ethlogger.Warnln("Fetching seed failed:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Reading seed failed:", err)
|
ethlogger.Warnln("Reading seed failed:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +425,7 @@ func (s *Ethereum) peerHandler(listener net.Listener) {
|
|||||||
for {
|
for {
|
||||||
conn, err := listener.Accept()
|
conn, err := listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln(err)
|
ethlogger.Debugln(err)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -447,6 +450,7 @@ func (s *Ethereum) Stop() {
|
|||||||
s.txPool.Stop()
|
s.txPool.Stop()
|
||||||
s.stateManager.Stop()
|
s.stateManager.Stop()
|
||||||
|
|
||||||
|
ethlogger.Infoln("Server stopped")
|
||||||
close(s.shutdownChan)
|
close(s.shutdownChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,13 +472,13 @@ out:
|
|||||||
var err error
|
var err error
|
||||||
_, err = s.nat.AddPortMapping("TCP", int(lport), int(lport), "eth listen port", 20*60)
|
_, err = s.nat.AddPortMapping("TCP", int(lport), int(lport), "eth listen port", 20*60)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("can't add UPnP port mapping:", err)
|
ethlogger.Debugln("can't add UPnP port mapping:", err)
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
if first && err == nil {
|
if first && err == nil {
|
||||||
_, err = s.nat.GetExternalAddress()
|
_, err = s.nat.GetExternalAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("UPnP can't get external address:", err)
|
ethlogger.Debugln("UPnP can't get external address:", err)
|
||||||
continue out
|
continue out
|
||||||
}
|
}
|
||||||
first = false
|
first = false
|
||||||
@ -488,8 +492,8 @@ out:
|
|||||||
timer.Stop()
|
timer.Stop()
|
||||||
|
|
||||||
if err := s.nat.DeletePortMapping("TCP", int(lport), int(lport)); err != nil {
|
if err := s.nat.DeletePortMapping("TCP", int(lport), int(lport)); err != nil {
|
||||||
ethutil.Config.Log.Debugln("unable to remove UPnP port mapping:", err)
|
ethlogger.Debugln("unable to remove UPnP port mapping:", err)
|
||||||
} else {
|
} else {
|
||||||
ethutil.Config.Log.Debugln("succesfully disestablished UPnP port mapping")
|
ethlogger.Debugln("succesfully disestablished UPnP port mapping")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
62
ethlog/README.md
Normal file
62
ethlog/README.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
## Features
|
||||||
|
|
||||||
|
- packages use tagged logger sending log messages to shared (process-wide) logging engine
|
||||||
|
- log writers (interface ethlog.LogSystem) can be added to the logging engine by wrappers/guis/clients
|
||||||
|
- shared logging engine dispatching to multiple log systems
|
||||||
|
- log level can be set separately per log system
|
||||||
|
- async logging thread: logging IO does not block main thread
|
||||||
|
- log messages are synchronously stringified to avoid incorrectly logging of changed states
|
||||||
|
- log level enum: ethlog.LogLevel: Silence, ErrorLevel, WarnLevel, InfoLevel, DebugLevel, DebugDetailLevel
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
In an ethereum component package:
|
||||||
|
|
||||||
|
import "github.com/ethereum/eth-go/ethlog"
|
||||||
|
|
||||||
|
// package-wide logger using tag
|
||||||
|
var logger = ethlog.NewLogger("TAG")
|
||||||
|
|
||||||
|
Logger provides named Printf and Println style methods for all loglevels
|
||||||
|
|
||||||
|
logger.Infoln("this is info") # > [TAG] This is info
|
||||||
|
logger.Infof("this %v is info", object) # > [TAG] This object is info
|
||||||
|
|
||||||
|
Ethereum wrappers should register log systems conforming to ethlog.LogSystem
|
||||||
|
|
||||||
|
import "github.com/ethereum/eth-go/ethlog"
|
||||||
|
|
||||||
|
type CustomLogWriter struct {
|
||||||
|
logLevel ethlog.LogLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestLogSystem) SetLogLevel(i LogLevel) {
|
||||||
|
t.level = i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestLogSystem) GetLogLevel() LogLevel {
|
||||||
|
return t.level
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CustomLogWriter) Printf(format string, v...interface{}) {
|
||||||
|
//....
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CustomLogWriter) Println(v...interface{}) {
|
||||||
|
//....
|
||||||
|
}
|
||||||
|
|
||||||
|
ethlog.AddLogWriter(&CustomLogWriter{})
|
||||||
|
|
||||||
|
ethlog also provides constructors for that wrap io.Writers into a standard logger with a settable level:
|
||||||
|
|
||||||
|
filename := "test.log"
|
||||||
|
file, _ := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
||||||
|
fileLogSystem := NewStdLogSystem(file, 0, WarnLevel)
|
||||||
|
AddLogSystem(fileLogSystem)
|
||||||
|
stdOutLogSystem := NewStdLogSystem(os.Stdout, 0, WarnLevel)
|
||||||
|
AddLogSystem(stdOutLogSystem)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
188
ethlog/loggers.go
Normal file
188
ethlog/loggers.go
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
package ethlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LogSystem interface {
|
||||||
|
GetLogLevel() LogLevel
|
||||||
|
SetLogLevel(i LogLevel)
|
||||||
|
Println(v ...interface{})
|
||||||
|
Printf(format string, v ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type logMessage struct {
|
||||||
|
LogLevel LogLevel
|
||||||
|
format bool
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPrintlnLogMessage(level LogLevel, tag string, v ...interface{}) *logMessage {
|
||||||
|
return &logMessage{level, false, fmt.Sprintf("[%s] %s", tag, fmt.Sprint(v...))}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPrintfLogMessage(level LogLevel, tag string, format string, v ...interface{}) *logMessage {
|
||||||
|
return &logMessage{level, true, fmt.Sprintf("[%s] %s", tag, fmt.Sprintf(format, v...))}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *logMessage) send(logger LogSystem) {
|
||||||
|
if msg.format {
|
||||||
|
logger.Printf(msg.msg)
|
||||||
|
} else {
|
||||||
|
logger.Println(msg.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var logMessages chan (*logMessage)
|
||||||
|
var logSystems []LogSystem
|
||||||
|
var drained = true
|
||||||
|
|
||||||
|
type LogLevel uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Silence LogLevel = iota
|
||||||
|
ErrorLevel
|
||||||
|
WarnLevel
|
||||||
|
InfoLevel
|
||||||
|
DebugLevel
|
||||||
|
DebugDetailLevel
|
||||||
|
)
|
||||||
|
|
||||||
|
// log messages are dispatched to log writers
|
||||||
|
func start() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case msg := <-logMessages:
|
||||||
|
for _, logSystem := range logSystems {
|
||||||
|
if logSystem.GetLogLevel() >= msg.LogLevel {
|
||||||
|
msg.send(logSystem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
drained = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// waits until log messages are drained (dispatched to log writers)
|
||||||
|
func Flush() {
|
||||||
|
for !drained {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Logger struct {
|
||||||
|
tag string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger(tag string) *Logger {
|
||||||
|
return &Logger{tag}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddLogSystem(logSystem LogSystem) {
|
||||||
|
var mutex = &sync.Mutex{}
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
if logSystems == nil {
|
||||||
|
logMessages = make(chan *logMessage)
|
||||||
|
go start()
|
||||||
|
}
|
||||||
|
logSystems = append(logSystems, logSystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) sendln(level LogLevel, v ...interface{}) {
|
||||||
|
if logMessages != nil {
|
||||||
|
msg := newPrintlnLogMessage(level, logger.tag, v...)
|
||||||
|
drained = false
|
||||||
|
logMessages <- msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) sendf(level LogLevel, format string, v ...interface{}) {
|
||||||
|
if logMessages != nil {
|
||||||
|
msg := newPrintfLogMessage(level, logger.tag, format, v...)
|
||||||
|
drained = false
|
||||||
|
logMessages <- msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Errorln(v ...interface{}) {
|
||||||
|
logger.sendln(ErrorLevel, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Warnln(v ...interface{}) {
|
||||||
|
logger.sendln(WarnLevel, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Infoln(v ...interface{}) {
|
||||||
|
logger.sendln(InfoLevel, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Debugln(v ...interface{}) {
|
||||||
|
logger.sendln(DebugLevel, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) DebugDetailln(v ...interface{}) {
|
||||||
|
logger.sendln(DebugDetailLevel, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Errorf(format string, v ...interface{}) {
|
||||||
|
logger.sendf(ErrorLevel, format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Warnf(format string, v ...interface{}) {
|
||||||
|
logger.sendf(WarnLevel, format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Infof(format string, v ...interface{}) {
|
||||||
|
logger.sendf(InfoLevel, format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Debugf(format string, v ...interface{}) {
|
||||||
|
logger.sendf(DebugLevel, format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) DebugDetailf(format string, v ...interface{}) {
|
||||||
|
logger.sendf(DebugDetailLevel, format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Fatalln(v ...interface{}) {
|
||||||
|
logger.sendln(ErrorLevel, v...)
|
||||||
|
Flush()
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) Fatalf(format string, v ...interface{}) {
|
||||||
|
logger.sendf(ErrorLevel, format, v...)
|
||||||
|
Flush()
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type StdLogSystem struct {
|
||||||
|
logger *log.Logger
|
||||||
|
level LogLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *StdLogSystem) Println(v ...interface{}) {
|
||||||
|
t.logger.Println(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *StdLogSystem) Printf(format string, v ...interface{}) {
|
||||||
|
t.logger.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *StdLogSystem) SetLogLevel(i LogLevel) {
|
||||||
|
t.level = i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *StdLogSystem) GetLogLevel() LogLevel {
|
||||||
|
return t.level
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStdLogSystem(writer io.Writer, flags int, level LogLevel) *StdLogSystem {
|
||||||
|
logger := log.New(writer, "", flags)
|
||||||
|
return &StdLogSystem{logger, level}
|
||||||
|
}
|
109
ethlog/loggers_test.go
Normal file
109
ethlog/loggers_test.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package ethlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestLogSystem struct {
|
||||||
|
Output string
|
||||||
|
level LogLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestLogSystem) Println(v ...interface{}) {
|
||||||
|
t.Output += fmt.Sprintln(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestLogSystem) Printf(format string, v ...interface{}) {
|
||||||
|
t.Output += fmt.Sprintf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestLogSystem) SetLogLevel(i LogLevel) {
|
||||||
|
t.level = i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestLogSystem) GetLogLevel() LogLevel {
|
||||||
|
return t.level
|
||||||
|
}
|
||||||
|
|
||||||
|
func quote(s string) string {
|
||||||
|
return fmt.Sprintf("'%s'", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoggerPrintln(t *testing.T) {
|
||||||
|
logger := NewLogger("TEST")
|
||||||
|
testLogSystem := &TestLogSystem{level: WarnLevel}
|
||||||
|
AddLogSystem(testLogSystem)
|
||||||
|
logger.Errorln("error")
|
||||||
|
logger.Warnln("warn")
|
||||||
|
logger.Infoln("info")
|
||||||
|
logger.Debugln("debug")
|
||||||
|
Flush()
|
||||||
|
output := testLogSystem.Output
|
||||||
|
fmt.Println(quote(output))
|
||||||
|
if output != "[TEST] error\n[TEST] warn\n" {
|
||||||
|
t.Error("Expected logger output '[TEST] error\\n[TEST] warn\\n', got ", quote(testLogSystem.Output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoggerPrintf(t *testing.T) {
|
||||||
|
logger := NewLogger("TEST")
|
||||||
|
testLogSystem := &TestLogSystem{level: WarnLevel}
|
||||||
|
AddLogSystem(testLogSystem)
|
||||||
|
logger.Errorf("error to %v\n", *testLogSystem)
|
||||||
|
logger.Warnf("warn")
|
||||||
|
logger.Infof("info")
|
||||||
|
logger.Debugf("debug")
|
||||||
|
Flush()
|
||||||
|
output := testLogSystem.Output
|
||||||
|
fmt.Println(quote(output))
|
||||||
|
if output != "[TEST] error to { 2}\n[TEST] warn" {
|
||||||
|
t.Error("Expected logger output '[TEST] error to { 2}\\n[TEST] warn', got ", quote(testLogSystem.Output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultipleLogSystems(t *testing.T) {
|
||||||
|
logger := NewLogger("TEST")
|
||||||
|
testLogSystem0 := &TestLogSystem{level: ErrorLevel}
|
||||||
|
testLogSystem1 := &TestLogSystem{level: WarnLevel}
|
||||||
|
AddLogSystem(testLogSystem0)
|
||||||
|
AddLogSystem(testLogSystem1)
|
||||||
|
logger.Errorln("error")
|
||||||
|
logger.Warnln("warn")
|
||||||
|
Flush()
|
||||||
|
output0 := testLogSystem0.Output
|
||||||
|
output1 := testLogSystem1.Output
|
||||||
|
if output0 != "[TEST] error\n" {
|
||||||
|
t.Error("Expected logger 0 output '[TEST] error\\n', got ", quote(testLogSystem0.Output))
|
||||||
|
}
|
||||||
|
if output1 != "[TEST] error\n[TEST] warn\n" {
|
||||||
|
t.Error("Expected logger 1 output '[TEST] error\\n[TEST] warn\\n', got ", quote(testLogSystem1.Output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileLogSystem(t *testing.T) {
|
||||||
|
logger := NewLogger("TEST")
|
||||||
|
filename := "test.log"
|
||||||
|
file, _ := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
||||||
|
testLogSystem := NewStdLogSystem(file, 0, WarnLevel)
|
||||||
|
AddLogSystem(testLogSystem)
|
||||||
|
logger.Errorf("error to %s\n", filename)
|
||||||
|
logger.Warnln("warn")
|
||||||
|
Flush()
|
||||||
|
contents, _ := ioutil.ReadFile(filename)
|
||||||
|
output := string(contents)
|
||||||
|
fmt.Println(quote(output))
|
||||||
|
if output != "[TEST] error to test.log\n[TEST] warn\n" {
|
||||||
|
t.Error("Expected contents of file 'test.log': '[TEST] error to test.log\\n[TEST] warn\\n', got ", quote(output))
|
||||||
|
} else {
|
||||||
|
os.Remove(filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoLogSystem(t *testing.T) {
|
||||||
|
logger := NewLogger("TEST")
|
||||||
|
logger.Warnln("warn")
|
||||||
|
Flush()
|
||||||
|
}
|
@ -3,11 +3,14 @@ package ethminer
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var logger = ethlog.NewLogger("MINER")
|
||||||
|
|
||||||
type Miner struct {
|
type Miner struct {
|
||||||
pow ethchain.PoW
|
pow ethchain.PoW
|
||||||
ethereum ethchain.EthManager
|
ethereum ethchain.EthManager
|
||||||
@ -54,23 +57,28 @@ func NewDefaultMiner(coinbase []byte, ethereum ethchain.EthManager) Miner {
|
|||||||
|
|
||||||
return miner
|
return miner
|
||||||
}
|
}
|
||||||
|
|
||||||
func (miner *Miner) Start() {
|
func (miner *Miner) Start() {
|
||||||
// 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())
|
||||||
go miner.listener()
|
go miner.listener()
|
||||||
|
logger.Infoln("Started")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (miner *Miner) listener() {
|
func (miner *Miner) listener() {
|
||||||
out:
|
out:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-miner.quitChan:
|
case <-miner.quitChan:
|
||||||
|
logger.Infoln("Stopped")
|
||||||
break out
|
break out
|
||||||
case chanMessage := <-miner.reactChan:
|
case chanMessage := <-miner.reactChan:
|
||||||
|
|
||||||
if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
|
if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
|
||||||
//ethutil.Config.Log.Infoln("[MINER] Got new block via Reactor")
|
//logger.Infoln("Got new block via Reactor")
|
||||||
if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 {
|
if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 {
|
||||||
// TODO: Perhaps continue mining to get some uncle rewards
|
// TODO: Perhaps continue mining to get some uncle rewards
|
||||||
//ethutil.Config.Log.Infoln("[MINER] New top block found resetting state")
|
//logger.Infoln("New top block found resetting state")
|
||||||
|
|
||||||
// Filter out which Transactions we have that were not in this block
|
// Filter out which Transactions we have that were not in this block
|
||||||
var newtxs []*ethchain.Transaction
|
var newtxs []*ethchain.Transaction
|
||||||
@ -92,7 +100,7 @@ out:
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
|
if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
|
||||||
ethutil.Config.Log.Infoln("[MINER] Adding uncle block")
|
logger.Infoln("Adding uncle block")
|
||||||
miner.uncles = append(miner.uncles, block)
|
miner.uncles = append(miner.uncles, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,8 +128,9 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) Stop() {
|
func (self *Miner) Stop() {
|
||||||
self.powQuitChan <- ethutil.React{}
|
logger.Infoln("Stopping...")
|
||||||
self.quitChan <- true
|
self.quitChan <- true
|
||||||
|
self.powQuitChan <- ethutil.React{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) mineNewBlock() {
|
func (self *Miner) mineNewBlock() {
|
||||||
@ -137,14 +146,14 @@ func (self *Miner) mineNewBlock() {
|
|||||||
// Sort the transactions by nonce in case of odd network propagation
|
// Sort the transactions by nonce in case of odd network propagation
|
||||||
sort.Sort(ethchain.TxByNonce{self.txs})
|
sort.Sort(ethchain.TxByNonce{self.txs})
|
||||||
|
|
||||||
// Accumulate all valid transaction and apply them to the new state
|
// Accumulate all valid transactions and apply them to the new state
|
||||||
// Error may be ignored. It's not important during mining
|
// Error may be ignored. It's not important during mining
|
||||||
parent := self.ethereum.BlockChain().GetBlock(self.block.PrevHash)
|
parent := self.ethereum.BlockChain().GetBlock(self.block.PrevHash)
|
||||||
coinbase := self.block.State().GetOrNewStateObject(self.block.Coinbase)
|
coinbase := self.block.State().GetOrNewStateObject(self.block.Coinbase)
|
||||||
coinbase.SetGasPool(self.block.CalcGasLimit(parent))
|
coinbase.SetGasPool(self.block.CalcGasLimit(parent))
|
||||||
receipts, txs, unhandledTxs, err := stateManager.ProcessTransactions(coinbase, self.block.State(), self.block, self.block, self.txs)
|
receipts, txs, unhandledTxs, err := stateManager.ProcessTransactions(coinbase, self.block.State(), self.block, self.block, self.txs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("[MINER]", err)
|
logger.Debugln(err)
|
||||||
}
|
}
|
||||||
self.txs = append(txs, unhandledTxs...)
|
self.txs = append(txs, unhandledTxs...)
|
||||||
|
|
||||||
@ -156,18 +165,18 @@ func (self *Miner) mineNewBlock() {
|
|||||||
|
|
||||||
self.block.State().Update()
|
self.block.State().Update()
|
||||||
|
|
||||||
ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(self.txs), "transactions")
|
logger.Infof("Mining on block. Includes %v transactions", len(self.txs))
|
||||||
|
|
||||||
// Find a valid nonce
|
// Find a valid nonce
|
||||||
self.block.Nonce = self.pow.Search(self.block, self.powQuitChan)
|
self.block.Nonce = self.pow.Search(self.block, self.powQuitChan)
|
||||||
if self.block.Nonce != nil {
|
if self.block.Nonce != nil {
|
||||||
err := self.ethereum.StateManager().Process(self.block, false)
|
err := self.ethereum.StateManager().Process(self.block, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Infoln(err)
|
logger.Infoln(err)
|
||||||
} else {
|
} else {
|
||||||
self.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{self.block.Value().Val})
|
self.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{self.block.Value().Val})
|
||||||
ethutil.Config.Log.Infof("[MINER] 🔨 Mined block %x\n", self.block.Hash())
|
logger.Infof("🔨 Mined block %x\n", self.block.Hash())
|
||||||
ethutil.Config.Log.Infoln(self.block)
|
logger.Infoln(self.block)
|
||||||
// Gather the new batch of transactions currently in the tx pool
|
// Gather the new batch of transactions currently in the tx pool
|
||||||
self.txs = self.ethereum.TxPool().CurrentTransactions()
|
self.txs = self.ethereum.TxPool().CurrentTransactions()
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
package ethpub
|
package ethpub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var logger = ethlog.NewLogger("PUB")
|
||||||
|
|
||||||
type PEthereum struct {
|
type PEthereum struct {
|
||||||
manager ethchain.EthManager
|
manager ethchain.EthManager
|
||||||
stateManager *ethchain.StateManager
|
stateManager *ethchain.StateManager
|
||||||
@ -81,6 +86,36 @@ func (lib *PEthereum) GetCoinBase() string {
|
|||||||
return lib.SecretToAddress(hex.EncodeToString(key))
|
return lib.SecretToAddress(hex.EncodeToString(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lib *PEthereum) GetTransactionsFor(address string, asJson bool) interface{} {
|
||||||
|
sBlk := lib.manager.BlockChain().LastBlockHash
|
||||||
|
blk := lib.manager.BlockChain().GetBlock(sBlk)
|
||||||
|
addr := []byte(ethutil.FromHex(address))
|
||||||
|
|
||||||
|
var txs []*PTx
|
||||||
|
|
||||||
|
for ; blk != nil; blk = lib.manager.BlockChain().GetBlock(sBlk) {
|
||||||
|
sBlk = blk.PrevHash
|
||||||
|
|
||||||
|
// Loop through all transactions to see if we missed any while being offline
|
||||||
|
for _, tx := range blk.Transactions() {
|
||||||
|
if bytes.Compare(tx.Sender(), addr) == 0 || bytes.Compare(tx.Recipient, addr) == 0 {
|
||||||
|
ptx := NewPTx(tx)
|
||||||
|
//TODO: somehow move this to NewPTx
|
||||||
|
ptx.Confirmations = int(lib.manager.BlockChain().LastBlockNumber - blk.BlockInfo().Number)
|
||||||
|
txs = append(txs, ptx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if asJson {
|
||||||
|
txJson, err := json.Marshal(txs)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return string(txJson)
|
||||||
|
}
|
||||||
|
return txs
|
||||||
|
}
|
||||||
|
|
||||||
func (lib *PEthereum) GetStorage(address, storageAddress string) string {
|
func (lib *PEthereum) GetStorage(address, storageAddress string) string {
|
||||||
return lib.GetStateObject(address).GetStorage(storageAddress)
|
return lib.GetStateObject(address).GetStorage(storageAddress)
|
||||||
}
|
}
|
||||||
@ -123,7 +158,6 @@ func GetAddressFromNameReg(stateManager *ethchain.StateManager, name string) []b
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -142,7 +176,7 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, sc
|
|||||||
var keyPair *ethutil.KeyPair
|
var keyPair *ethutil.KeyPair
|
||||||
var err error
|
var err error
|
||||||
if key[0:2] == "0x" {
|
if key[0:2] == "0x" {
|
||||||
keyPair, err = ethutil.NewKeyPairFromSec([]byte(ethutil.FromHex(key[0:2])))
|
keyPair, err = ethutil.NewKeyPairFromSec([]byte(ethutil.FromHex(key[2:])))
|
||||||
} else {
|
} else {
|
||||||
keyPair, err = ethutil.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
|
keyPair, err = ethutil.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
|
||||||
}
|
}
|
||||||
@ -191,7 +225,7 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, sc
|
|||||||
lib.txPool.QueueTransaction(tx)
|
lib.txPool.QueueTransaction(tx)
|
||||||
|
|
||||||
if contractCreation {
|
if contractCreation {
|
||||||
ethutil.Config.Log.Infof("Contract addr %x", tx.CreationAddress())
|
logger.Infof("Contract addr %x", tx.CreationAddress())
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewPReciept(contractCreation, tx.CreationAddress(), tx.Hash(), keyPair.Address()), nil
|
return NewPReciept(contractCreation, tx.CreationAddress(), tx.Hash(), keyPair.Address()), nil
|
||||||
|
@ -99,6 +99,7 @@ type PTx struct {
|
|||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
Contract bool `json:"isContract"`
|
Contract bool `json:"isContract"`
|
||||||
CreatesContract bool `json:"createsContract"`
|
CreatesContract bool `json:"createsContract"`
|
||||||
|
Confirmations int `json:"confirmations"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPTx(tx *ethchain.Transaction) *PTx {
|
func NewPTx(tx *ethchain.Transaction) *PTx {
|
||||||
@ -244,6 +245,14 @@ func (c *PStateObject) Script() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *PStateObject) HexScript() string {
|
||||||
|
if c.object != nil {
|
||||||
|
return ethutil.Hex(c.object.Script())
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type PStorageState struct {
|
type PStorageState struct {
|
||||||
StateAddress string
|
StateAddress string
|
||||||
Address string
|
Address string
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/ethereum/eth-go/ethpub"
|
"github.com/ethereum/eth-go/ethpub"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EthereumApi struct {
|
type EthereumApi struct {
|
||||||
@ -174,9 +175,16 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
state := p.ethp.GetStateObject(args.Address)
|
state := p.ethp.GetStateObject(args.Address)
|
||||||
// Convert the incoming string (which is a bigint) into hex
|
|
||||||
i, _ := new(big.Int).SetString(args.Key, 10)
|
var hx string
|
||||||
hx := ethutil.Hex(i.Bytes())
|
if strings.Index(args.Key, "0x") == 0 {
|
||||||
|
hx = string([]byte(args.Key)[2:])
|
||||||
|
} else {
|
||||||
|
// Convert the incoming string (which is a bigint) into hex
|
||||||
|
i, _ := new(big.Int).SetString(args.Key, 10)
|
||||||
|
hx = ethutil.Hex(i.Bytes())
|
||||||
|
}
|
||||||
|
logger.Debugf("GetStorageAt(%s, %s)\n", args.Address, hx)
|
||||||
value := state.GetStorage(hx)
|
value := state.GetStorage(hx)
|
||||||
*reply = NewSuccessRes(GetStorageAtRes{Address: args.Address, Key: args.Key, Value: value})
|
*reply = NewSuccessRes(GetStorageAtRes{Address: args.Address, Key: args.Key, Value: value})
|
||||||
return nil
|
return nil
|
||||||
|
@ -2,13 +2,15 @@ package ethrpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethpub"
|
"github.com/ethereum/eth-go/ethpub"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
|
||||||
"net"
|
"net"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"net/rpc/jsonrpc"
|
"net/rpc/jsonrpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var logger = ethlog.NewLogger("JSON")
|
||||||
|
|
||||||
type JsonRpcServer struct {
|
type JsonRpcServer struct {
|
||||||
quit chan bool
|
quit chan bool
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
@ -25,7 +27,7 @@ out:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ethutil.Config.Log.Infoln("[JSON] Shutdown JSON-RPC server")
|
logger.Infoln("Shutdown JSON-RPC server")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *JsonRpcServer) Stop() {
|
func (s *JsonRpcServer) Stop() {
|
||||||
@ -33,7 +35,7 @@ func (s *JsonRpcServer) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *JsonRpcServer) Start() {
|
func (s *JsonRpcServer) Start() {
|
||||||
ethutil.Config.Log.Infoln("[JSON] Starting JSON-RPC server")
|
logger.Infoln("Starting JSON-RPC server")
|
||||||
go s.exitHandler()
|
go s.exitHandler()
|
||||||
rpc.Register(&EthereumApi{ethp: s.ethp})
|
rpc.Register(&EthereumApi{ethp: s.ethp})
|
||||||
rpc.HandleHTTP()
|
rpc.HandleHTTP()
|
||||||
@ -41,10 +43,10 @@ func (s *JsonRpcServer) Start() {
|
|||||||
for {
|
for {
|
||||||
conn, err := s.listener.Accept()
|
conn, err := s.listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Infoln("[JSON] Error starting JSON-RPC:", err)
|
logger.Infoln("Error starting JSON-RPC:", err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
ethutil.Config.Log.Debugln("[JSON] Incoming request.")
|
logger.Debugln("Incoming request.")
|
||||||
go jsonrpc.ServeConn(conn)
|
go jsonrpc.ServeConn(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/rakyll/globalconf"
|
"github.com/rakyll/globalconf"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
|
||||||
"path"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,7 +12,6 @@ import (
|
|||||||
type config struct {
|
type config struct {
|
||||||
Db Database
|
Db Database
|
||||||
|
|
||||||
Log *Logger
|
|
||||||
ExecPath string
|
ExecPath string
|
||||||
Debug bool
|
Debug bool
|
||||||
Ver string
|
Ver string
|
||||||
@ -26,62 +22,31 @@ type config struct {
|
|||||||
conf *globalconf.GlobalConf
|
conf *globalconf.GlobalConf
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultConf = `
|
|
||||||
id = ""
|
|
||||||
port = 30303
|
|
||||||
upnp = true
|
|
||||||
maxpeer = 10
|
|
||||||
rpc = false
|
|
||||||
rpcport = 8080
|
|
||||||
`
|
|
||||||
|
|
||||||
var Config *config
|
var Config *config
|
||||||
|
|
||||||
func ApplicationFolder(base string) string {
|
|
||||||
usr, _ := user.Current()
|
|
||||||
p := path.Join(usr.HomeDir, base)
|
|
||||||
|
|
||||||
if len(base) > 0 {
|
|
||||||
//Check if the logging directory already exists, create it if not
|
|
||||||
_, err := os.Stat(p)
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
log.Printf("Debug logging directory %s doesn't exist, creating it\n", p)
|
|
||||||
os.Mkdir(p, 0777)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iniFilePath := path.Join(p, "conf.ini")
|
|
||||||
_, err = os.Stat(iniFilePath)
|
|
||||||
if err != nil && os.IsNotExist(err) {
|
|
||||||
file, err := os.Create(iniFilePath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
assetPath := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "ethereal", "assets")
|
|
||||||
file.Write([]byte(defaultConf + "\nasset_path = " + assetPath))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read config
|
// Read config
|
||||||
//
|
//
|
||||||
// Initialize the global Config variable with default settings
|
// Initialize Config from Config File
|
||||||
func ReadConfig(base string, logTypes LoggerType, g *globalconf.GlobalConf, id string) *config {
|
func ReadConfig(ConfigFile string, Datadir string, Identifier string, EnvPrefix string) *config {
|
||||||
if Config == nil {
|
if Config == nil {
|
||||||
path := ApplicationFolder(base)
|
// create ConfigFile if does not exist, otherwise globalconf panic when trying to persist flags
|
||||||
|
_, err := os.Stat(ConfigFile)
|
||||||
Config = &config{ExecPath: path, Debug: true, Ver: "0.5.14"}
|
if err != nil && os.IsNotExist(err) {
|
||||||
Config.conf = g
|
fmt.Printf("config file '%s' doesn't exist, creating it\n", ConfigFile)
|
||||||
Config.Identifier = id
|
os.Create(ConfigFile)
|
||||||
Config.Log = NewLogger(logTypes, LogLevelDebug)
|
}
|
||||||
|
g, err := globalconf.NewWithOptions(&globalconf.Options{
|
||||||
|
Filename: ConfigFile,
|
||||||
|
EnvPrefix: EnvPrefix,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
} else {
|
||||||
|
g.ParseAll()
|
||||||
|
}
|
||||||
|
Config = &config{ExecPath: Datadir, Debug: true, Ver: "0.5.14", conf: g, Identifier: Identifier}
|
||||||
Config.SetClientString("Ethereum(G)")
|
Config.SetClientString("Ethereum(G)")
|
||||||
}
|
}
|
||||||
|
|
||||||
return Config
|
return Config
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,137 +63,12 @@ func (c *config) SetIdentifier(id string) {
|
|||||||
c.Set("id", id)
|
c.Set("id", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// provides persistence for flags
|
||||||
func (c *config) Set(key, value string) {
|
func (c *config) Set(key, value string) {
|
||||||
f := &flag.Flag{Name: key, Value: &confValue{value}}
|
f := &flag.Flag{Name: key, Value: &confValue{value}}
|
||||||
c.conf.Set("", f)
|
c.conf.Set("", f)
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoggerType byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
LogFile = 0x1
|
|
||||||
LogStd = 0x2
|
|
||||||
)
|
|
||||||
|
|
||||||
type LogSystem interface {
|
|
||||||
Println(v ...interface{})
|
|
||||||
Printf(format string, v ...interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
type Logger struct {
|
|
||||||
logSys []LogSystem
|
|
||||||
logLevel int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLogger(flag LoggerType, level int) *Logger {
|
|
||||||
var loggers []LogSystem
|
|
||||||
|
|
||||||
flags := log.LstdFlags
|
|
||||||
|
|
||||||
if flag&LogFile > 0 {
|
|
||||||
file, err := os.OpenFile(path.Join(Config.ExecPath, "debug.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
|
|
||||||
if err != nil {
|
|
||||||
log.Panic("unable to create file logger", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log := log.New(file, "", flags)
|
|
||||||
|
|
||||||
loggers = append(loggers, log)
|
|
||||||
}
|
|
||||||
if flag&LogStd > 0 {
|
|
||||||
log := log.New(os.Stdout, "", flags)
|
|
||||||
loggers = append(loggers, log)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Logger{logSys: loggers, logLevel: level}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Logger) SetLevel(level int) {
|
|
||||||
self.logLevel = level
|
|
||||||
}
|
|
||||||
|
|
||||||
func (log *Logger) AddLogSystem(logger LogSystem) {
|
|
||||||
log.logSys = append(log.logSys, logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
LogLevelSystem = iota
|
|
||||||
LogLevelDebug
|
|
||||||
LogLevelInfo
|
|
||||||
)
|
|
||||||
|
|
||||||
func (log *Logger) Debugln(v ...interface{}) {
|
|
||||||
if log.logLevel != LogLevelDebug {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, logger := range log.logSys {
|
|
||||||
logger.Println(v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (log *Logger) Debugf(format string, v ...interface{}) {
|
|
||||||
if log.logLevel != LogLevelDebug {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, logger := range log.logSys {
|
|
||||||
logger.Printf(format, v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (log *Logger) Infoln(v ...interface{}) {
|
|
||||||
if log.logLevel > LogLevelInfo {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, logger := range log.logSys {
|
|
||||||
logger.Println(v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (log *Logger) Infof(format string, v ...interface{}) {
|
|
||||||
if log.logLevel > LogLevelInfo {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, logger := range log.logSys {
|
|
||||||
logger.Printf(format, v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (log *Logger) Fatal(v ...interface{}) {
|
|
||||||
if log.logLevel > LogLevelInfo {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, logger := range log.logSys {
|
|
||||||
logger.Println(v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (log *Logger) Println(level int, v ...interface{}) {
|
|
||||||
if log.logLevel > level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, logger := range log.logSys {
|
|
||||||
logger.Println(v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (log *Logger) Printf(level int, format string, v ...interface{}) {
|
|
||||||
if log.logLevel > level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, logger := range log.logSys {
|
|
||||||
logger.Printf(format, v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type confValue struct {
|
type confValue struct {
|
||||||
value string
|
value string
|
||||||
}
|
}
|
||||||
|
@ -64,4 +64,4 @@ func TestCompactDecode(t *testing.T) {
|
|||||||
if !CompareIntSlice(res, exp) {
|
if !CompareIntSlice(res, exp) {
|
||||||
t.Error("even terminated compact decode. Expected", exp, "got", res)
|
t.Error("even terminated compact decode. Expected", exp, "got", res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,39 +3,35 @@ package ethutil
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/obscuren/mutan"
|
"github.com/obscuren/mutan"
|
||||||
|
"github.com/obscuren/mutan/backends"
|
||||||
|
"github.com/obscuren/serpent-go"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// General compile function
|
// General compile function
|
||||||
func Compile(script string) ([]byte, error) {
|
func Compile(script string) (ret []byte, err error) {
|
||||||
byteCode, errors := mutan.Compile(strings.NewReader(script), false)
|
c := strings.Split(script, "\n")[0]
|
||||||
if len(errors) > 0 {
|
|
||||||
var errs string
|
if c == "#!serpent" {
|
||||||
for _, er := range errors {
|
byteCode, err := serpent.Compile(script)
|
||||||
if er != nil {
|
if err != nil {
|
||||||
errs += er.Error()
|
return nil, err
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("%v", errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
return byteCode, nil
|
return byteCode, nil
|
||||||
}
|
} else {
|
||||||
|
compiler := mutan.NewCompiler(backend.NewEthereumBackend())
|
||||||
func CompileScript(script string) ([]byte, []byte, error) {
|
byteCode, errors := compiler.Compile(strings.NewReader(script))
|
||||||
// Preprocess
|
if len(errors) > 0 {
|
||||||
mainInput, initInput := mutan.PreParse(script)
|
var errs string
|
||||||
// Compile main script
|
for _, er := range errors {
|
||||||
mainScript, err := Compile(mainInput)
|
if er != nil {
|
||||||
if err != nil {
|
errs += er.Error()
|
||||||
return nil, nil, err
|
}
|
||||||
}
|
}
|
||||||
|
return nil, fmt.Errorf("%v", errs)
|
||||||
// Compile init script
|
}
|
||||||
initScript, err := Compile(initInput)
|
|
||||||
if err != nil {
|
return byteCode, nil
|
||||||
return nil, nil, err
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return mainScript, initScript, nil
|
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func (cache *Cache) Put(v interface{}) interface{} {
|
|||||||
value := NewValue(v)
|
value := NewValue(v)
|
||||||
|
|
||||||
enc := value.Encode()
|
enc := value.Encode()
|
||||||
if len(enc) >= 32 {
|
if len(enc) < 32 {
|
||||||
sha := Sha3Bin(enc)
|
sha := Sha3Bin(enc)
|
||||||
|
|
||||||
cache.nodes[string(sha)] = NewNode(sha, value, true)
|
cache.nodes[string(sha)] = NewNode(sha, value, true)
|
||||||
|
66
peer.go
66
peer.go
@ -5,6 +5,7 @@ import (
|
|||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"net"
|
"net"
|
||||||
@ -14,6 +15,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var peerlogger = ethlog.NewLogger("PEER")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// The size of the output buffer for writing messages
|
// The size of the output buffer for writing messages
|
||||||
outputBufferSize = 50
|
outputBufferSize = 50
|
||||||
@ -138,6 +141,8 @@ type Peer struct {
|
|||||||
// We use this to give some kind of pingtime to a node, not very accurate, could be improved.
|
// We use this to give some kind of pingtime to a node, not very accurate, could be improved.
|
||||||
pingTime time.Duration
|
pingTime time.Duration
|
||||||
pingStartTime time.Time
|
pingStartTime time.Time
|
||||||
|
|
||||||
|
lastRequestedBlock *ethchain.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
|
func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
|
||||||
@ -176,7 +181,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
|
|||||||
conn, err := net.DialTimeout("tcp", addr, 10*time.Second)
|
conn, err := net.DialTimeout("tcp", addr, 10*time.Second)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("Connection to peer failed", err)
|
peerlogger.Debugln("Connection to peer failed", err)
|
||||||
p.Stop()
|
p.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -245,11 +250,11 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ethutil.Config.Log.Println(ethutil.LogLevelSystem, "<=", msg.Type, msg.Data)
|
peerlogger.DebugDetailln("<=", msg.Type, msg.Data)
|
||||||
|
|
||||||
err := ethwire.WriteMessage(p.conn, msg)
|
err := ethwire.WriteMessage(p.conn, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("[PEER] Can't send message:", err)
|
peerlogger.Debugln(" Can't send message:", err)
|
||||||
// Stop the client if there was an error writing to it
|
// Stop the client if there was an error writing to it
|
||||||
p.Stop()
|
p.Stop()
|
||||||
return
|
return
|
||||||
@ -274,7 +279,7 @@ out:
|
|||||||
case <-pingTimer.C:
|
case <-pingTimer.C:
|
||||||
timeSince := time.Since(time.Unix(p.lastPong, 0))
|
timeSince := time.Since(time.Unix(p.lastPong, 0))
|
||||||
if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) {
|
if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) {
|
||||||
ethutil.Config.Log.Infof("[PEER] Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince)
|
peerlogger.Infof("Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince)
|
||||||
p.Stop()
|
p.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -316,10 +321,10 @@ func (p *Peer) HandleInbound() {
|
|||||||
// 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 {
|
||||||
ethutil.Config.Log.Debugln(err)
|
peerlogger.Debugln(err)
|
||||||
}
|
}
|
||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
ethutil.Config.Log.Println(ethutil.LogLevelSystem, "=>", msg.Type, msg.Data)
|
peerlogger.DebugDetailln("=>", msg.Type, msg.Data)
|
||||||
|
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case ethwire.MsgHandshakeTy:
|
case ethwire.MsgHandshakeTy:
|
||||||
@ -331,7 +336,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
}
|
}
|
||||||
case ethwire.MsgDiscTy:
|
case ethwire.MsgDiscTy:
|
||||||
p.Stop()
|
p.Stop()
|
||||||
ethutil.Config.Log.Infoln("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint()))
|
peerlogger.Infoln("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint()))
|
||||||
case ethwire.MsgPingTy:
|
case ethwire.MsgPingTy:
|
||||||
// Respond back with pong
|
// Respond back with pong
|
||||||
p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, ""))
|
p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, ""))
|
||||||
@ -351,7 +356,12 @@ func (p *Peer) HandleInbound() {
|
|||||||
// We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find
|
// We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find
|
||||||
// common ground to start syncing from
|
// common ground to start syncing from
|
||||||
lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1))
|
lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1))
|
||||||
ethutil.Config.Log.Infof("[PEER] Last block: %x. Checking if we have it locally.\n", lastBlock.Hash())
|
if p.lastRequestedBlock != nil && bytes.Compare(lastBlock.Hash(), p.lastRequestedBlock.Hash()) == 0 {
|
||||||
|
p.catchingUp = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p.lastRequestedBlock = lastBlock
|
||||||
|
peerlogger.Infof("Last block: %x. Checking if we have it locally.\n", lastBlock.Hash())
|
||||||
for i := msg.Data.Len() - 1; i >= 0; i-- {
|
for i := msg.Data.Len() - 1; i >= 0; i-- {
|
||||||
block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i))
|
block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i))
|
||||||
// Do we have this block on our chain? If so we can continue
|
// Do we have this block on our chain? If so we can continue
|
||||||
@ -372,7 +382,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
// we just keep increasing the amount of blocks.
|
// we just keep increasing the amount of blocks.
|
||||||
p.blocksRequested = p.blocksRequested * 2
|
p.blocksRequested = p.blocksRequested * 2
|
||||||
|
|
||||||
ethutil.Config.Log.Infof("[PEER] 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.catchingUp = false
|
||||||
p.FindCommonParentBlock()
|
p.FindCommonParentBlock()
|
||||||
break
|
break
|
||||||
@ -388,9 +398,9 @@ func (p *Peer) HandleInbound() {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ethutil.Config.Debug {
|
if ethutil.Config.Debug {
|
||||||
ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash())
|
peerlogger.Infof("Block %x failed\n", block.Hash())
|
||||||
ethutil.Config.Log.Infof("[PEER] %v\n", err)
|
peerlogger.Infof("%v\n", err)
|
||||||
ethutil.Config.Log.Debugln(block)
|
peerlogger.Debugln(block)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
@ -407,7 +417,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// If the parent is unknown try to catch up with this peer
|
// If the parent is unknown try to catch up with this peer
|
||||||
if ethchain.IsParentErr(err) {
|
if ethchain.IsParentErr(err) {
|
||||||
ethutil.Config.Log.Infoln("Attempting to catch. Parent known")
|
peerlogger.Infoln("Attempting to catch. Parent known")
|
||||||
p.catchingUp = false
|
p.catchingUp = false
|
||||||
p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash())
|
p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash())
|
||||||
} else if ethchain.IsValidationErr(err) {
|
} else if ethchain.IsValidationErr(err) {
|
||||||
@ -419,7 +429,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
if p.catchingUp && msg.Data.Len() > 1 {
|
if p.catchingUp && msg.Data.Len() > 1 {
|
||||||
if lastBlock != nil {
|
if lastBlock != nil {
|
||||||
blockInfo := lastBlock.BlockInfo()
|
blockInfo := lastBlock.BlockInfo()
|
||||||
ethutil.Config.Log.Debugf("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash)
|
peerlogger.DebugDetailf("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.catchingUp = false
|
p.catchingUp = false
|
||||||
@ -486,17 +496,17 @@ func (p *Peer) HandleInbound() {
|
|||||||
|
|
||||||
// If a parent is found send back a reply
|
// If a parent is found send back a reply
|
||||||
if parent != nil {
|
if parent != nil {
|
||||||
ethutil.Config.Log.Debugf("[PEER] Found canonical block, returning chain from: %x ", parent.Hash())
|
peerlogger.DebugDetailf("Found canonical block, returning chain from: %x ", parent.Hash())
|
||||||
chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks)
|
chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks)
|
||||||
if len(chain) > 0 {
|
if len(chain) > 0 {
|
||||||
//ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash())
|
//peerlogger.Debugf("Returning %d blocks: %x ", len(chain), parent.Hash())
|
||||||
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain))
|
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain))
|
||||||
} else {
|
} else {
|
||||||
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{}))
|
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//ethutil.Config.Log.Debugf("[PEER] Could not find a similar block")
|
//peerlogger.Debugf("Could not find a similar block")
|
||||||
// If no blocks are found we send back a reply with msg not in chain
|
// If no blocks are found we send back a reply with msg not in chain
|
||||||
// and the last hash from get chain
|
// and the last hash from get chain
|
||||||
if l > 0 {
|
if l > 0 {
|
||||||
@ -506,7 +516,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ethwire.MsgNotInChainTy:
|
case ethwire.MsgNotInChainTy:
|
||||||
ethutil.Config.Log.Debugf("Not in chain: %x\n", msg.Data.Get(0).Bytes())
|
peerlogger.DebugDetailf("Not in chain: %x\n", msg.Data.Get(0).Bytes())
|
||||||
if p.diverted == true {
|
if p.diverted == true {
|
||||||
// If were already looking for a common parent and we get here again we need to go deeper
|
// If were already looking for a common parent and we get here again we need to go deeper
|
||||||
p.blocksRequested = p.blocksRequested * 2
|
p.blocksRequested = p.blocksRequested * 2
|
||||||
@ -527,7 +537,7 @@ func (p *Peer) HandleInbound() {
|
|||||||
|
|
||||||
// Unofficial but fun nonetheless
|
// Unofficial but fun nonetheless
|
||||||
case ethwire.MsgTalkTy:
|
case ethwire.MsgTalkTy:
|
||||||
ethutil.Config.Log.Infoln("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str())
|
peerlogger.Infoln("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -546,7 +556,7 @@ func (p *Peer) Start() {
|
|||||||
|
|
||||||
err := p.pushHandshake()
|
err := p.pushHandshake()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln("Peer can't send outbound version ack", err)
|
peerlogger.Debugln("Peer can't send outbound version ack", err)
|
||||||
|
|
||||||
p.Stop()
|
p.Stop()
|
||||||
|
|
||||||
@ -620,7 +630,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
|
|||||||
p.pubkey = c.Get(5).Bytes()
|
p.pubkey = c.Get(5).Bytes()
|
||||||
|
|
||||||
if p.pubkey == nil {
|
if p.pubkey == nil {
|
||||||
//ethutil.Config.Log.Debugln("Pubkey required, not supplied in handshake.")
|
peerlogger.Warnln("Pubkey required, not supplied in handshake.")
|
||||||
p.Stop()
|
p.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -635,13 +645,13 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if usedPub > 0 {
|
if usedPub > 0 {
|
||||||
//ethutil.Config.Log.Debugf("Pubkey %x found more then once. Already connected to client.", p.pubkey)
|
peerlogger.Debugf("Pubkey %x found more then once. Already connected to client.", p.pubkey)
|
||||||
p.Stop()
|
p.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Get(0).Uint() != ProtocolVersion {
|
if c.Get(0).Uint() != ProtocolVersion {
|
||||||
ethutil.Config.Log.Debugf("Invalid peer version. Require protocol: %d. Received: %d\n", ProtocolVersion, c.Get(0).Uint())
|
peerlogger.Debugf("Invalid peer version. Require protocol: %d. Received: %d\n", ProtocolVersion, c.Get(0).Uint())
|
||||||
p.Stop()
|
p.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -675,16 +685,16 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
|
|||||||
p.ethereum.PushPeer(p)
|
p.ethereum.PushPeer(p)
|
||||||
p.ethereum.reactor.Post("peerList", p.ethereum.Peers())
|
p.ethereum.reactor.Post("peerList", p.ethereum.Peers())
|
||||||
|
|
||||||
ethutil.Config.Log.Infof("[SERV] Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers)
|
ethlogger.Infof("Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers)
|
||||||
|
|
||||||
// Catch up with the connected peer
|
// Catch up with the connected peer
|
||||||
if !p.ethereum.IsUpToDate() {
|
if !p.ethereum.IsUpToDate() {
|
||||||
ethutil.Config.Log.Debugln("Already syncing up with a peer; sleeping")
|
peerlogger.Debugln("Already syncing up with a peer; sleeping")
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
}
|
}
|
||||||
p.SyncWithPeerToLastKnown()
|
p.SyncWithPeerToLastKnown()
|
||||||
|
|
||||||
ethutil.Config.Log.Debugln("[PEER]", p)
|
peerlogger.Debugln(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Peer) String() string {
|
func (p *Peer) String() string {
|
||||||
@ -727,7 +737,7 @@ func (p *Peer) FindCommonParentBlock() {
|
|||||||
|
|
||||||
msgInfo := append(hashes, uint64(len(hashes)))
|
msgInfo := append(hashes, uint64(len(hashes)))
|
||||||
|
|
||||||
ethutil.Config.Log.Infof("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String())
|
peerlogger.DebugDetailf("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String())
|
||||||
|
|
||||||
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo)
|
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo)
|
||||||
p.QueueMessage(msg)
|
p.QueueMessage(msg)
|
||||||
@ -739,7 +749,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) {
|
|||||||
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)})
|
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)})
|
||||||
p.QueueMessage(msg)
|
p.QueueMessage(msg)
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("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())
|
||||||
|
|
||||||
msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{})
|
msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{})
|
||||||
p.QueueMessage(msg)
|
p.QueueMessage(msg)
|
||||||
|
Loading…
Reference in New Issue
Block a user