Commit ef7961b7 authored by Taylor Gerring's avatar Taylor Gerring

Merge pull request #194 from ethereum/poc8

Update tests branch to PoC8
parents c17a3cb0 8cf9ed0e
...@@ -36,50 +36,40 @@ Automated (dev) builds ...@@ -36,50 +36,40 @@ Automated (dev) builds
* [Windows] Coming soon™ * [Windows] Coming soon™
* [Linux] Coming soon™ * [Linux] Coming soon™
Packages Binaries
======== ========
Ethereum Go is split up in several sub packages Please refer to each Go Ethereum comes with several binaries found in
individual package for more information. [cmd](https://github.com/ethereum/go-ethereum/tree/master/cmd):
1. [eth](https://github.com/ethereum/go-ethereum)
2. [ethchain](https://github.com/ethereum/go-ethereum/tree/master/ethchain) * `mist` Official Ethereum Browser
3. [ethwire](https://github.com/ethereum/go-ethereum/tree/master/ethwire) * `ethereum` Ethereum CLI
4. [ethdb](https://github.com/ethereum/go-ethereum/tree/master/ethdb) * `ethtest` test tool which runs with the [tests](https://github.com/ethereum/testes) suit:
5. [ethutil](https://github.com/ethereum/go-ethereum/tree/master/ethutil) `ethtest "`cat myfile.json`"`.
6. [ethpipe](https://github.com/ethereum/go-ethereum/tree/master/ethpipe) * `evm` is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas
7. [ethvm](https://github.com/ethereum/go-ethereum/tree/master/ethvm) 10000 -price 0 -dump`. See `-h` for a detailed description.
8. [ethtrie](https://github.com/ethereum/go-ethereum/tree/master/ethtrie)
9. [ethreact](https://github.com/ethereum/go-ethereum/tree/master/ethreact)
10. [ethlog](https://github.com/ethereum/go-ethereum/tree/master/ethlog)
The [eth](https://github.com/ethereum/go-ethereum) is the top-level package
of the Ethereum protocol. It functions as the Ethereum bootstrapping and
peer communication layer. The [ethchain](https://github.com/ethereum/go-ethereum/tree/master/ethchain)
contains the Ethereum blockchain, block manager, transaction and
transaction handlers. The [ethwire](https://github.com/ethereum/go-ethereum/tree/master/ethwire) contains
the Ethereum [wire protocol](http://wiki.ethereum.org/index.php/Wire_Protocol) which can be used
to hook in to the Ethereum network. [ethutil](https://github.com/ethereum/go-ethereum/tree/master/ethutil) contains
utility functions which are not Ethereum specific. The utility package
contains the [patricia trie](http://wiki.ethereum.org/index.php/Patricia_Tree),
[RLP Encoding](http://wiki.ethereum.org/index.php/RLP) and hex encoding
helpers. The [ethdb](https://github.com/ethereum/go-ethereum/tree/master/ethdb) package
contains the LevelDB interface and memory DB interface.
General command line options General command line options
============================ ============================
``` ```
Shared between ethereum and Mist == Shared between ethereum and Mist ==
= Settings
-id Set the custom identifier of the client (shows up on other clients) -id Set the custom identifier of the client (shows up on other clients)
-port Port on which the server will accept incomming connections -port Port on which the server will accept incomming connections
-upnp Enable UPnP -upnp Enable UPnP
-maxpeer Desired amount of peers -maxpeer Desired amount of peers
-rpc Start JSON RPC -rpc Start JSON RPC
-dir Data directory used to store configs and databases -dir Data directory used to store configs and databases
-import Import a private key
-genaddr Generates a new address and private key (destructive action) = Utility
-h This -h This
-import Import a private key
-genaddr Generates a new address and private key (destructive action)
-dump Dump a specific state of a block to stdout given the -number or -hash
-difftool Supress all output and prints VM output to stdout
-diff vm=only vm output, all=all output including state storage
Ethereum only Ethereum only
ethereum [options] [filename] ethereum [options] [filename]
...@@ -87,23 +77,11 @@ ethereum [options] [filename] ...@@ -87,23 +77,11 @@ ethereum [options] [filename]
filename Load the given file and interpret as JavaScript filename Load the given file and interpret as JavaScript
-m Start mining blocks -m Start mining blocks
Mist only == Mist only ==
-asset_path absolute path to GUI assets directory -asset_path absolute path to GUI assets directory
``` ```
Tools
=====
Go Ethereum comes with several binaries:
* `mist` Official Ethereum Browser
* `ethereum` Ethereum CLI
* `ethtest` test tool which runs with the [tests](https://github.com/ethereum/testes) suit:
`ethtest "`cat myfile.json`"`.
* `evm` is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas
10000 -price 0 -dump`. See `-h` for a detailed description.
Contribution Contribution
============ ============
......
...@@ -10,8 +10,10 @@ import ( ...@@ -10,8 +10,10 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/wire" "github.com/ethereum/go-ethereum/wire"
) )
...@@ -20,7 +22,7 @@ var poollogger = logger.NewLogger("BPOOL") ...@@ -20,7 +22,7 @@ var poollogger = logger.NewLogger("BPOOL")
type block struct { type block struct {
from *Peer from *Peer
peer *Peer peer *Peer
block *chain.Block block *types.Block
reqAt time.Time reqAt time.Time
requested int requested int
} }
...@@ -73,7 +75,7 @@ func (self *BlockPool) HasCommonHash(hash []byte) bool { ...@@ -73,7 +75,7 @@ func (self *BlockPool) HasCommonHash(hash []byte) bool {
return self.eth.ChainManager().GetBlock(hash) != nil return self.eth.ChainManager().GetBlock(hash) != nil
} }
func (self *BlockPool) Blocks() (blocks chain.Blocks) { func (self *BlockPool) Blocks() (blocks types.Blocks) {
for _, item := range self.pool { for _, item := range self.pool {
if item.block != nil { if item.block != nil {
blocks = append(blocks, item.block) blocks = append(blocks, item.block)
...@@ -123,15 +125,15 @@ func (self *BlockPool) AddHash(hash []byte, peer *Peer) { ...@@ -123,15 +125,15 @@ func (self *BlockPool) AddHash(hash []byte, peer *Peer) {
} }
} }
func (self *BlockPool) Add(b *chain.Block, peer *Peer) { func (self *BlockPool) Add(b *types.Block, peer *Peer) {
self.addBlock(b, peer, false) self.addBlock(b, peer, false)
} }
func (self *BlockPool) AddNew(b *chain.Block, peer *Peer) { func (self *BlockPool) AddNew(b *types.Block, peer *Peer) {
self.addBlock(b, peer, true) self.addBlock(b, peer, true)
} }
func (self *BlockPool) addBlock(b *chain.Block, peer *Peer, newBlock bool) { func (self *BlockPool) addBlock(b *types.Block, peer *Peer, newBlock bool) {
self.mut.Lock() self.mut.Lock()
defer self.mut.Unlock() defer self.mut.Unlock()
...@@ -283,7 +285,7 @@ out: ...@@ -283,7 +285,7 @@ out:
break out break out
case <-procTimer.C: case <-procTimer.C:
blocks := self.Blocks() blocks := self.Blocks()
chain.BlockBy(chain.Number).Sort(blocks) types.BlockBy(types.Number).Sort(blocks)
// Find common block // Find common block
for i, block := range blocks { for i, block := range blocks {
...@@ -309,10 +311,6 @@ out: ...@@ -309,10 +311,6 @@ out:
} }
} }
// TODO figure out whether we were catching up
// If caught up and just a new block has been propagated:
// sm.eth.EventMux().Post(NewBlockEvent{block})
// otherwise process and don't emit anything
if len(blocks) > 0 { if len(blocks) > 0 {
chainManager := self.eth.ChainManager() chainManager := self.eth.ChainManager()
// Test and import // Test and import
...@@ -333,9 +331,14 @@ out: ...@@ -333,9 +331,14 @@ out:
self.td = ethutil.Big0 self.td = ethutil.Big0
self.peer = nil self.peer = nil
} else { } else {
chainManager.InsertChain(bchain) if !chain.IsTDError(err) {
for _, block := range blocks { chainManager.InsertChain(bchain, func(block *types.Block, messages state.Messages) {
self.Remove(block.Hash()) self.eth.EventMux().Post(chain.NewBlockEvent{block})
self.eth.EventMux().Post(messages)
self.Remove(block.Hash())
})
} }
} }
} }
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
...@@ -69,7 +70,7 @@ type BlockManager struct { ...@@ -69,7 +70,7 @@ type BlockManager struct {
// The last attempted block is mainly used for debugging purposes // The last attempted block is mainly used for debugging purposes
// This does not have to be a valid block and will be set during // This does not have to be a valid block and will be set during
// 'Process' & canonical validation. // 'Process' & canonical validation.
lastAttemptedBlock *Block lastAttemptedBlock *types.Block
events event.Subscription events event.Subscription
} }
...@@ -117,11 +118,11 @@ func (sm *BlockManager) ChainManager() *ChainManager { ...@@ -117,11 +118,11 @@ func (sm *BlockManager) ChainManager() *ChainManager {
return sm.bc return sm.bc
} }
func (self *BlockManager) ProcessTransactions(coinbase *state.StateObject, state *state.State, block, parent *Block, txs Transactions) (Receipts, Transactions, Transactions, Transactions, error) { func (self *BlockManager) ProcessTransactions(coinbase *state.StateObject, state *state.State, block, parent *types.Block, txs types.Transactions) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) {
var ( var (
receipts Receipts receipts types.Receipts
handled, unhandled Transactions handled, unhandled types.Transactions
erroneous Transactions erroneous types.Transactions
totalUsedGas = big.NewInt(0) totalUsedGas = big.NewInt(0)
err error err error
) )
...@@ -159,8 +160,9 @@ done: ...@@ -159,8 +160,9 @@ done:
txGas.Sub(txGas, st.gas) txGas.Sub(txGas, st.gas)
cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas)) cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
receipt := &Receipt{ethutil.CopyBytes(state.Root()), cumulative, nil /*bloom*/, state.Logs()} receipt := types.NewReceipt(state.Root(), cumulative)
receipt.Bloom = CreateBloom(Receipts{receipt}) receipt.SetLogs(state.Logs())
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
// Notify all subscribers // Notify all subscribers
go self.eth.EventMux().Post(TxPostEvent{tx}) go self.eth.EventMux().Post(TxPostEvent{tx})
...@@ -178,7 +180,7 @@ done: ...@@ -178,7 +180,7 @@ done:
return receipts, handled, unhandled, erroneous, err return receipts, handled, unhandled, erroneous, err
} }
func (sm *BlockManager) Process(block *Block) (td *big.Int, msgs state.Messages, err error) { func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Messages, err error) {
// Processing a blocks may never happen simultaneously // Processing a blocks may never happen simultaneously
sm.mutex.Lock() sm.mutex.Lock()
defer sm.mutex.Unlock() defer sm.mutex.Unlock()
...@@ -195,7 +197,7 @@ func (sm *BlockManager) Process(block *Block) (td *big.Int, msgs state.Messages, ...@@ -195,7 +197,7 @@ func (sm *BlockManager) Process(block *Block) (td *big.Int, msgs state.Messages,
return sm.ProcessWithParent(block, parent) return sm.ProcessWithParent(block, parent)
} }
func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, messages state.Messages, err error) { func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
sm.lastAttemptedBlock = block sm.lastAttemptedBlock = block
state := parent.State().Copy() state := parent.State().Copy()
...@@ -215,13 +217,13 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me ...@@ -215,13 +217,13 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me
return return
} }
txSha := DeriveSha(block.transactions) txSha := types.DeriveSha(block.Transactions())
if bytes.Compare(txSha, block.TxSha) != 0 { if bytes.Compare(txSha, block.TxSha) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha) err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
return return
} }
receiptSha := DeriveSha(receipts) receiptSha := types.DeriveSha(receipts)
if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
return return
...@@ -238,8 +240,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me ...@@ -238,8 +240,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me
return return
} }
block.receipts = receipts // although this isn't necessary it be in the future //block.receipts = receipts // although this isn't necessary it be in the future
rbloom := CreateBloom(receipts) rbloom := types.CreateBloom(receipts)
if bytes.Compare(rbloom, block.LogsBloom) != 0 { if bytes.Compare(rbloom, block.LogsBloom) != 0 {
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return return
...@@ -272,7 +274,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me ...@@ -272,7 +274,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me
} }
} }
func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *Block) (receipts Receipts, err error) { func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *types.Block) (receipts types.Receipts, err error) {
coinbase := state.GetOrNewStateObject(block.Coinbase) coinbase := state.GetOrNewStateObject(block.Coinbase)
coinbase.SetGasPool(block.CalcGasLimit(parent)) coinbase.SetGasPool(block.CalcGasLimit(parent))
...@@ -285,7 +287,7 @@ func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *Block) (rec ...@@ -285,7 +287,7 @@ func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *Block) (rec
return receipts, nil return receipts, nil
} }
func (sm *BlockManager) CalculateTD(block *Block) (*big.Int, bool) { func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
uncleDiff := new(big.Int) uncleDiff := new(big.Int)
for _, uncle := range block.Uncles { for _, uncle := range block.Uncles {
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty) uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
...@@ -311,7 +313,7 @@ func (sm *BlockManager) CalculateTD(block *Block) (*big.Int, bool) { ...@@ -311,7 +313,7 @@ func (sm *BlockManager) CalculateTD(block *Block) (*big.Int, bool) {
// Validates the current block. Returns an error if the block was invalid, // Validates the current block. Returns an error if the block was invalid,
// an uncle or anything that isn't on the current block chain. // an uncle or anything that isn't on the current block chain.
// Validation validates easy over difficult (dagger takes longer time = difficult) // Validation validates easy over difficult (dagger takes longer time = difficult)
func (sm *BlockManager) ValidateBlock(block, parent *Block) error { func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
expd := CalcDifficulty(block, parent) expd := CalcDifficulty(block, parent)
if expd.Cmp(block.Difficulty) < 0 { if expd.Cmp(block.Difficulty) < 0 {
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
...@@ -337,7 +339,7 @@ func (sm *BlockManager) ValidateBlock(block, parent *Block) error { ...@@ -337,7 +339,7 @@ func (sm *BlockManager) ValidateBlock(block, parent *Block) error {
return nil return nil
} }
func (sm *BlockManager) AccumelateRewards(state *state.State, block, parent *Block) error { func (sm *BlockManager) AccumelateRewards(state *state.State, block, parent *types.Block) error {
reward := new(big.Int).Set(BlockReward) reward := new(big.Int).Set(BlockReward)
knownUncles := ethutil.Set(parent.Uncles) knownUncles := ethutil.Set(parent.Uncles)
...@@ -380,7 +382,7 @@ func (sm *BlockManager) AccumelateRewards(state *state.State, block, parent *Blo ...@@ -380,7 +382,7 @@ func (sm *BlockManager) AccumelateRewards(state *state.State, block, parent *Blo
return nil return nil
} }
func (sm *BlockManager) GetMessages(block *Block) (messages []*state.Message, err error) { func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Message, err error) {
if !sm.bc.HasBlock(block.PrevHash) { if !sm.bc.HasBlock(block.PrevHash) {
return nil, ParentError(block.PrevHash) return nil, ParentError(block.PrevHash)
} }
......
This diff is collapsed.
package chain package chain
import (
"fmt"
"math/big"
"testing"
"time"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
)
var TD *big.Int
func init() {
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
ethutil.Config.Db, _ = ethdb.NewMemDatabase()
}
type fakeproc struct {
}
func (self fakeproc) ProcessWithParent(a, b *types.Block) (*big.Int, state.Messages, error) {
TD = new(big.Int).Add(TD, big.NewInt(1))
return TD, nil, nil
}
func makechain(cman *ChainManager, max int) *BlockChain {
blocks := make(types.Blocks, max)
for i := 0; i < max; i++ {
addr := ethutil.LeftPadBytes([]byte{byte(i)}, 20)
block := cman.NewBlock(addr)
if i != 0 {
cman.CurrentBlock = blocks[i-1]
}
blocks[i] = block
}
return NewChain(blocks)
}
func TestLongerFork(t *testing.T) {
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chainA := makechain(cman, 5)
TD = big.NewInt(1)
chainB := makechain(cman, 10)
td, err := cman.TestChain(chainA)
if err != nil {
t.Error("unable to create new TD from chainA:", err)
}
cman.TD = td
_, err = cman.TestChain(chainB)
if err != nil {
t.Error("expected chainB not to give errors:", err)
}
}
func TestEqualFork(t *testing.T) {
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chainA := makechain(cman, 5)
TD = big.NewInt(2)
chainB := makechain(cman, 5)
td, err := cman.TestChain(chainA)
if err != nil {
t.Error("unable to create new TD from chainA:", err)
}
cman.TD = td
_, err = cman.TestChain(chainB)
if err != nil {
t.Error("expected chainB not to give errors:", err)
}
}
func TestBrokenChain(t *testing.T) {
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chain := makechain(cman, 5)
chain.Remove(chain.Front())
_, err := cman.TestChain(chain)
if err == nil {
t.Error("expected broken chain to return error")
}
}
func BenchmarkChainTesting(b *testing.B) {
const chainlen = 1000
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
ethutil.Config.Db, _ = ethdb.NewMemDatabase()
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chain := makechain(cman, chainlen)
stime := time.Now()
cman.TestChain(chain)
fmt.Println(chainlen, "took", time.Since(stime))
}
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"math/rand" "math/rand"
"time" "time"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
...@@ -15,7 +16,7 @@ import ( ...@@ -15,7 +16,7 @@ import (
var powlogger = logger.NewLogger("POW") var powlogger = logger.NewLogger("POW")
type PoW interface { type PoW interface {
Search(block *Block, stop <-chan struct{}) []byte Search(block *types.Block, stop <-chan struct{}) []byte
Verify(hash []byte, diff *big.Int, nonce []byte) bool Verify(hash []byte, diff *big.Int, nonce []byte) bool
GetHashrate() int64 GetHashrate() int64
Turbo(bool) Turbo(bool)
...@@ -35,7 +36,7 @@ func (pow *EasyPow) Turbo(on bool) { ...@@ -35,7 +36,7 @@ func (pow *EasyPow) Turbo(on bool) {
pow.turbo = on pow.turbo = on
} }
func (pow *EasyPow) Search(block *Block, stop <-chan struct{}) []byte { func (pow *EasyPow) Search(block *types.Block, stop <-chan struct{}) []byte {
r := rand.New(rand.NewSource(time.Now().UnixNano())) r := rand.New(rand.NewSource(time.Now().UnixNano()))
hash := block.HashNoNonce() hash := block.HashNoNonce()
diff := block.Difficulty diff := block.Difficulty
......
package chain package chain
import "github.com/ethereum/go-ethereum/chain/types"
// TxPreEvent is posted when a transaction enters the transaction pool. // TxPreEvent is posted when a transaction enters the transaction pool.
type TxPreEvent struct{ Tx *Transaction } type TxPreEvent struct{ Tx *types.Transaction }
// TxPostEvent is posted when a transaction has been processed. // TxPostEvent is posted when a transaction has been processed.
type TxPostEvent struct{ Tx *Transaction } type TxPostEvent struct{ Tx *types.Transaction }
// NewBlockEvent is posted when a block has been imported. // NewBlockEvent is posted when a block has been imported.
type NewBlockEvent struct{ Block *Block } type NewBlockEvent struct{ Block *types.Block }
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"math" "math"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
) )
...@@ -24,7 +25,7 @@ type Filter struct { ...@@ -24,7 +25,7 @@ type Filter struct {
Altered []AccountChange Altered []AccountChange
BlockCallback func(*Block) BlockCallback func(*types.Block)
MessageCallback func(state.Messages) MessageCallback func(state.Messages)
} }
...@@ -171,11 +172,11 @@ func (self *Filter) FilterMessages(msgs []*state.Message) []*state.Message { ...@@ -171,11 +172,11 @@ func (self *Filter) FilterMessages(msgs []*state.Message) []*state.Message {
return messages return messages
} }
func (self *Filter) bloomFilter(block *Block) bool { func (self *Filter) bloomFilter(block *types.Block) bool {
var fromIncluded, toIncluded bool var fromIncluded, toIncluded bool
if len(self.from) > 0 { if len(self.from) > 0 {
for _, from := range self.from { for _, from := range self.from {
if BloomLookup(block.LogsBloom, from) { if types.BloomLookup(block.LogsBloom, from) {
fromIncluded = true fromIncluded = true
break break
} }
...@@ -186,7 +187,7 @@ func (self *Filter) bloomFilter(block *Block) bool { ...@@ -186,7 +187,7 @@ func (self *Filter) bloomFilter(block *Block) bool {
if len(self.to) > 0 { if len(self.to) > 0 {
for _, to := range self.to { for _, to := range self.to {
if BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) { if types.BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) {
toIncluded = true toIncluded = true
break break
} }
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"container/list" "container/list"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
...@@ -19,7 +20,7 @@ type TestManager struct { ...@@ -19,7 +20,7 @@ type TestManager struct {
db ethutil.Database db ethutil.Database
txPool *TxPool txPool *TxPool
blockChain *ChainManager blockChain *ChainManager
Blocks []*Block Blocks []*types.Block
} }
func (s *TestManager) IsListening() bool { func (s *TestManager) IsListening() bool {
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm" "github.com/ethereum/go-ethereum/vm"
) )
...@@ -26,17 +27,17 @@ import ( ...@@ -26,17 +27,17 @@ import (
*/ */
type StateTransition struct { type StateTransition struct {
coinbase, receiver []byte coinbase, receiver []byte
tx *Transaction tx *types.Transaction
gas, gasPrice *big.Int gas, gasPrice *big.Int
value *big.Int value *big.Int
data []byte data []byte
state *state.State state *state.State
block *Block block *types.Block
cb, rec, sen *state.StateObject cb, rec, sen *state.StateObject
} }
func NewStateTransition(coinbase *state.StateObject, tx *Transaction, state *state.State, block *Block) *StateTransition { func NewStateTransition(coinbase *state.StateObject, tx *types.Transaction, state *state.State, block *types.Block) *StateTransition {
return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil} return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil}
} }
...@@ -203,7 +204,7 @@ func (self *StateTransition) TransitionState() (err error) { ...@@ -203,7 +204,7 @@ func (self *StateTransition) TransitionState() (err error) {
}) })
// Process the init code and create 'valid' contract // Process the init code and create 'valid' contract
if IsContractAddr(self.receiver) { if types.IsContractAddr(self.receiver) {
// Evaluate the initialization script // Evaluate the initialization script
// and use the return value as the // and use the return value as the
// script section for the state object. // script section for the state object.
...@@ -280,7 +281,7 @@ func (self *StateTransition) Eval(msg *state.Message, script []byte, context *st ...@@ -280,7 +281,7 @@ func (self *StateTransition) Eval(msg *state.Message, script []byte, context *st
} }
// Converts an transaction in to a state object // Converts an transaction in to a state object
func MakeContract(tx *Transaction, state *state.State) *state.StateObject { func MakeContract(tx *types.Transaction, state *state.State) *state.StateObject {
addr := tx.CreationAddress(state) addr := tx.CreationAddress(state)
contract := state.GetOrNewStateObject(addr) contract := state.GetOrNewStateObject(addr)
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"math/big" "math/big"
"sync" "sync"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/wire" "github.com/ethereum/go-ethereum/wire"
...@@ -16,7 +17,7 @@ var txplogger = logger.NewLogger("TXP") ...@@ -16,7 +17,7 @@ var txplogger = logger.NewLogger("TXP")
const txPoolQueueSize = 50 const txPoolQueueSize = 50
type TxPoolHook chan *Transaction type TxPoolHook chan *types.Transaction
type TxMsgTy byte type TxMsgTy byte
const ( const (
...@@ -26,21 +27,21 @@ const ( ...@@ -26,21 +27,21 @@ const (
var MinGasPrice = big.NewInt(10000000000000) var MinGasPrice = big.NewInt(10000000000000)
type TxMsg struct { type TxMsg struct {
Tx *Transaction Tx *types.Transaction
Type TxMsgTy Type TxMsgTy
} }
func EachTx(pool *list.List, it func(*Transaction, *list.Element) bool) { func EachTx(pool *list.List, it func(*types.Transaction, *list.Element) bool) {
for e := pool.Front(); e != nil; e = e.Next() { for e := pool.Front(); e != nil; e = e.Next() {
if it(e.Value.(*Transaction), e) { if it(e.Value.(*types.Transaction), e) {
break break
} }
} }
} }
func FindTx(pool *list.List, finder func(*Transaction, *list.Element) bool) *Transaction { func FindTx(pool *list.List, finder func(*types.Transaction, *list.Element) bool) *types.Transaction {
for e := pool.Front(); e != nil; e = e.Next() { for e := pool.Front(); e != nil; e = e.Next() {
if tx, ok := e.Value.(*Transaction); ok { if tx, ok := e.Value.(*types.Transaction); ok {
if finder(tx, e) { if finder(tx, e) {
return tx return tx
} }
...@@ -51,7 +52,7 @@ func FindTx(pool *list.List, finder func(*Transaction, *list.Element) bool) *Tra ...@@ -51,7 +52,7 @@ func FindTx(pool *list.List, finder func(*Transaction, *list.Element) bool) *Tra
} }
type TxProcessor interface { type TxProcessor interface {
ProcessTransaction(tx *Transaction) ProcessTransaction(tx *types.Transaction)
} }
// The tx pool a thread safe transaction pool handler. In order to // The tx pool a thread safe transaction pool handler. In order to
...@@ -65,7 +66,7 @@ type TxPool struct { ...@@ -65,7 +66,7 @@ type TxPool struct {
mutex sync.Mutex mutex sync.Mutex
// Queueing channel for reading and writing incoming // Queueing channel for reading and writing incoming
// transactions to // transactions to
queueChan chan *Transaction queueChan chan *types.Transaction
// Quiting channel // Quiting channel
quit chan bool quit chan bool
// The actual pool // The actual pool
...@@ -79,14 +80,14 @@ type TxPool struct { ...@@ -79,14 +80,14 @@ type TxPool struct {
func NewTxPool(ethereum EthManager) *TxPool { func NewTxPool(ethereum EthManager) *TxPool {
return &TxPool{ return &TxPool{
pool: list.New(), pool: list.New(),
queueChan: make(chan *Transaction, txPoolQueueSize), queueChan: make(chan *types.Transaction, txPoolQueueSize),
quit: make(chan bool), quit: make(chan bool),
Ethereum: ethereum, Ethereum: ethereum,
} }
} }
// Blocking function. Don't use directly. Use QueueTransaction instead // Blocking function. Don't use directly. Use QueueTransaction instead
func (pool *TxPool) addTransaction(tx *Transaction) { func (pool *TxPool) addTransaction(tx *types.Transaction) {
pool.mutex.Lock() pool.mutex.Lock()
defer pool.mutex.Unlock() defer pool.mutex.Unlock()
...@@ -96,7 +97,7 @@ func (pool *TxPool) addTransaction(tx *Transaction) { ...@@ -96,7 +97,7 @@ func (pool *TxPool) addTransaction(tx *Transaction) {
pool.Ethereum.Broadcast(wire.MsgTxTy, []interface{}{tx.RlpData()}) pool.Ethereum.Broadcast(wire.MsgTxTy, []interface{}{tx.RlpData()})
} }
func (pool *TxPool) ValidateTransaction(tx *Transaction) error { func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
// Get the last block so we can retrieve the sender and receiver from // Get the last block so we can retrieve the sender and receiver from
// the merkle trie // the merkle trie
block := pool.Ethereum.ChainManager().CurrentBlock block := pool.Ethereum.ChainManager().CurrentBlock
...@@ -142,7 +143,7 @@ out: ...@@ -142,7 +143,7 @@ out:
select { select {
case tx := <-pool.queueChan: case tx := <-pool.queueChan:
hash := tx.Hash() hash := tx.Hash()
foundTx := FindTx(pool.pool, func(tx *Transaction, e *list.Element) bool { foundTx := FindTx(pool.pool, func(tx *types.Transaction, e *list.Element) bool {
return bytes.Compare(tx.Hash(), hash) == 0 return bytes.Compare(tx.Hash(), hash) == 0
}) })
...@@ -172,18 +173,18 @@ out: ...@@ -172,18 +173,18 @@ out:
} }
} }
func (pool *TxPool) QueueTransaction(tx *Transaction) { func (pool *TxPool) QueueTransaction(tx *types.Transaction) {
pool.queueChan <- tx pool.queueChan <- tx
} }
func (pool *TxPool) CurrentTransactions() []*Transaction { func (pool *TxPool) CurrentTransactions() []*types.Transaction {
pool.mutex.Lock() pool.mutex.Lock()
defer pool.mutex.Unlock() defer pool.mutex.Unlock()
txList := make([]*Transaction, pool.pool.Len()) txList := make([]*types.Transaction, pool.pool.Len())
i := 0 i := 0
for e := pool.pool.Front(); e != nil; e = e.Next() { for e := pool.pool.Front(); e != nil; e = e.Next() {
tx := e.Value.(*Transaction) tx := e.Value.(*types.Transaction)
txList[i] = tx txList[i] = tx
...@@ -198,7 +199,7 @@ func (pool *TxPool) RemoveInvalid(state *state.State) { ...@@ -198,7 +199,7 @@ func (pool *TxPool) RemoveInvalid(state *state.State) {
defer pool.mutex.Unlock() defer pool.mutex.Unlock()
for e := pool.pool.Front(); e != nil; e = e.Next() { for e := pool.pool.Front(); e != nil; e = e.Next() {
tx := e.Value.(*Transaction) tx := e.Value.(*types.Transaction)
sender := state.GetAccount(tx.Sender()) sender := state.GetAccount(tx.Sender())
err := pool.ValidateTransaction(tx) err := pool.ValidateTransaction(tx)
if err != nil || sender.Nonce >= tx.Nonce { if err != nil || sender.Nonce >= tx.Nonce {
...@@ -207,12 +208,12 @@ func (pool *TxPool) RemoveInvalid(state *state.State) { ...@@ -207,12 +208,12 @@ func (pool *TxPool) RemoveInvalid(state *state.State) {
} }
} }
func (self *TxPool) RemoveSet(txs Transactions) { func (self *TxPool) RemoveSet(txs types.Transactions) {
self.mutex.Lock() self.mutex.Lock()
defer self.mutex.Unlock() defer self.mutex.Unlock()
for _, tx := range txs { for _, tx := range txs {
EachTx(self.pool, func(t *Transaction, element *list.Element) bool { EachTx(self.pool, func(t *types.Transaction, element *list.Element) bool {
if t == tx { if t == tx {
self.pool.Remove(element) self.pool.Remove(element)
return true // To stop the loop return true // To stop the loop
...@@ -222,7 +223,7 @@ func (self *TxPool) RemoveSet(txs Transactions) { ...@@ -222,7 +223,7 @@ func (self *TxPool) RemoveSet(txs Transactions) {
} }
} }
func (pool *TxPool) Flush() []*Transaction { func (pool *TxPool) Flush() []*types.Transaction {
txList := pool.CurrentTransactions() txList := pool.CurrentTransactions()
// Recreate a new list all together // Recreate a new list all together
......
package chain package types
import ( import (
"bytes" "bytes"
...@@ -156,7 +156,7 @@ func (block *Block) State() *state.State { ...@@ -156,7 +156,7 @@ func (block *Block) State() *state.State {
return block.state return block.state
} }
func (block *Block) Transactions() []*Transaction { func (block *Block) Transactions() Transactions {
return block.transactions return block.transactions
} }
......
package chain package types
import ( import (
"math/big" "math/big"
......
package chain package types
/* /*
import ( import (
......
package types
import (
"math/big"
"github.com/ethereum/go-ethereum/state"
)
type BlockProcessor interface {
ProcessWithParent(*Block, *Block) (*big.Int, state.Messages, error)
}
package chain package types
import ( import (
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
......
package chain package types
import ( import (
"bytes" "bytes"
...@@ -16,6 +16,10 @@ type Receipt struct { ...@@ -16,6 +16,10 @@ type Receipt struct {
logs state.Logs logs state.Logs
} }
func NewReceipt(root []byte, cumalativeGasUsed *big.Int) *Receipt {
return &Receipt{PostState: ethutil.CopyBytes(root), CumulativeGasUsed: cumalativeGasUsed}
}
func NewRecieptFromValue(val *ethutil.Value) *Receipt { func NewRecieptFromValue(val *ethutil.Value) *Receipt {
r := &Receipt{} r := &Receipt{}
r.RlpValueDecode(val) r.RlpValueDecode(val)
...@@ -23,6 +27,10 @@ func NewRecieptFromValue(val *ethutil.Value) *Receipt { ...@@ -23,6 +27,10 @@ func NewRecieptFromValue(val *ethutil.Value) *Receipt {
return r return r
} }
func (self *Receipt) SetLogs(logs state.Logs) {
self.logs = logs
}
func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) { func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) {
self.PostState = decoder.Get(0).Bytes() self.PostState = decoder.Get(0).Bytes()
self.CumulativeGasUsed = decoder.Get(1).BigInt() self.CumulativeGasUsed = decoder.Get(1).BigInt()
......
package chain package types
import ( import (
"fmt" "fmt"
......
...@@ -3,17 +3,18 @@ package chain ...@@ -3,17 +3,18 @@ package chain
import ( import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm" "github.com/ethereum/go-ethereum/vm"
) )
type VMEnv struct { type VMEnv struct {
state *state.State state *state.State
block *Block block *types.Block
tx *Transaction tx *types.Transaction
} }
func NewEnv(state *state.State, tx *Transaction, block *Block) *VMEnv { func NewEnv(state *state.State, tx *types.Transaction, block *types.Block) *VMEnv {
return &VMEnv{ return &VMEnv{
state: state, state: state,
block: block, block: block,
......
...@@ -21,8 +21,7 @@ import ( ...@@ -21,8 +21,7 @@ import (
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
...@@ -74,7 +73,7 @@ func main() { ...@@ -74,7 +73,7 @@ func main() {
ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer) ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer)
if Dump { if Dump {
var block *chain.Block var block *types.Block
if len(DumpHash) == 0 && DumpNumber == -1 { if len(DumpHash) == 0 && DumpNumber == -1 {
block = ethereum.ChainManager().CurrentBlock block = ethereum.ChainManager().CurrentBlock
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* @authors * @authors:
* Jeffrey Wilcke <i@jev.io> * Jeffrey Wilcke <i@jev.io>
* @date 2014 * @date 2014
* *
......
...@@ -21,8 +21,7 @@ import ( ...@@ -21,8 +21,7 @@ import (
"encoding/json" "encoding/json"
"os" "os"
"strconv" "strconv"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
...@@ -106,7 +105,7 @@ func (self *Gui) DumpState(hash, path string) { ...@@ -106,7 +105,7 @@ func (self *Gui) DumpState(hash, path string) {
if len(hash) == 0 { if len(hash) == 0 {
stateDump = self.eth.BlockManager().CurrentState().Dump() stateDump = self.eth.BlockManager().CurrentState().Dump()
} else { } else {
var block *chain.Block var block *types.Block
if hash[0] == '#' { if hash[0] == '#' {
i, _ := strconv.Atoi(hash[1:]) i, _ := strconv.Atoi(hash[1:])
block = self.eth.ChainManager().GetBlockByNumber(uint64(i)) block = self.eth.ChainManager().GetBlockByNumber(uint64(i))
......
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"encoding/json" "encoding/json"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/javascript" "github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
...@@ -36,7 +37,7 @@ type AppContainer interface { ...@@ -36,7 +37,7 @@ type AppContainer interface {
Window() *qml.Window Window() *qml.Window
Engine() *qml.Engine Engine() *qml.Engine
NewBlock(*chain.Block) NewBlock(*types.Block)
NewWatcher(chan bool) NewWatcher(chan bool)
Messages(state.Messages, string) Messages(state.Messages, string)
Post(string, int) Post(string, int)
......
...@@ -32,6 +32,7 @@ import ( ...@@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
...@@ -63,6 +64,15 @@ func LoadExtension(path string) (uintptr, error) { ...@@ -63,6 +64,15 @@ func LoadExtension(path string) (uintptr, error) {
return ptr.Interface().(uintptr), nil return ptr.Interface().(uintptr), nil
} }
*/ */
/*
vec, errr := LoadExtension("/Users/jeffrey/Desktop/build-libqmltest-Desktop_Qt_5_2_1_clang_64bit-Debug/liblibqmltest_debug.dylib")
fmt.Printf("Fetched vec with addr: %#x\n", vec)
if errr != nil {
fmt.Println(errr)
} else {
context.SetVar("vec", (unsafe.Pointer)(vec))
}
*/
var guilogger = logger.NewLogger("GUI") var guilogger = logger.NewLogger("GUI")
...@@ -112,9 +122,10 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden ...@@ -112,9 +122,10 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden
} }
func (gui *Gui) Start(assetPath string) { func (gui *Gui) Start(assetPath string) {
defer gui.txDb.Close() defer gui.txDb.Close()
guilogger.Infoln("Starting GUI")
// Register ethereum functions // Register ethereum functions
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
Init: func(p *xeth.JSBlock, obj qml.Object) { p.Number = 0; p.Hash = "" }, Init: func(p *xeth.JSBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
...@@ -132,16 +143,6 @@ func (gui *Gui) Start(assetPath string) { ...@@ -132,16 +143,6 @@ func (gui *Gui) Start(assetPath string) {
context.SetVar("gui", gui) context.SetVar("gui", gui)
context.SetVar("eth", gui.uiLib) context.SetVar("eth", gui.uiLib)
/*
vec, errr := LoadExtension("/Users/jeffrey/Desktop/build-libqmltest-Desktop_Qt_5_2_1_clang_64bit-Debug/liblibqmltest_debug.dylib")
fmt.Printf("Fetched vec with addr: %#x\n", vec)
if errr != nil {
fmt.Println(errr)
} else {
context.SetVar("vec", (unsafe.Pointer)(vec))
}
*/
// Load the main QML interface // Load the main QML interface
data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
...@@ -160,7 +161,6 @@ func (gui *Gui) Start(assetPath string) { ...@@ -160,7 +161,6 @@ func (gui *Gui) Start(assetPath string) {
panic(err) panic(err)
} }
guilogger.Infoln("Starting GUI")
gui.open = true gui.open = true
win.Show() win.Show()
...@@ -245,7 +245,7 @@ func (gui *Gui) CreateAndSetPrivKey() (string, string, string, string) { ...@@ -245,7 +245,7 @@ func (gui *Gui) CreateAndSetPrivKey() (string, string, string, string) {
return gui.eth.KeyManager().KeyPair().AsStrings() return gui.eth.KeyManager().KeyPair().AsStrings()
} }
func (gui *Gui) setInitialChainManager() { func (gui *Gui) setInitialChain(ancientBlocks bool) {
sBlk := gui.eth.ChainManager().LastBlockHash sBlk := gui.eth.ChainManager().LastBlockHash
blk := gui.eth.ChainManager().GetBlock(sBlk) blk := gui.eth.ChainManager().GetBlock(sBlk)
for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) { for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) {
...@@ -255,10 +255,6 @@ func (gui *Gui) setInitialChainManager() { ...@@ -255,10 +255,6 @@ func (gui *Gui) setInitialChainManager() {
} }
} }
type address struct {
Name, Address string
}
func (gui *Gui) loadAddressBook() { func (gui *Gui) loadAddressBook() {
view := gui.getObjectByName("infoView") view := gui.getObjectByName("infoView")
nameReg := gui.pipe.World().Config().Get("NameReg") nameReg := gui.pipe.World().Config().Get("NameReg")
...@@ -295,7 +291,7 @@ func (self *Gui) loadMergedMiningOptions() { ...@@ -295,7 +291,7 @@ func (self *Gui) loadMergedMiningOptions() {
} }
} }
func (gui *Gui) insertTransaction(window string, tx *chain.Transaction) { func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
pipe := xeth.New(gui.eth) pipe := xeth.New(gui.eth)
nameReg := pipe.World().Config().Get("NameReg") nameReg := pipe.World().Config().Get("NameReg")
addr := gui.address() addr := gui.address()
...@@ -345,7 +341,7 @@ func (gui *Gui) insertTransaction(window string, tx *chain.Transaction) { ...@@ -345,7 +341,7 @@ func (gui *Gui) insertTransaction(window string, tx *chain.Transaction) {
func (gui *Gui) readPreviousTransactions() { func (gui *Gui) readPreviousTransactions() {
it := gui.txDb.NewIterator() it := gui.txDb.NewIterator()
for it.Next() { for it.Next() {
tx := chain.NewTransactionFromBytes(it.Value()) tx := types.NewTransactionFromBytes(it.Value())
gui.insertTransaction("post", tx) gui.insertTransaction("post", tx)
...@@ -353,7 +349,7 @@ func (gui *Gui) readPreviousTransactions() { ...@@ -353,7 +349,7 @@ func (gui *Gui) readPreviousTransactions() {
it.Release() it.Release()
} }
func (gui *Gui) processBlock(block *chain.Block, initial bool) { func (gui *Gui) processBlock(block *types.Block, initial bool) {
name := strings.Trim(gui.pipe.World().Config().Get("NameReg").Storage(block.Coinbase).Str(), "\x00") name := strings.Trim(gui.pipe.World().Config().Get("NameReg").Storage(block.Coinbase).Str(), "\x00")
b := xeth.NewJSBlock(block) b := xeth.NewJSBlock(block)
b.Name = name b.Name = name
...@@ -385,11 +381,11 @@ func (self *Gui) getObjectByName(objectName string) qml.Object { ...@@ -385,11 +381,11 @@ func (self *Gui) getObjectByName(objectName string) qml.Object {
func (gui *Gui) update() { func (gui *Gui) update() {
// We have to wait for qml to be done loading all the windows. // We have to wait for qml to be done loading all the windows.
for !gui.qmlDone { for !gui.qmlDone {
time.Sleep(500 * time.Millisecond) time.Sleep(300 * time.Millisecond)
} }
go func() { go func() {
go gui.setInitialChainManager() go gui.setInitialChain(false)
gui.loadAddressBook() gui.loadAddressBook()
gui.loadMergedMiningOptions() gui.loadMergedMiningOptions()
gui.setPeerInfo() gui.setPeerInfo()
...@@ -493,14 +489,7 @@ func (gui *Gui) update() { ...@@ -493,14 +489,7 @@ func (gui *Gui) update() {
case <-generalUpdateTicker.C: case <-generalUpdateTicker.C:
statusText := "#" + gui.eth.ChainManager().CurrentBlock.Number.String() statusText := "#" + gui.eth.ChainManager().CurrentBlock.Number.String()
lastBlockLabel.Set("text", statusText) lastBlockLabel.Set("text", statusText)
miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash") miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash")
/*
if gui.miner != nil {
pow := gui.miner.GetPow()
miningLabel.Set("text", "Mining @ "+strconv.FormatInt(pow.GetHashrate(), 10)+"Khash")
}
*/
blockLength := gui.eth.BlockPool().BlocksProcessed blockLength := gui.eth.BlockPool().BlocksProcessed
chainLength := gui.eth.BlockPool().ChainLength chainLength := gui.eth.BlockPool().ChainLength
...@@ -510,7 +499,6 @@ func (gui *Gui) update() { ...@@ -510,7 +499,6 @@ func (gui *Gui) update() {
dlWidget = gui.win.Root().ObjectByName("downloadIndicator") dlWidget = gui.win.Root().ObjectByName("downloadIndicator")
dlLabel = gui.win.Root().ObjectByName("downloadLabel") dlLabel = gui.win.Root().ObjectByName("downloadLabel")
) )
dlWidget.Set("value", pct) dlWidget.Set("value", pct)
dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength)) dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength))
...@@ -549,7 +537,6 @@ NumGC: %d ...@@ -549,7 +537,6 @@ NumGC: %d
func (gui *Gui) setPeerInfo() { func (gui *Gui) setPeerInfo() {
gui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", gui.eth.PeerCount(), gui.eth.MaxPeers)) gui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", gui.eth.PeerCount(), gui.eth.MaxPeers))
gui.win.Root().Call("resetPeers") gui.win.Root().Call("resetPeers")
for _, peer := range gui.pipe.Peers() { for _, peer := range gui.pipe.Peers() {
gui.win.Root().Call("addPeer", peer) gui.win.Root().Call("addPeer", peer)
......
...@@ -26,8 +26,7 @@ import ( ...@@ -26,8 +26,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/javascript" "github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
...@@ -138,7 +137,7 @@ func (app *HtmlApplication) Window() *qml.Window { ...@@ -138,7 +137,7 @@ func (app *HtmlApplication) Window() *qml.Window {
return app.win return app.win
} }
func (app *HtmlApplication) NewBlock(block *chain.Block) { func (app *HtmlApplication) NewBlock(block *types.Block) {
b := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} b := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())}
app.webView.Call("onNewBlockCb", b) app.webView.Call("onNewBlockCb", b)
} }
......
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
package main package main
import ( import (
"fmt"
"os" "os"
"runtime" "runtime"
"time"
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
...@@ -38,6 +40,7 @@ func run() error { ...@@ -38,6 +40,7 @@ func run() error {
// precedence: code-internal flag default < config file < environment variables < command line // precedence: code-internal flag default < config file < environment variables < command line
Init() // parsing command line Init() // parsing command line
tstart := time.Now()
config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
utils.InitDataDir(Datadir) utils.InitDataDir(Datadir)
...@@ -51,14 +54,11 @@ func run() error { ...@@ -51,14 +54,11 @@ func run() error {
os.Exit(1) os.Exit(1)
} }
keyManager := utils.NewKeyManager(KeyStore, Datadir, db) keyManager := utils.NewKeyManager(KeyStore, Datadir, db)
// create, import, export keys // create, import, export keys
utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive) utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier) clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier)
ethereum = utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer) ethereum = utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer)
if ShowGenesis { if ShowGenesis {
...@@ -75,7 +75,10 @@ func run() error { ...@@ -75,7 +75,10 @@ func run() error {
utils.RegisterInterrupt(func(os.Signal) { utils.RegisterInterrupt(func(os.Signal) {
gui.Stop() gui.Stop()
}) })
utils.StartEthereum(ethereum, UseSeed) go utils.StartEthereum(ethereum, UseSeed)
fmt.Println("ETH stack took", time.Since(tstart))
// gui blocks the main thread // gui blocks the main thread
gui.Start(AssetPath) gui.Start(AssetPath)
......
...@@ -20,8 +20,7 @@ package main ...@@ -20,8 +20,7 @@ package main
import ( import (
"fmt" "fmt"
"runtime" "runtime"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth" "github.com/ethereum/go-ethereum/xeth"
...@@ -65,7 +64,7 @@ func (app *QmlApplication) NewWatcher(quitChan chan bool) { ...@@ -65,7 +64,7 @@ func (app *QmlApplication) NewWatcher(quitChan chan bool) {
} }
// Events // Events
func (app *QmlApplication) NewBlock(block *chain.Block) { func (app *QmlApplication) NewBlock(block *types.Block) {
pblock := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} pblock := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())}
app.win.Call("onNewBlockCb", pblock) app.win.Call("onNewBlockCb", pblock)
} }
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/javascript" "github.com/ethereum/go-ethereum/javascript"
...@@ -126,7 +127,7 @@ func (self *UiLib) PastPeers() *ethutil.List { ...@@ -126,7 +127,7 @@ func (self *UiLib) PastPeers() *ethutil.List {
} }
func (self *UiLib) ImportTx(rlpTx string) { func (self *UiLib) ImportTx(rlpTx string) {
tx := chain.NewTransactionFromBytes(ethutil.Hex2Bytes(rlpTx)) tx := types.NewTransactionFromBytes(ethutil.Hex2Bytes(rlpTx))
self.eth.TxPool().QueueTransaction(tx) self.eth.TxPool().QueueTransaction(tx)
} }
...@@ -228,7 +229,7 @@ func (self *UiLib) NewFilter(object map[string]interface{}) (id int) { ...@@ -228,7 +229,7 @@ func (self *UiLib) NewFilter(object map[string]interface{}) (id int) {
func (self *UiLib) NewFilterString(typ string) (id int) { func (self *UiLib) NewFilterString(typ string) (id int) {
filter := chain.NewFilter(self.eth) filter := chain.NewFilter(self.eth)
filter.BlockCallback = func(block *chain.Block) { filter.BlockCallback = func(block *types.Block) {
if self.win != nil && self.win.Root() != nil { if self.win != nil && self.win.Root() != nil {
self.win.Root().Call("invokeFilterCallback", "{}", id) self.win.Root().Call("invokeFilterCallback", "{}", id)
} else { } else {
......
...@@ -2,21 +2,20 @@ package utils ...@@ -2,21 +2,20 @@ package utils
import ( import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm" "github.com/ethereum/go-ethereum/vm"
) )
type VMEnv struct { type VMEnv struct {
state *state.State state *state.State
block *chain.Block block *types.Block
transactor []byte transactor []byte
value *big.Int value *big.Int
} }
func NewEnv(state *state.State, block *chain.Block, transactor []byte, value *big.Int) *VMEnv { func NewEnv(state *state.State, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
return &VMEnv{ return &VMEnv{
state: state, state: state,
block: block, block: block,
......
...@@ -23,6 +23,10 @@ func (db *MemDatabase) Put(key []byte, value []byte) { ...@@ -23,6 +23,10 @@ func (db *MemDatabase) Put(key []byte, value []byte) {
db.db[string(key)] = value db.db[string(key)] = value
} }
func (db *MemDatabase) Set(key []byte, value []byte) {
db.Put(key, value)
}
func (db *MemDatabase) Get(key []byte) ([]byte, error) { func (db *MemDatabase) Get(key []byte) ([]byte, error) {
return db.db[string(key)], nil return db.db[string(key)], nil
} }
......
...@@ -129,8 +129,9 @@ func New(db ethutil.Database, clientIdentity wire.ClientIdentity, keyManager *cr ...@@ -129,8 +129,9 @@ func New(db ethutil.Database, clientIdentity wire.ClientIdentity, keyManager *cr
ethereum.blockPool = NewBlockPool(ethereum) ethereum.blockPool = NewBlockPool(ethereum)
ethereum.txPool = chain.NewTxPool(ethereum) ethereum.txPool = chain.NewTxPool(ethereum)
ethereum.blockChain = chain.NewChainManager(ethereum) ethereum.blockChain = chain.NewChainManager()
ethereum.blockManager = chain.NewBlockManager(ethereum) ethereum.blockManager = chain.NewBlockManager(ethereum)
ethereum.blockChain.SetProcessor(ethereum.blockManager)
// Start the tx pool // Start the tx pool
ethereum.txPool.Start() ethereum.txPool.Start()
......
mode: count
github.com/ethereum/go-ethereum/event/event.go:41.66,45.17 4 1005
github.com/ethereum/go-ethereum/event/event.go:63.2,63.12 1 1004
github.com/ethereum/go-ethereum/event/event.go:45.17,47.3 1 1
github.com/ethereum/go-ethereum/event/event.go:47.3,48.22 1 1004
github.com/ethereum/go-ethereum/event/event.go:51.3,51.27 1 1004
github.com/ethereum/go-ethereum/event/event.go:48.22,50.4 1 5
github.com/ethereum/go-ethereum/event/event.go:51.27,54.32 3 1006
github.com/ethereum/go-ethereum/event/event.go:57.4,60.25 4 1005
github.com/ethereum/go-ethereum/event/event.go:54.32,56.5 1 1
github.com/ethereum/go-ethereum/event/event.go:68.48,71.17 3 3513
github.com/ethereum/go-ethereum/event/event.go:75.2,77.27 3 3511
github.com/ethereum/go-ethereum/event/event.go:80.2,80.12 1 3509
github.com/ethereum/go-ethereum/event/event.go:71.17,74.3 2 2
github.com/ethereum/go-ethereum/event/event.go:77.27,79.3 1 2576
github.com/ethereum/go-ethereum/event/event.go:86.28,88.32 2 5
github.com/ethereum/go-ethereum/event/event.go:93.2,95.20 3 5
github.com/ethereum/go-ethereum/event/event.go:88.32,89.28 1 3
github.com/ethereum/go-ethereum/event/event.go:89.28,91.4 1 3
github.com/ethereum/go-ethereum/event/event.go:98.36,100.34 2 1001
github.com/ethereum/go-ethereum/event/event.go:109.2,109.22 1 1001
github.com/ethereum/go-ethereum/event/event.go:100.34,101.37 1 1001
github.com/ethereum/go-ethereum/event/event.go:101.37,102.22 1 1001
github.com/ethereum/go-ethereum/event/event.go:102.22,104.5 1 2
github.com/ethereum/go-ethereum/event/event.go:104.5,106.5 1 999
github.com/ethereum/go-ethereum/event/event.go:112.46,113.26 1 2007
github.com/ethereum/go-ethereum/event/event.go:118.2,118.11 1 1005
github.com/ethereum/go-ethereum/event/event.go:113.26,114.16 1 181499
github.com/ethereum/go-ethereum/event/event.go:114.16,116.4 1 1002
github.com/ethereum/go-ethereum/event/event.go:121.52,126.2 4 999
github.com/ethereum/go-ethereum/event/event.go:142.35,150.2 2 1005
github.com/ethereum/go-ethereum/event/event.go:152.44,154.2 1 1003
github.com/ethereum/go-ethereum/event/event.go:156.32,159.2 2 1001
github.com/ethereum/go-ethereum/event/event.go:161.30,164.14 3 1004
github.com/ethereum/go-ethereum/event/event.go:167.2,173.19 6 1003
github.com/ethereum/go-ethereum/event/event.go:164.14,166.3 1 1
github.com/ethereum/go-ethereum/event/event.go:176.42,178.9 2 2575
github.com/ethereum/go-ethereum/event/event.go:182.2,182.20 1 2575
github.com/ethereum/go-ethereum/event/event.go:179.2,179.21 0 1004
github.com/ethereum/go-ethereum/event/event.go:180.2,180.19 0 1571
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
...@@ -130,7 +131,7 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value { ...@@ -130,7 +131,7 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
var state *state.State var state *state.State
if len(call.ArgumentList) > 0 { if len(call.ArgumentList) > 0 {
var block *chain.Block var block *types.Block
if call.Argument(0).IsNumber() { if call.Argument(0).IsNumber() {
num, _ := call.Argument(0).ToInteger() num, _ := call.Argument(0).ToInteger()
block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num)) block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num))
......
...@@ -29,8 +29,10 @@ import ( ...@@ -29,8 +29,10 @@ import (
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/wire" "github.com/ethereum/go-ethereum/wire"
...@@ -44,7 +46,7 @@ type LocalTx struct { ...@@ -44,7 +46,7 @@ type LocalTx struct {
Value string `json:"value"` Value string `json:"value"`
} }
func (self *LocalTx) Sign(key []byte) *chain.Transaction { func (self *LocalTx) Sign(key []byte) *types.Transaction {
return nil return nil
} }
...@@ -54,7 +56,7 @@ type Miner struct { ...@@ -54,7 +56,7 @@ type Miner struct {
eth *eth.Ethereum eth *eth.Ethereum
events event.Subscription events event.Subscription
uncles chain.Blocks uncles types.Blocks
localTxs map[int]*LocalTx localTxs map[int]*LocalTx
localTxId int localTxId int
...@@ -212,13 +214,15 @@ func (self *Miner) mine() { ...@@ -212,13 +214,15 @@ func (self *Miner) mine() {
nonce := self.pow.Search(block, self.powQuitCh) nonce := self.pow.Search(block, self.powQuitCh)
if nonce != nil { if nonce != nil {
block.Nonce = nonce block.Nonce = nonce
lchain := chain.NewChain(chain.Blocks{block}) lchain := chain.NewChain(types.Blocks{block})
_, err := chainMan.TestChain(lchain) _, err := chainMan.TestChain(lchain)
if err != nil { if err != nil {
minerlogger.Infoln(err) minerlogger.Infoln(err)
} else { } else {
chainMan.InsertChain(lchain) chainMan.InsertChain(lchain, func(block *types.Block, _ state.Messages) {
//self.eth.EventMux().Post(chain.NewBlockEvent{block}) self.eth.EventMux().Post(chain.NewBlockEvent{block})
})
self.eth.Broadcast(wire.MsgBlockTy, []interface{}{block.Value().Val}) self.eth.Broadcast(wire.MsgBlockTy, []interface{}{block.Value().Val})
minerlogger.Infof("🔨 Mined block %x\n", block.Hash()) minerlogger.Infof("🔨 Mined block %x\n", block.Hash())
...@@ -229,15 +233,15 @@ func (self *Miner) mine() { ...@@ -229,15 +233,15 @@ func (self *Miner) mine() {
} }
} }
func (self *Miner) finiliseTxs() chain.Transactions { func (self *Miner) finiliseTxs() types.Transactions {
// Sort the transactions by nonce in case of odd network propagation // Sort the transactions by nonce in case of odd network propagation
var txs chain.Transactions var txs types.Transactions
state := self.eth.BlockManager().TransState() state := self.eth.BlockManager().TransState()
// XXX This has to change. Coinbase is, for new, same as key. // XXX This has to change. Coinbase is, for new, same as key.
key := self.eth.KeyManager() key := self.eth.KeyManager()
for _, ltx := range self.localTxs { for _, ltx := range self.localTxs {
tx := chain.NewTransactionMessage(ltx.To, ethutil.Big(ltx.Value), ethutil.Big(ltx.Gas), ethutil.Big(ltx.GasPrice), ltx.Data) tx := types.NewTransactionMessage(ltx.To, ethutil.Big(ltx.Value), ethutil.Big(ltx.Gas), ethutil.Big(ltx.GasPrice), ltx.Data)
tx.Nonce = state.GetNonce(self.Coinbase) tx.Nonce = state.GetNonce(self.Coinbase)
state.SetNonce(self.Coinbase, tx.Nonce+1) state.SetNonce(self.Coinbase, tx.Nonce+1)
...@@ -247,7 +251,7 @@ func (self *Miner) finiliseTxs() chain.Transactions { ...@@ -247,7 +251,7 @@ func (self *Miner) finiliseTxs() chain.Transactions {
} }
txs = append(txs, self.eth.TxPool().CurrentTransactions()...) txs = append(txs, self.eth.TxPool().CurrentTransactions()...)
sort.Sort(chain.TxByNonce{txs}) sort.Sort(types.TxByNonce{txs})
return txs return txs
} }
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/wire" "github.com/ethereum/go-ethereum/wire"
...@@ -24,7 +24,7 @@ const ( ...@@ -24,7 +24,7 @@ const (
// The size of the output buffer for writing messages // The size of the output buffer for writing messages
outputBufferSize = 50 outputBufferSize = 50
// Current protocol version // Current protocol version
ProtocolVersion = 42 ProtocolVersion = 43
// Current P2P version // Current P2P version
P2PVersion = 2 P2PVersion = 2
// Ethereum network version // Ethereum network version
...@@ -155,7 +155,7 @@ type Peer struct { ...@@ -155,7 +155,7 @@ type Peer struct {
pingTime time.Duration pingTime time.Duration
pingStartTime time.Time pingStartTime time.Time
lastRequestedBlock *chain.Block lastRequestedBlock *types.Block
protocolCaps *ethutil.Value protocolCaps *ethutil.Value
} }
...@@ -429,7 +429,7 @@ func (p *Peer) HandleInbound() { ...@@ -429,7 +429,7 @@ func (p *Peer) HandleInbound() {
// in the TxPool where it will undergo validation and // in the TxPool where it will undergo validation and
// processing when a new block is found // processing when a new block is found
for i := 0; i < msg.Data.Len(); i++ { for i := 0; i < msg.Data.Len(); i++ {
tx := chain.NewTransactionFromValue(msg.Data.Get(i)) tx := types.NewTransactionFromValue(msg.Data.Get(i))
p.ethereum.TxPool().QueueTransaction(tx) p.ethereum.TxPool().QueueTransaction(tx)
} }
case wire.MsgGetPeersTy: case wire.MsgGetPeersTy:
...@@ -535,7 +535,7 @@ func (p *Peer) HandleInbound() { ...@@ -535,7 +535,7 @@ func (p *Peer) HandleInbound() {
it := msg.Data.NewIterator() it := msg.Data.NewIterator()
for it.Next() { for it.Next() {
block := chain.NewBlockFromRlpValue(it.Value()) block := types.NewBlockFromRlpValue(it.Value())
blockPool.Add(block, p) blockPool.Add(block, p)
p.lastBlockReceived = time.Now() p.lastBlockReceived = time.Now()
...@@ -543,7 +543,7 @@ func (p *Peer) HandleInbound() { ...@@ -543,7 +543,7 @@ func (p *Peer) HandleInbound() {
case wire.MsgNewBlockTy: case wire.MsgNewBlockTy:
var ( var (
blockPool = p.ethereum.blockPool blockPool = p.ethereum.blockPool
block = chain.NewBlockFromRlpValue(msg.Data.Get(0)) block = types.NewBlockFromRlpValue(msg.Data.Get(0))
td = msg.Data.Get(1).BigInt() td = msg.Data.Get(1).BigInt()
) )
......
This diff is collapsed.
package ptrie
type Backend interface {
Get([]byte) ([]byte, error)
Put([]byte, []byte)
}
type Cache struct {
store map[string][]byte
backend Backend
}
func NewCache(backend Backend) *Cache {
return &Cache{make(map[string][]byte), backend}
}
func (self *Cache) Get(key []byte) []byte {
data := self.store[string(key)]
if data == nil {
data, _ = self.backend.Get(key)
}
return data
}
func (self *Cache) Put(key []byte, data []byte) {
self.store[string(key)] = data
}
func (self *Cache) Flush() {
for k, v := range self.store {
self.backend.Put([]byte(k), v)
}
// This will eventually grow too large. We'd could
// do a make limit on storage and push out not-so-popular nodes.
//self.Reset()
}
func (self *Cache) Reset() {
self.store = make(map[string][]byte)
}
package ptrie
type FullNode struct {
trie *Trie
nodes [17]Node
}
func NewFullNode(t *Trie) *FullNode {
return &FullNode{trie: t}
}
func (self *FullNode) Dirty() bool { return true }
func (self *FullNode) Value() Node {
self.nodes[16] = self.trie.trans(self.nodes[16])
return self.nodes[16]
}
func (self *FullNode) Branches() []Node {
return self.nodes[:16]
}
func (self *FullNode) Copy() Node {
nnode := NewFullNode(self.trie)
for i, node := range self.nodes {
nnode.nodes[i] = node
}
return nnode
}
// Returns the length of non-nil nodes
func (self *FullNode) Len() (amount int) {
for _, node := range self.nodes {
if node != nil {
amount++
}
}
return
}
func (self *FullNode) Hash() interface{} {
return self.trie.store(self)
}
func (self *FullNode) RlpData() interface{} {
t := make([]interface{}, 17)
for i, node := range self.nodes {
if node != nil {
t[i] = node.Hash()
} else {
t[i] = ""
}
}
return t
}
func (self *FullNode) set(k byte, value Node) {
self.nodes[int(k)] = value
}
func (self *FullNode) branch(i byte) Node {
if self.nodes[int(i)] != nil {
self.nodes[int(i)] = self.trie.trans(self.nodes[int(i)])
return self.nodes[int(i)]
}
return nil
}
package ptrie
type HashNode struct {
key []byte
}
func NewHash(key []byte) *HashNode {
return &HashNode{key}
}
func (self *HashNode) RlpData() interface{} {
return self.key
}
func (self *HashNode) Hash() interface{} {
return self.key
}
// These methods will never be called but we have to satisfy Node interface
func (self *HashNode) Value() Node { return nil }
func (self *HashNode) Dirty() bool { return true }
func (self *HashNode) Copy() Node { return self }
package ptrie
import (
"bytes"
"github.com/ethereum/go-ethereum/trie"
)
type Iterator struct {
trie *Trie
Key []byte
Value []byte
}
func NewIterator(trie *Trie) *Iterator {
return &Iterator{trie: trie, Key: []byte{0}}
}
func (self *Iterator) Next() bool {
self.trie.mu.Lock()
defer self.trie.mu.Unlock()
key := trie.RemTerm(trie.CompactHexDecode(string(self.Key)))
k := self.next(self.trie.root, key)
self.Key = []byte(trie.DecodeCompact(k))
return len(k) > 0
}
func (self *Iterator) next(node Node, key []byte) []byte {
if node == nil {
return nil
}
switch node := node.(type) {
case *FullNode:
if len(key) > 0 {
k := self.next(node.branch(key[0]), key[1:])
if k != nil {
return append([]byte{key[0]}, k...)
}
}
var r byte
if len(key) > 0 {
r = key[0] + 1
}
for i := r; i < 16; i++ {
k := self.key(node.branch(byte(i)))
if k != nil {
return append([]byte{i}, k...)
}
}
case *ShortNode:
k := trie.RemTerm(node.Key())
if vnode, ok := node.Value().(*ValueNode); ok {
if bytes.Compare([]byte(k), key) > 0 {
self.Value = vnode.Val()
return k
}
} else {
cnode := node.Value()
var ret []byte
skey := key[len(k):]
if trie.BeginsWith(key, k) {
ret = self.next(cnode, skey)
} else if bytes.Compare(k, key[:len(k)]) > 0 {
ret = self.key(node)
}
if ret != nil {
return append(k, ret...)
}
}
}
return nil
}
func (self *Iterator) key(node Node) []byte {
switch node := node.(type) {
case *ShortNode:
// Leaf node
if vnode, ok := node.Value().(*ValueNode); ok {
k := trie.RemTerm(node.Key())
self.Value = vnode.Val()
return k
} else {
k := trie.RemTerm(node.Key())
return append(k, self.key(node.Value())...)
}
case *FullNode:
if node.Value() != nil {
self.Value = node.Value().(*ValueNode).Val()
return []byte{16}
}
for i := 0; i < 16; i++ {
k := self.key(node.branch(byte(i)))
if k != nil {
return append([]byte{byte(i)}, k...)
}
}
}
return nil
}
package ptrie
import "testing"
func TestIterator(t *testing.T) {
trie := NewEmpty()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"dog", "puppy"},
{"somethingveryoddindeedthis is", "myothernodedata"},
}
v := make(map[string]bool)
for _, val := range vals {
v[val.k] = false
trie.UpdateString(val.k, val.v)
}
trie.Commit()
it := trie.Iterator()
for it.Next() {
v[string(it.Key)] = true
}
for k, found := range v {
if !found {
t.Error("iterator didn't find", k)
}
}
}
package ptrie
import "fmt"
var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"}
type Node interface {
Value() Node
Copy() Node // All nodes, for now, return them self
Dirty() bool
fstring(string) string
Hash() interface{}
RlpData() interface{}
}
// Value node
func (self *ValueNode) String() string { return self.fstring("") }
func (self *FullNode) String() string { return self.fstring("") }
func (self *ShortNode) String() string { return self.fstring("") }
func (self *ValueNode) fstring(ind string) string { return fmt.Sprintf("%s ", self.data) }
func (self *HashNode) fstring(ind string) string { return fmt.Sprintf("%x ", self.key) }
// Full node
func (self *FullNode) fstring(ind string) string {
resp := fmt.Sprintf("[\n%s ", ind)
for i, node := range self.nodes {
if node == nil {
resp += fmt.Sprintf("%s: <nil> ", indices[i])
} else {
resp += fmt.Sprintf("%s: %v", indices[i], node.fstring(ind+" "))
}
}
return resp + fmt.Sprintf("\n%s] ", ind)
}
// Short node
func (self *ShortNode) fstring(ind string) string {
return fmt.Sprintf("[ %s: %v ] ", self.key, self.value.fstring(ind+" "))
}
package ptrie
import "github.com/ethereum/go-ethereum/trie"
type ShortNode struct {
trie *Trie
key []byte
value Node
}
func NewShortNode(t *Trie, key []byte, value Node) *ShortNode {
return &ShortNode{t, []byte(trie.CompactEncode(key)), value}
}
func (self *ShortNode) Value() Node {
self.value = self.trie.trans(self.value)
return self.value
}
func (self *ShortNode) Dirty() bool { return true }
func (self *ShortNode) Copy() Node { return NewShortNode(self.trie, self.key, self.value) }
func (self *ShortNode) RlpData() interface{} {
return []interface{}{self.key, self.value.Hash()}
}
func (self *ShortNode) Hash() interface{} {
return self.trie.store(self)
}
func (self *ShortNode) Key() []byte {
return trie.CompactDecode(string(self.key))
}
package ptrie
import (
"bytes"
"container/list"
"fmt"
"sync"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/trie"
)
func ParanoiaCheck(t1 *Trie, backend Backend) (bool, *Trie) {
t2 := New(nil, backend)
it := t1.Iterator()
for it.Next() {
t2.Update(it.Key, it.Value)
}
return bytes.Compare(t2.Hash(), t1.Hash()) == 0, t2
}
type Trie struct {
mu sync.Mutex
root Node
roothash []byte
cache *Cache
revisions *list.List
}
func New(root []byte, backend Backend) *Trie {
trie := &Trie{}
trie.revisions = list.New()
trie.roothash = root
trie.cache = NewCache(backend)
if root != nil {
value := ethutil.NewValueFromBytes(trie.cache.Get(root))
trie.root = trie.mknode(value)
}
return trie
}
func (self *Trie) Iterator() *Iterator {
return NewIterator(self)
}
// Legacy support
func (self *Trie) Root() []byte { return self.Hash() }
func (self *Trie) Hash() []byte {
var hash []byte
if self.root != nil {
//hash = self.root.Hash().([]byte)
t := self.root.Hash()
if byts, ok := t.([]byte); ok {
hash = byts
} else {
hash = crypto.Sha3(ethutil.Encode(self.root.RlpData()))
}
} else {
hash = crypto.Sha3(ethutil.Encode(""))
}
if !bytes.Equal(hash, self.roothash) {
self.revisions.PushBack(self.roothash)
self.roothash = hash
}
return hash
}
func (self *Trie) Commit() {
// Hash first
self.Hash()
self.cache.Flush()
}
// Reset should only be called if the trie has been hashed
func (self *Trie) Reset() {
self.cache.Reset()
revision := self.revisions.Remove(self.revisions.Back()).([]byte)
self.roothash = revision
value := ethutil.NewValueFromBytes(self.cache.Get(self.roothash))
self.root = self.mknode(value)
}
func (self *Trie) UpdateString(key, value string) Node { return self.Update([]byte(key), []byte(value)) }
func (self *Trie) Update(key, value []byte) Node {
self.mu.Lock()
defer self.mu.Unlock()
k := trie.CompactHexDecode(string(key))
if len(value) != 0 {
self.root = self.insert(self.root, k, &ValueNode{self, value})
} else {
self.root = self.delete(self.root, k)
}
return self.root
}
func (self *Trie) GetString(key string) []byte { return self.Get([]byte(key)) }
func (self *Trie) Get(key []byte) []byte {
self.mu.Lock()
defer self.mu.Unlock()
k := trie.CompactHexDecode(string(key))
n := self.get(self.root, k)
if n != nil {
return n.(*ValueNode).Val()
}
return nil
}
func (self *Trie) DeleteString(key string) Node { return self.Delete([]byte(key)) }
func (self *Trie) Delete(key []byte) Node {
self.mu.Lock()
defer self.mu.Unlock()
k := trie.CompactHexDecode(string(key))
self.root = self.delete(self.root, k)
return self.root
}
func (self *Trie) insert(node Node, key []byte, value Node) Node {
if len(key) == 0 {
return value
}
if node == nil {
return NewShortNode(self, key, value)
}
switch node := node.(type) {
case *ShortNode:
k := node.Key()
cnode := node.Value()
if bytes.Equal(k, key) {
return NewShortNode(self, key, value)
}
var n Node
matchlength := trie.MatchingNibbleLength(key, k)
if matchlength == len(k) {
n = self.insert(cnode, key[matchlength:], value)
} else {
pnode := self.insert(nil, k[matchlength+1:], cnode)
nnode := self.insert(nil, key[matchlength+1:], value)
fulln := NewFullNode(self)
fulln.set(k[matchlength], pnode)
fulln.set(key[matchlength], nnode)
n = fulln
}
if matchlength == 0 {
return n
}
return NewShortNode(self, key[:matchlength], n)
case *FullNode:
cpy := node.Copy().(*FullNode)
cpy.set(key[0], self.insert(node.branch(key[0]), key[1:], value))
return cpy
default:
panic("Invalid node")
}
}
func (self *Trie) get(node Node, key []byte) Node {
if len(key) == 0 {
return node
}
if node == nil {
return nil
}
switch node := node.(type) {
case *ShortNode:
k := node.Key()
cnode := node.Value()
if len(key) >= len(k) && bytes.Equal(k, key[:len(k)]) {
return self.get(cnode, key[len(k):])
}
return nil
case *FullNode:
return self.get(node.branch(key[0]), key[1:])
default:
panic(fmt.Sprintf("%T: invalid node: %v", node, node))
}
}
func (self *Trie) delete(node Node, key []byte) Node {
if len(key) == 0 {
return nil
}
switch node := node.(type) {
case *ShortNode:
k := node.Key()
cnode := node.Value()
if bytes.Equal(key, k) {
return nil
} else if bytes.Equal(key[:len(k)], k) {
child := self.delete(cnode, key[len(k):])
var n Node
switch child := child.(type) {
case *ShortNode:
nkey := append(k, child.Key()...)
n = NewShortNode(self, nkey, child.Value())
case *FullNode:
n = NewShortNode(self, node.key, child)
}
return n
} else {
return node
}
case *FullNode:
n := node.Copy().(*FullNode)
n.set(key[0], self.delete(n.branch(key[0]), key[1:]))
pos := -1
for i := 0; i < 17; i++ {
if n.branch(byte(i)) != nil {
if pos == -1 {
pos = i
} else {
pos = -2
}
}
}
var nnode Node
if pos == 16 {
nnode = NewShortNode(self, []byte{16}, n.branch(byte(pos)))
} else if pos >= 0 {
cnode := n.branch(byte(pos))
switch cnode := cnode.(type) {
case *ShortNode:
// Stitch keys
k := append([]byte{byte(pos)}, cnode.Key()...)
nnode = NewShortNode(self, k, cnode.Value())
case *FullNode:
nnode = NewShortNode(self, []byte{byte(pos)}, n.branch(byte(pos)))
}
} else {
nnode = n
}
return nnode
default:
panic("Invalid node")
}
}
// casting functions and cache storing
func (self *Trie) mknode(value *ethutil.Value) Node {
l := value.Len()
switch l {
case 2:
return NewShortNode(self, trie.CompactDecode(string(value.Get(0).Bytes())), self.mknode(value.Get(1)))
case 17:
fnode := NewFullNode(self)
for i := 0; i < l; i++ {
fnode.set(byte(i), self.mknode(value.Get(i)))
}
return fnode
case 32:
return &HashNode{value.Bytes()}
default:
return &ValueNode{self, value.Bytes()}
}
}
func (self *Trie) trans(node Node) Node {
switch node := node.(type) {
case *HashNode:
value := ethutil.NewValueFromBytes(self.cache.Get(node.key))
return self.mknode(value)
default:
return node
}
}
func (self *Trie) store(node Node) interface{} {
data := ethutil.Encode(node)
if len(data) >= 32 {
key := crypto.Sha3(data)
self.cache.Put(key, data)
return key
}
return node.RlpData()
}
package ptrie
import (
"bytes"
"fmt"
"testing"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
)
type Db map[string][]byte
func (self Db) Get(k []byte) ([]byte, error) { return self[string(k)], nil }
func (self Db) Put(k, v []byte) { self[string(k)] = v }
// Used for testing
func NewEmpty() *Trie {
return New(nil, make(Db))
}
func TestEmptyTrie(t *testing.T) {
trie := NewEmpty()
res := trie.Hash()
exp := crypto.Sha3(ethutil.Encode(""))
if !bytes.Equal(res, exp) {
t.Errorf("expected %x got %x", exp, res)
}
}
func TestInsert(t *testing.T) {
trie := NewEmpty()
trie.UpdateString("doe", "reindeer")
trie.UpdateString("dog", "puppy")
trie.UpdateString("dogglesworth", "cat")
exp := ethutil.Hex2Bytes("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3")
root := trie.Hash()
if !bytes.Equal(root, exp) {
t.Errorf("exp %x got %x", exp, root)
}
trie = NewEmpty()
trie.UpdateString("A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
exp = ethutil.Hex2Bytes("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")
root = trie.Hash()
if !bytes.Equal(root, exp) {
t.Errorf("exp %x got %x", exp, root)
}
}
func TestGet(t *testing.T) {
trie := NewEmpty()
trie.UpdateString("doe", "reindeer")
trie.UpdateString("dog", "puppy")
trie.UpdateString("dogglesworth", "cat")
res := trie.GetString("dog")
if !bytes.Equal(res, []byte("puppy")) {
t.Errorf("expected puppy got %x", res)
}
unknown := trie.GetString("unknown")
if unknown != nil {
t.Errorf("expected nil got %x", unknown)
}
}
func TestDelete(t *testing.T) {
trie := NewEmpty()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"ether", ""},
{"dog", "puppy"},
{"shaman", ""},
}
for _, val := range vals {
if val.v != "" {
trie.UpdateString(val.k, val.v)
} else {
trie.DeleteString(val.k)
}
}
hash := trie.Hash()
exp := ethutil.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
if !bytes.Equal(hash, exp) {
t.Errorf("expected %x got %x", exp, hash)
}
}
func TestEmptyValues(t *testing.T) {
trie := NewEmpty()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"ether", ""},
{"dog", "puppy"},
{"shaman", ""},
}
for _, val := range vals {
trie.UpdateString(val.k, val.v)
}
hash := trie.Hash()
exp := ethutil.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
if !bytes.Equal(hash, exp) {
t.Errorf("expected %x got %x", exp, hash)
}
}
func TestReplication(t *testing.T) {
trie := NewEmpty()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"ether", ""},
{"dog", "puppy"},
{"shaman", ""},
{"somethingveryoddindeedthis is", "myothernodedata"},
}
for _, val := range vals {
trie.UpdateString(val.k, val.v)
}
trie.Commit()
trie2 := New(trie.roothash, trie.cache.backend)
if string(trie2.GetString("horse")) != "stallion" {
t.Error("expected to have harse => stallion")
}
hash := trie2.Hash()
exp := trie.Hash()
if !bytes.Equal(hash, exp) {
t.Errorf("root failure. expected %x got %x", exp, hash)
}
}
func TestReset(t *testing.T) {
trie := NewEmpty()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
}
for _, val := range vals {
trie.UpdateString(val.k, val.v)
}
trie.Commit()
before := ethutil.CopyBytes(trie.roothash)
trie.UpdateString("should", "revert")
trie.Hash()
// Should have no effect
trie.Hash()
trie.Hash()
// ###
trie.Reset()
after := ethutil.CopyBytes(trie.roothash)
if !bytes.Equal(before, after) {
t.Errorf("expected roots to be equal. %x - %x", before, after)
}
}
func TestParanoia(t *testing.T) {
t.Skip()
trie := NewEmpty()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"ether", ""},
{"dog", "puppy"},
{"shaman", ""},
{"somethingveryoddindeedthis is", "myothernodedata"},
}
for _, val := range vals {
trie.UpdateString(val.k, val.v)
}
trie.Commit()
ok, t2 := ParanoiaCheck(trie, trie.cache.backend)
if !ok {
t.Errorf("trie paranoia check failed %x %x", trie.roothash, t2.roothash)
}
}
// Not an actual test
func TestOutput(t *testing.T) {
t.Skip()
base := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
trie := NewEmpty()
for i := 0; i < 50; i++ {
trie.UpdateString(fmt.Sprintf("%s%d", base, i), "valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
}
fmt.Println("############################## FULL ################################")
fmt.Println(trie.root)
trie.Commit()
fmt.Println("############################## SMALL ################################")
trie2 := New(trie.roothash, trie.cache.backend)
trie2.GetString(base + "20")
fmt.Println(trie2.root)
}
func BenchmarkGets(b *testing.B) {
trie := NewEmpty()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"ether", ""},
{"dog", "puppy"},
{"shaman", ""},
{"somethingveryoddindeedthis is", "myothernodedata"},
}
for _, val := range vals {
trie.UpdateString(val.k, val.v)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
trie.Get([]byte("horse"))
}
}
func BenchmarkUpdate(b *testing.B) {
trie := NewEmpty()
b.ResetTimer()
for i := 0; i < b.N; i++ {
trie.UpdateString(fmt.Sprintf("aaaaaaaaa%d", i), "value")
}
trie.Hash()
}
package ptrie
type ValueNode struct {
trie *Trie
data []byte
}
func (self *ValueNode) Value() Node { return self } // Best not to call :-)
func (self *ValueNode) Val() []byte { return self.data }
func (self *ValueNode) Dirty() bool { return true }
func (self *ValueNode) Copy() Node { return &ValueNode{self.trie, self.data} }
func (self *ValueNode) RlpData() interface{} { return self.data }
func (self *ValueNode) Hash() interface{} { return self.data }
This diff is collapsed.
This diff is collapsed.
/*
Package rlp implements the RLP serialization format.
The purpose of RLP (Recursive Linear Prefix) qis to encode arbitrarily
nested arrays of binary data, and RLP is the main encoding method used
to serialize objects in Ethereum. The only purpose of RLP is to encode
structure; encoding specific atomic data types (eg. strings, ints,
floats) is left up to higher-order protocols; in Ethereum integers
must be represented in big endian binary form with no leading zeroes
(thus making the integer value zero be equivalent to the empty byte
array).
RLP values are distinguished by a type tag. The type tag precedes the
value in the input stream and defines the size and kind of the bytes
that follow.
*/
package rlp
package rlp
import (
"fmt"
"math/big"
"reflect"
"sync"
)
type decoder func(*Stream, reflect.Value) error
type typeinfo struct {
decoder
}
var (
typeCacheMutex sync.RWMutex
typeCache = make(map[reflect.Type]*typeinfo)
)
func cachedTypeInfo(typ reflect.Type) (*typeinfo, error) {
typeCacheMutex.RLock()
info := typeCache[typ]
typeCacheMutex.RUnlock()
if info != nil {
return info, nil
}
// not in the cache, need to generate info for this type.
typeCacheMutex.Lock()
defer typeCacheMutex.Unlock()
return cachedTypeInfo1(typ)
}
func cachedTypeInfo1(typ reflect.Type) (*typeinfo, error) {
info := typeCache[typ]
if info != nil {
// another goroutine got the write lock first
return info, nil
}
// put a dummmy value into the cache before generating.
// if the generator tries to lookup itself, it will get
// the dummy value and won't call itself recursively.
typeCache[typ] = new(typeinfo)
info, err := genTypeInfo(typ)
if err != nil {
// remove the dummy value if the generator fails
delete(typeCache, typ)
return nil, err
}
*typeCache[typ] = *info
return typeCache[typ], err
}
var (
decoderInterface = reflect.TypeOf(new(Decoder)).Elem()
bigInt = reflect.TypeOf(big.Int{})
)
func genTypeInfo(typ reflect.Type) (info *typeinfo, err error) {
info = new(typeinfo)
kind := typ.Kind()
switch {
case typ.Implements(decoderInterface):
info.decoder = decodeDecoder
case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderInterface):
info.decoder = decodeDecoderNoPtr
case typ.AssignableTo(reflect.PtrTo(bigInt)):
info.decoder = decodeBigInt
case typ.AssignableTo(bigInt):
info.decoder = decodeBigIntNoPtr
case isInteger(kind):
info.decoder = makeNumDecoder(typ)
case kind == reflect.String:
info.decoder = decodeString
case kind == reflect.Slice || kind == reflect.Array:
info.decoder, err = makeListDecoder(typ)
case kind == reflect.Struct:
info.decoder, err = makeStructDecoder(typ)
case kind == reflect.Ptr:
info.decoder, err = makePtrDecoder(typ)
case kind == reflect.Interface && typ.NumMethod() == 0:
info.decoder = decodeInterface
default:
err = fmt.Errorf("rlp: type %v is not RLP-serializable", typ)
}
return info, err
}
func isInteger(k reflect.Kind) bool {
return k >= reflect.Int && k <= reflect.Uintptr
}
...@@ -46,3 +46,11 @@ func (self *State) Dump() []byte { ...@@ -46,3 +46,11 @@ func (self *State) Dump() []byte {
return json return json
} }
// Debug stuff
func (self *StateObject) CreateOutputForDiff() {
fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce)
self.EachStorage(func(addr string, value *ethutil.Value) {
fmt.Printf("%x %x\n", addr, value.Bytes())
})
}
...@@ -148,9 +148,7 @@ func (self *StateObject) EachStorage(cb trie.EachCallback) { ...@@ -148,9 +148,7 @@ func (self *StateObject) EachStorage(cb trie.EachCallback) {
func (self *StateObject) Sync() { func (self *StateObject) Sync() {
for key, value := range self.storage { for key, value := range self.storage {
if value.Len() == 0 { // value.BigInt().Cmp(ethutil.Big0) == 0 { if value.Len() == 0 {
//data := self.getStorage([]byte(key))
//fmt.Printf("deleting %x %x 0x%x\n", self.Address(), []byte(key), data)
self.State.Trie.Delete(string(key)) self.State.Trie.Delete(string(key))
continue continue
} }
...@@ -287,14 +285,6 @@ func (self *StateObject) Root() []byte { ...@@ -287,14 +285,6 @@ func (self *StateObject) Root() []byte {
return self.State.Trie.GetRoot() return self.State.Trie.GetRoot()
} }
// Debug stuff
func (self *StateObject) CreateOutputForDiff() {
fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce)
self.EachStorage(func(addr string, value *ethutil.Value) {
fmt.Printf("%x %x\n", addr, value.Bytes())
})
}
// //
// Encoding // Encoding
// //
......
...@@ -197,7 +197,12 @@ func (t *Trie) Update(key, value string) { ...@@ -197,7 +197,12 @@ func (t *Trie) Update(key, value string) {
k := CompactHexDecode(key) k := CompactHexDecode(key)
root := t.UpdateState(t.Root, k, value) var root interface{}
if value != "" {
root = t.UpdateState(t.Root, k, value)
} else {
root = t.deleteState(t.Root, k)
}
t.setRoot(root) t.setRoot(root)
} }
......
package trie package trie
import ( import (
"bytes"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
"net/http" "net/http"
"testing"
"time" "time"
checker "gopkg.in/check.v1" checker "gopkg.in/check.v1"
...@@ -387,3 +389,59 @@ func TestRndCase(t *testing.T) { ...@@ -387,3 +389,59 @@ func TestRndCase(t *testing.T) {
fmt.Printf("%x\n", trie.Get(string(ethutil.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")))) fmt.Printf("%x\n", trie.Get(string(ethutil.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))))
} }
*/ */
func TestOtherSomething(t *testing.T) {
_, trie := NewTrie()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"ether", ""},
{"dog", "puppy"},
{"shaman", ""},
}
for _, val := range vals {
trie.Update(val.k, val.v)
}
exp := ethutil.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
hash := trie.Root.([]byte)
if !bytes.Equal(hash, exp) {
t.Errorf("expected %x got %x", exp, hash)
}
}
func BenchmarkGets(b *testing.B) {
_, trie := NewTrie()
vals := []struct{ k, v string }{
{"do", "verb"},
{"ether", "wookiedoo"},
{"horse", "stallion"},
{"shaman", "horse"},
{"doge", "coin"},
{"ether", ""},
{"dog", "puppy"},
{"shaman", ""},
{"somethingveryoddindeedthis is", "myothernodedata"},
}
for _, val := range vals {
trie.Update(val.k, val.v)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
trie.Get("horse")
}
}
func BenchmarkUpdate(b *testing.B) {
_, trie := NewTrie()
b.ResetTimer()
for i := 0; i < b.N; i++ {
trie.Update(fmt.Sprintf("aaaaaaaaaaaaaaa%d", i), "value")
}
}
...@@ -805,7 +805,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -805,7 +805,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
stack.Push(closure.Gas) stack.Push(closure.Gas)
// 0x60 range // 0x60 range
case CREATE: case CREATE:
var ( var (
err error err error
value = stack.Pop() value = stack.Pop()
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"sync/atomic" "sync/atomic"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
...@@ -209,7 +210,7 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr ...@@ -209,7 +210,7 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr
gas = ethutil.Big(gasStr) gas = ethutil.Big(gasStr)
gasPrice = ethutil.Big(gasPriceStr) gasPrice = ethutil.Big(gasPriceStr)
data []byte data []byte
tx *chain.Transaction tx *types.Transaction
) )
if ethutil.IsHex(codeStr) { if ethutil.IsHex(codeStr) {
...@@ -219,9 +220,9 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr ...@@ -219,9 +220,9 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr
} }
if contractCreation { if contractCreation {
tx = chain.NewContractCreationTx(value, gas, gasPrice, data) tx = types.NewContractCreationTx(value, gas, gasPrice, data)
} else { } else {
tx = chain.NewTransactionMessage(hash, value, gas, gasPrice, data) tx = types.NewTransactionMessage(hash, value, gas, gasPrice, data)
} }
acc := self.obj.BlockManager().TransState().GetOrNewStateObject(keyPair.Address()) acc := self.obj.BlockManager().TransState().GetOrNewStateObject(keyPair.Address())
...@@ -240,7 +241,7 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr ...@@ -240,7 +241,7 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr
} }
func (self *JSXEth) PushTx(txStr string) (*JSReceipt, error) { func (self *JSXEth) PushTx(txStr string) (*JSReceipt, error) {
tx := chain.NewTransactionFromBytes(ethutil.Hex2Bytes(txStr)) tx := types.NewTransactionFromBytes(ethutil.Hex2Bytes(txStr))
self.obj.TxPool().QueueTransaction(tx) self.obj.TxPool().QueueTransaction(tx)
return NewJSReciept(tx.CreatesContract(), tx.CreationAddress(self.World().State()), tx.Hash(), tx.Sender()), nil return NewJSReciept(tx.CreatesContract(), tx.CreationAddress(self.World().State()), tx.Hash(), tx.Sender()), nil
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"strings" "strings"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
...@@ -14,7 +15,7 @@ import ( ...@@ -14,7 +15,7 @@ import (
// Block interface exposed to QML // Block interface exposed to QML
type JSBlock struct { type JSBlock struct {
//Transactions string `json:"transactions"` //Transactions string `json:"transactions"`
ref *chain.Block ref *types.Block
Size string `json:"size"` Size string `json:"size"`
Number int `json:"number"` Number int `json:"number"`
Hash string `json:"hash"` Hash string `json:"hash"`
...@@ -31,7 +32,7 @@ type JSBlock struct { ...@@ -31,7 +32,7 @@ type JSBlock struct {
} }
// Creates a new QML Block from a chain block // Creates a new QML Block from a chain block
func NewJSBlock(block *chain.Block) *JSBlock { func NewJSBlock(block *types.Block) *JSBlock {
if block == nil { if block == nil {
return &JSBlock{} return &JSBlock{}
} }
...@@ -79,7 +80,7 @@ func (self *JSBlock) GetTransaction(hash string) *JSTransaction { ...@@ -79,7 +80,7 @@ func (self *JSBlock) GetTransaction(hash string) *JSTransaction {
} }
type JSTransaction struct { type JSTransaction struct {
ref *chain.Transaction ref *types.Transaction
Value string `json:"value"` Value string `json:"value"`
Gas string `json:"gas"` Gas string `json:"gas"`
...@@ -94,7 +95,7 @@ type JSTransaction struct { ...@@ -94,7 +95,7 @@ type JSTransaction struct {
Confirmations int `json:"confirmations"` Confirmations int `json:"confirmations"`
} }
func NewJSTx(tx *chain.Transaction, state *state.State) *JSTransaction { func NewJSTx(tx *types.Transaction, state *state.State) *JSTransaction {
hash := ethutil.Bytes2Hex(tx.Hash()) hash := ethutil.Bytes2Hex(tx.Hash())
receiver := ethutil.Bytes2Hex(tx.Recipient) receiver := ethutil.Bytes2Hex(tx.Recipient)
if receiver == "0000000000000000000000000000000000000000" { if receiver == "0000000000000000000000000000000000000000" {
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"strings" "strings"
"github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
...@@ -72,7 +73,7 @@ func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price * ...@@ -72,7 +73,7 @@ func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *
return ret, err return ret, err
} }
func (self *XEth) Block(hash []byte) *chain.Block { func (self *XEth) Block(hash []byte) *types.Block {
return self.blockChain.GetBlock(hash) return self.blockChain.GetBlock(hash)
} }
...@@ -115,7 +116,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e ...@@ -115,7 +116,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e
contractCreation = true contractCreation = true
} }
var tx *chain.Transaction var tx *types.Transaction
// Compile and assemble the given data // Compile and assemble the given data
if contractCreation { if contractCreation {
script, err := ethutil.Compile(string(data), false) script, err := ethutil.Compile(string(data), false)
...@@ -123,7 +124,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e ...@@ -123,7 +124,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e
return nil, err return nil, err
} }
tx = chain.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), script) tx = types.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), script)
} else { } else {
data := ethutil.StringToByteFunc(string(data), func(s string) (ret []byte) { data := ethutil.StringToByteFunc(string(data), func(s string) (ret []byte) {
slice := strings.Split(s, "\n") slice := strings.Split(s, "\n")
...@@ -134,7 +135,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e ...@@ -134,7 +135,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e
return return
}) })
tx = chain.NewTransactionMessage(hash, value.BigInt(), gas.BigInt(), price.BigInt(), data) tx = types.NewTransactionMessage(hash, value.BigInt(), gas.BigInt(), price.BigInt(), data)
} }
acc := self.blockManager.TransState().GetOrNewStateObject(key.Address()) acc := self.blockManager.TransState().GetOrNewStateObject(key.Address())
...@@ -155,7 +156,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e ...@@ -155,7 +156,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *e
return tx.Hash(), nil return tx.Hash(), nil
} }
func (self *XEth) PushTx(tx *chain.Transaction) ([]byte, error) { func (self *XEth) PushTx(tx *types.Transaction) ([]byte, error) {
self.obj.TxPool().QueueTransaction(tx) self.obj.TxPool().QueueTransaction(tx)
if tx.Recipient == nil { if tx.Recipient == nil {
addr := tx.CreationAddress(self.World().State()) addr := tx.CreationAddress(self.World().State())
......
...@@ -2,20 +2,19 @@ package xeth ...@@ -2,20 +2,19 @@ package xeth
import ( import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm" "github.com/ethereum/go-ethereum/vm"
) )
type VMEnv struct { type VMEnv struct {
state *state.State state *state.State
block *chain.Block block *types.Block
value *big.Int value *big.Int
sender []byte sender []byte
} }
func NewEnv(state *state.State, block *chain.Block, value *big.Int, sender []byte) *VMEnv { func NewEnv(state *state.State, block *types.Block, value *big.Int, sender []byte) *VMEnv {
return &VMEnv{ return &VMEnv{
state: state, state: state,
block: block, block: block,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment