aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--ethchain/block_chain.go12
-rw-r--r--ethchain/dagger.go2
-rw-r--r--ethchain/stack.go2
-rw-r--r--ethchain/state_manager.go66
-rw-r--r--ethchain/state_object_test.go29
-rw-r--r--ethchain/transaction_pool.go7
-rw-r--r--ethchain/vm.go2
-rw-r--r--ethchain/vm_test.go9
-rw-r--r--ethminer/miner.go76
-rw-r--r--ethpub/pub.go11
-rw-r--r--ethpub/types.go16
-rw-r--r--ethutil/config.go2
-rw-r--r--peer.go10
14 files changed, 151 insertions, 95 deletions
diff --git a/README.md b/README.md
index f6bcaad28..2b080273b 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ Ethereum
Ethereum Go Development package (C) Jeffrey Wilcke
Ethereum is currently in its testing phase. The current state is "Proof
-of Concept 5.0 RC7". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
+of Concept 5.0 RC8". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
Ethereum Go is split up in several sub packages Please refer to each
individual package for more information.
diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go
index 2865336fb..b72c78cdb 100644
--- a/ethchain/block_chain.go
+++ b/ethchain/block_chain.go
@@ -190,8 +190,8 @@ func (bc *BlockChain) ResetTillBlockHash(hash []byte) error {
returnTo = bc.GetBlock(hash)
bc.CurrentBlock = returnTo
bc.LastBlockHash = returnTo.Hash()
- info := bc.BlockInfo(returnTo)
- bc.LastBlockNumber = info.Number
+ //info := bc.BlockInfo(returnTo)
+ bc.LastBlockNumber = returnTo.Number.Uint64()
}
// XXX Why are we resetting? This is the block chain, it has nothing to do with states
@@ -228,9 +228,9 @@ func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} {
// Get the current hash to start with
currentHash := bc.CurrentBlock.Hash()
// Get the last number on the block chain
- lastNumber := bc.BlockInfo(bc.CurrentBlock).Number
+ lastNumber := bc.CurrentBlock.Number.Uint64()
// Get the parents number
- parentNumber := bc.BlockInfoByHash(hash).Number
+ parentNumber := bc.GetBlock(hash).Number.Uint64()
// Get the min amount. We might not have max amount of blocks
count := uint64(math.Min(float64(lastNumber-parentNumber), float64(max)))
startNumber := parentNumber + count
@@ -291,10 +291,10 @@ func (bc *BlockChain) setLastBlock() {
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
if len(data) != 0 {
block := NewBlockFromBytes(data)
- info := bc.BlockInfo(block)
+ //info := bc.BlockInfo(block)
bc.CurrentBlock = block
bc.LastBlockHash = block.Hash()
- bc.LastBlockNumber = info.Number
+ bc.LastBlockNumber = block.Number.Uint64()
ethutil.Config.Log.Infof("[CHAIN] Last known block height #%d\n", bc.LastBlockNumber)
} else {
diff --git a/ethchain/dagger.go b/ethchain/dagger.go
index 18e53d3a8..565e1e447 100644
--- a/ethchain/dagger.go
+++ b/ethchain/dagger.go
@@ -29,7 +29,7 @@ func (pow *EasyPow) Search(block *Block, reactChan chan ethutil.React) []byte {
for {
select {
case <-reactChan:
- ethutil.Config.Log.Infoln("[POW] Received reactor event; breaking out.")
+ //ethutil.Config.Log.Infoln("[POW] Received reactor event; breaking out.")
return nil
default:
i++
diff --git a/ethchain/stack.go b/ethchain/stack.go
index e9297b324..bf34e6ea9 100644
--- a/ethchain/stack.go
+++ b/ethchain/stack.go
@@ -65,7 +65,7 @@ func (st *Stack) Peekn() (*big.Int, *big.Int) {
}
func (st *Stack) Push(d *big.Int) {
- st.data = append(st.data, d)
+ st.data = append(st.data, new(big.Int).Set(d))
}
func (st *Stack) Get(amount *big.Int) []*big.Int {
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index c7c6857d8..8b56d65bb 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -100,36 +100,52 @@ func (sm *StateManager) MakeContract(state *State, tx *Transaction) *StateObject
func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Transaction) {
// Process each transaction/contract
for _, tx := range txs {
- // If there's no recipient, it's a contract
- // Check if this is a contract creation traction and if so
- // create a contract of this tx.
- if tx.IsContract() {
- err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
- if err == nil {
- contract := sm.MakeContract(state, tx)
- if contract != nil {
- sm.EvalScript(state, contract.Init(), contract, tx, block)
- } else {
- ethutil.Config.Log.Infoln("[STATE] Unable to create contract")
- }
+ sm.ApplyTransaction(state, block, tx)
+ }
+}
+
+func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) error {
+ // If there's no recipient, it's a contract
+ // Check if this is a contract creation traction and if so
+ // create a contract of this tx.
+ if tx.IsContract() {
+ err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
+ if err == nil {
+ contract := sm.MakeContract(state, tx)
+ if contract != nil {
+ sm.EvalScript(state, contract.Init(), contract, tx, block)
} else {
- ethutil.Config.Log.Infoln("[STATE] contract create:", err)
+ return fmt.Errorf("[STATE] Unable to create contract")
}
} else {
- err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
- contract := state.GetStateObject(tx.Recipient)
- ethutil.Config.Log.Debugf("contract recip %x\n", tx.Recipient)
- if err == nil && len(contract.Script()) > 0 {
- sm.EvalScript(state, contract.Script(), contract, tx, block)
- } else if err != nil {
- ethutil.Config.Log.Infoln("[STATE] process:", err)
- }
+ return fmt.Errorf("[STATE] contract create:", err)
+ }
+ } else {
+ err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
+ contract := state.GetStateObject(tx.Recipient)
+ if err == nil && contract != nil && len(contract.Script()) > 0 {
+ sm.EvalScript(state, contract.Script(), contract, tx, block)
+ } else if err != nil {
+ return fmt.Errorf("[STATE] process:", err)
}
}
+
+ return nil
+}
+
+func (sm *StateManager) Process(block *Block, dontReact bool) error {
+ if !sm.bc.HasBlock(block.PrevHash) {
+ return ParentError(block.PrevHash)
+ }
+
+ parent := sm.bc.GetBlock(block.PrevHash)
+
+ return sm.ProcessBlock(parent.State(), parent, block, dontReact)
+
}
// Block processing and validating with a given (temporarily) state
-func (sm *StateManager) ProcessBlock(state *State, block *Block, dontReact bool) error {
+func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontReact bool) error {
// Processing a blocks may never happen simultaneously
sm.mutex.Lock()
defer sm.mutex.Unlock()
@@ -153,7 +169,7 @@ func (sm *StateManager) ProcessBlock(state *State, block *Block, dontReact bool)
}
// Process the transactions on to current block
- sm.ApplyTransactions(state, sm.bc.CurrentBlock, block.Transactions())
+ sm.ApplyTransactions(state, parent, block.Transactions())
// Block validation
if err := sm.ValidateBlock(block); err != nil {
@@ -170,7 +186,7 @@ func (sm *StateManager) ProcessBlock(state *State, block *Block, dontReact bool)
//if !sm.compState.Cmp(state) {
if !block.State().Cmp(state) {
- return fmt.Errorf("Invalid merkle root. Expected %x, got %x", block.State().trie.Root, state.trie.Root)
+ return fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root)
}
// Calculate the new total difficulty and sync back to the db
@@ -182,7 +198,7 @@ func (sm *StateManager) ProcessBlock(state *State, block *Block, dontReact bool)
sm.bc.Add(block)
sm.notifyChanges(state)
- ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.BlockInfo().Number, block.Hash())
+ ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.Number, block.Hash())
if dontReact == false {
sm.Ethereum.Reactor().Post("newBlock", block)
diff --git a/ethchain/state_object_test.go b/ethchain/state_object_test.go
index 1db01a537..e955acc56 100644
--- a/ethchain/state_object_test.go
+++ b/ethchain/state_object_test.go
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/ethereum/eth-go/ethdb"
"github.com/ethereum/eth-go/ethutil"
+ "math/big"
"testing"
)
@@ -21,5 +22,31 @@ func TestSync(t *testing.T) {
state.Sync()
object := state.GetStateObject([]byte("aa"))
- fmt.Printf("%x\n", object.Script())
+ if len(object.Script()) == 0 {
+ t.Fail()
+ }
+}
+
+func TestObjectGet(t *testing.T) {
+ ethutil.ReadConfig("", ethutil.LogStd)
+
+ db, _ := ethdb.NewMemDatabase()
+ ethutil.Config.Db = db
+
+ state := NewState(ethutil.NewTrie(db, ""))
+
+ contract := NewContract([]byte("aa"), ethutil.Big1, ZeroHash256)
+ state.UpdateStateObject(contract)
+
+ contract = state.GetStateObject([]byte("aa"))
+ contract.SetStorage(big.NewInt(0), ethutil.NewValue("hello"))
+ o := contract.GetMem(big.NewInt(0))
+ fmt.Println(o)
+
+ state.UpdateStateObject(contract)
+ contract.SetStorage(big.NewInt(0), ethutil.NewValue("hello00"))
+
+ contract = state.GetStateObject([]byte("aa"))
+ o = contract.GetMem(big.NewInt(0))
+ fmt.Println("after", o)
}
diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go
index 796ec7c9a..dcf0c4c31 100644
--- a/ethchain/transaction_pool.go
+++ b/ethchain/transaction_pool.go
@@ -81,8 +81,9 @@ func NewTxPool(ethereum EthManager) *TxPool {
// Blocking function. Don't use directly. Use QueueTransaction instead
func (pool *TxPool) addTransaction(tx *Transaction) {
pool.mutex.Lock()
+ defer pool.mutex.Unlock()
+
pool.pool.PushBack(tx)
- pool.mutex.Unlock()
// Broadcast the transaction to the rest of the peers
pool.Ethereum.Broadcast(ethwire.MsgTxTy, []interface{}{tx.RlpData()})
@@ -182,9 +183,7 @@ out:
// Validate the transaction
err := pool.ValidateTransaction(tx)
if err != nil {
- if ethutil.Config.Debug {
- log.Println("Validating Tx failed", err)
- }
+ ethutil.Config.Log.Debugln("Validating Tx failed", err)
} else {
// Call blocking version.
pool.addTransaction(tx)
diff --git a/ethchain/vm.go b/ethchain/vm.go
index c4304e5ac..d8254998e 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -390,10 +390,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
require(1)
loc := stack.Pop()
val := closure.GetMem(loc)
+ //fmt.Println("get", val.BigInt(), "@", loc)
stack.Push(val.BigInt())
case oSSTORE:
require(2)
val, loc := stack.Popn()
+ //fmt.Println("storing", val, "@", loc)
closure.SetStorage(loc, ethutil.NewValue(val))
// Add the change to manifest
diff --git a/ethchain/vm_test.go b/ethchain/vm_test.go
index 5d03ccf0c..2ec70536a 100644
--- a/ethchain/vm_test.go
+++ b/ethchain/vm_test.go
@@ -1,5 +1,6 @@
package ethchain
+/*
import (
_ "bytes"
"fmt"
@@ -23,10 +24,11 @@ func TestRun4(t *testing.T) {
if a > b {
int32 c = this.caller()
}
- Exit()
+ exit()
`), false)
tx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), script, nil)
- addr := tx.Hash()[12:]
+ tx.Sign(ContractAddr)
+ addr := tx.CreationAddress()
contract := MakeContract(tx, state)
state.UpdateStateObject(contract)
fmt.Printf("%x\n", addr)
@@ -34,7 +36,7 @@ func TestRun4(t *testing.T) {
callerScript, err := mutan.Compile(strings.NewReader(`
// Check if there's any cash in the initial store
if this.store[1000] == 0 {
- this.store[1000] = 10^20
+ this.store[1000] = 10**20
}
@@ -93,3 +95,4 @@ func TestRun4(t *testing.T) {
}
fmt.Println("account.Amount =", account.Amount)
}
+*/
diff --git a/ethminer/miner.go b/ethminer/miner.go
index 294bc7b3d..2e31dcead 100644
--- a/ethminer/miner.go
+++ b/ethminer/miner.go
@@ -60,10 +60,10 @@ func (miner *Miner) listener() {
select {
case chanMessage := <-miner.reactChan:
if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
- ethutil.Config.Log.Infoln("[MINER] Got new block via Reactor")
+ //ethutil.Config.Log.Infoln("[MINER] Got new block via Reactor")
if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 {
// TODO: Perhaps continue mining to get some uncle rewards
- ethutil.Config.Log.Infoln("[MINER] New top block found resetting state")
+ //ethutil.Config.Log.Infoln("[MINER] New top block found resetting state")
// Filter out which Transactions we have that were not in this block
var newtxs []*ethchain.Transaction
@@ -87,13 +87,11 @@ func (miner *Miner) listener() {
if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
ethutil.Config.Log.Infoln("[MINER] Adding uncle block")
miner.uncles = append(miner.uncles, block)
- //miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
}
}
}
if tx, ok := chanMessage.Resource.(*ethchain.Transaction); ok {
- //log.Infoln("[MINER] Got new transaction from Reactor", tx)
found := false
for _, ctx := range miner.txs {
if found = bytes.Compare(ctx.Hash(), tx.Hash()) == 0; found {
@@ -102,42 +100,54 @@ func (miner *Miner) listener() {
}
if found == false {
- //log.Infoln("[MINER] We did not know about this transaction, adding")
+ // Undo all previous commits
+ miner.block.Undo()
+ // Apply new transactions
miner.txs = append(miner.txs, tx)
- miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
- miner.block.SetTransactions(miner.txs)
- } else {
- //log.Infoln("[MINER] We already had this transaction, ignoring")
}
}
default:
- ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(miner.txs), "transactions")
+ miner.mineNewBlock()
+ }
+ }
+}
- // Apply uncles
- if len(miner.uncles) > 0 {
- miner.block.SetUncles(miner.uncles)
- }
+func (self *Miner) mineNewBlock() {
+ stateManager := self.ethereum.StateManager()
- // Apply all transactions to the block
- miner.ethereum.StateManager().ApplyTransactions(miner.block.State(), miner.block, miner.block.Transactions())
- miner.ethereum.StateManager().AccumelateRewards(miner.block.State(), miner.block)
-
- // Search the nonce
- miner.block.Nonce = miner.pow.Search(miner.block, miner.quitChan)
- if miner.block.Nonce != nil {
- err := miner.ethereum.StateManager().ProcessBlock(miner.ethereum.StateManager().CurrentState(), miner.block, true)
- if err != nil {
- ethutil.Config.Log.Infoln(err)
- miner.txs = []*ethchain.Transaction{} // Move this somewhere neat
- miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
- } else {
- miner.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{miner.block.Value().Val})
- ethutil.Config.Log.Infof("[MINER] 🔨 Mined block %x\n", miner.block.Hash())
+ self.block = self.ethereum.BlockChain().NewBlock(self.coinbase, self.txs)
- miner.txs = []*ethchain.Transaction{} // Move this somewhere neat
- miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
- }
- }
+ // Apply uncles
+ if len(self.uncles) > 0 {
+ self.block.SetUncles(self.uncles)
+ }
+
+ // Accumulate all valid transaction and apply them to the new state
+ var txs []*ethchain.Transaction
+ for _, tx := range self.txs {
+ if err := stateManager.ApplyTransaction(self.block.State(), self.block, tx); err == nil {
+ txs = append(txs, tx)
+ }
+ }
+ self.txs = txs
+ // Set the transactions to the block so the new SHA3 can be calculated
+ self.block.SetTransactions(self.txs)
+ // Accumulate the rewards included for this block
+ stateManager.AccumelateRewards(self.block.State(), self.block)
+
+ ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(self.txs), "transactions")
+
+ // Find a valid nonce
+ self.block.Nonce = self.pow.Search(self.block, self.quitChan)
+ if self.block.Nonce != nil {
+ err := self.ethereum.StateManager().Process(self.block, true)
+ if err != nil {
+ ethutil.Config.Log.Infoln(err)
+ } else {
+ self.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{self.block.Value().Val})
+ ethutil.Config.Log.Infof("[MINER] 🔨 Mined block %x\n", self.block.Hash())
+ // Gather the new batch of transactions currently in the tx pool
+ self.txs = self.ethereum.TxPool().CurrentTransactions()
}
}
}
diff --git a/ethpub/pub.go b/ethpub/pub.go
index ec187e276..cd002b500 100644
--- a/ethpub/pub.go
+++ b/ethpub/pub.go
@@ -24,18 +24,9 @@ func NewPEthereum(manager ethchain.EthManager) *PEthereum {
func (lib *PEthereum) GetBlock(hexHash string) *PBlock {
hash := ethutil.FromHex(hexHash)
-
block := lib.blockChain.GetBlock(hash)
- var blockInfo *PBlock
-
- if block != nil {
- blockInfo = &PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
- } else {
- blockInfo = &PBlock{Number: -1, Hash: ""}
- }
-
- return blockInfo
+ return NewPBlock(block)
}
func (lib *PEthereum) GetKey() *PKey {
diff --git a/ethpub/types.go b/ethpub/types.go
index 77cca78b9..afec47fdc 100644
--- a/ethpub/types.go
+++ b/ethpub/types.go
@@ -8,16 +8,26 @@ import (
// Block interface exposed to QML
type PBlock struct {
+ ref *ethchain.Block
Number int `json:"number"`
Hash string `json:"hash"`
}
// Creates a new QML Block from a chain block
func NewPBlock(block *ethchain.Block) *PBlock {
- info := block.BlockInfo()
- hash := hex.EncodeToString(block.Hash())
+ if block == nil {
+ return nil
+ }
+
+ return &PBlock{ref: block, Number: int(block.Number.Uint64()), Hash: ethutil.Hex(block.Hash())}
+}
- return &PBlock{Number: int(info.Number), Hash: hash}
+func (self *PBlock) ToString() string {
+ if self.ref != nil {
+ return self.ref.String()
+ }
+
+ return ""
}
type PTx struct {
diff --git a/ethutil/config.go b/ethutil/config.go
index abe86babe..1b41c4634 100644
--- a/ethutil/config.go
+++ b/ethutil/config.go
@@ -42,7 +42,7 @@ func ReadConfig(base string, logTypes LoggerType) *config {
}
}
- Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC7"}
+ Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC8"}
Config.Log = NewLogger(logTypes, LogLevelDebug)
Config.SetClientString("/Ethereum(G)")
}
diff --git a/peer.go b/peer.go
index 690281da9..7f81489b6 100644
--- a/peer.go
+++ b/peer.go
@@ -335,8 +335,8 @@ func (p *Peer) HandleInbound() {
block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i))
//p.ethereum.StateManager().PrepareDefault(block)
- state := p.ethereum.StateManager().CurrentState()
- err = p.ethereum.StateManager().ProcessBlock(state, block, false)
+ //state := p.ethereum.StateManager().CurrentState()
+ err = p.ethereum.StateManager().Process(block, false)
if err != nil {
if ethutil.Config.Debug {
@@ -658,10 +658,8 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) {
ethutil.Config.Log.Debugf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr())
- /*
- msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{})
- p.QueueMessage(msg)
- */
+ msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{})
+ p.QueueMessage(msg)
}
}