diff options
author | obscuren <geffobscura@gmail.com> | 2014-12-04 17:28:02 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-12-04 17:28:02 +0800 |
commit | 9008b155d3c8d2a32c4c8945f1174243d48d4e90 (patch) | |
tree | a55140b7d4802a0db14cbc265b8ca21d44d6f10a /chain | |
parent | b6cb5272de96185b424d5c6c4a817d99f536d29b (diff) | |
download | go-tangerine-9008b155d3c8d2a32c4c8945f1174243d48d4e90.tar go-tangerine-9008b155d3c8d2a32c4c8945f1174243d48d4e90.tar.gz go-tangerine-9008b155d3c8d2a32c4c8945f1174243d48d4e90.tar.bz2 go-tangerine-9008b155d3c8d2a32c4c8945f1174243d48d4e90.tar.lz go-tangerine-9008b155d3c8d2a32c4c8945f1174243d48d4e90.tar.xz go-tangerine-9008b155d3c8d2a32c4c8945f1174243d48d4e90.tar.zst go-tangerine-9008b155d3c8d2a32c4c8945f1174243d48d4e90.zip |
Renamed `chain` => `core`
Diffstat (limited to 'chain')
-rw-r--r-- | chain/.gitignore | 12 | ||||
-rw-r--r-- | chain/asm.go | 50 | ||||
-rw-r--r-- | chain/block_manager.go | 414 | ||||
-rw-r--r-- | chain/chain_manager.go | 276 | ||||
-rw-r--r-- | chain/chain_manager_test.go | 116 | ||||
-rw-r--r-- | chain/dagger.go | 245 | ||||
-rw-r--r-- | chain/dagger_test.go | 19 | ||||
-rw-r--r-- | chain/error.go | 141 | ||||
-rw-r--r-- | chain/events.go | 12 | ||||
-rw-r--r-- | chain/execution.go | 80 | ||||
-rw-r--r-- | chain/fees.go | 7 | ||||
-rw-r--r-- | chain/filter.go | 200 | ||||
-rw-r--r-- | chain/filter_test.go | 7 | ||||
-rw-r--r-- | chain/genesis.go | 52 | ||||
-rw-r--r-- | chain/helper_test.go | 93 | ||||
-rw-r--r-- | chain/state_transition.go | 198 | ||||
-rw-r--r-- | chain/transaction_pool.go | 236 | ||||
-rw-r--r-- | chain/types/block.go | 413 | ||||
-rw-r--r-- | chain/types/bloom9.go | 56 | ||||
-rw-r--r-- | chain/types/bloom9_test.go | 31 | ||||
-rw-r--r-- | chain/types/common.go | 11 | ||||
-rw-r--r-- | chain/types/derive_sha.go | 20 | ||||
-rw-r--r-- | chain/types/receipt.go | 68 | ||||
-rw-r--r-- | chain/types/transaction.go | 225 | ||||
-rw-r--r-- | chain/types/transaction_test.go | 1 | ||||
-rw-r--r-- | chain/vm_env.go | 63 |
26 files changed, 0 insertions, 3046 deletions
diff --git a/chain/.gitignore b/chain/.gitignore deleted file mode 100644 index f725d58d1..000000000 --- a/chain/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile ~/.gitignore_global - -/tmp -*/**/*un~ -*un~ -.DS_Store -*/**/.DS_Store - diff --git a/chain/asm.go b/chain/asm.go deleted file mode 100644 index 5a2e961ac..000000000 --- a/chain/asm.go +++ /dev/null @@ -1,50 +0,0 @@ -package chain - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/vm" -) - -func Disassemble(script []byte) (asm []string) { - pc := new(big.Int) - for { - if pc.Cmp(big.NewInt(int64(len(script)))) >= 0 { - return - } - - // Get the memory location of pc - val := script[pc.Int64()] - // Get the opcode (it must be an opcode!) - op := vm.OpCode(val) - - asm = append(asm, fmt.Sprintf("%04v: %v", pc, op)) - - switch op { - case vm.PUSH1, vm.PUSH2, vm.PUSH3, vm.PUSH4, vm.PUSH5, vm.PUSH6, vm.PUSH7, vm.PUSH8, - vm.PUSH9, vm.PUSH10, vm.PUSH11, vm.PUSH12, vm.PUSH13, vm.PUSH14, vm.PUSH15, - vm.PUSH16, vm.PUSH17, vm.PUSH18, vm.PUSH19, vm.PUSH20, vm.PUSH21, vm.PUSH22, - vm.PUSH23, vm.PUSH24, vm.PUSH25, vm.PUSH26, vm.PUSH27, vm.PUSH28, vm.PUSH29, - vm.PUSH30, vm.PUSH31, vm.PUSH32: - pc.Add(pc, ethutil.Big1) - a := int64(op) - int64(vm.PUSH1) + 1 - if int(pc.Int64()+a) > len(script) { - return - } - - data := script[pc.Int64() : pc.Int64()+a] - if len(data) == 0 { - data = []byte{0} - } - asm = append(asm, fmt.Sprintf("%04v: 0x%x", pc, data)) - - pc.Add(pc, big.NewInt(a-1)) - } - - pc.Add(pc, ethutil.Big1) - } - - return asm -} diff --git a/chain/block_manager.go b/chain/block_manager.go deleted file mode 100644 index eda8a5a0c..000000000 --- a/chain/block_manager.go +++ /dev/null @@ -1,414 +0,0 @@ -package chain - -import ( - "bytes" - "container/list" - "errors" - "fmt" - "math/big" - "sync" - "time" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/wire" -) - -var statelogger = logger.NewLogger("BLOCK") - -type Peer interface { - Inbound() bool - LastSend() time.Time - LastPong() int64 - Host() []byte - Port() uint16 - Version() string - PingTime() string - Connected() *int32 - Caps() *ethutil.Value -} - -type EthManager interface { - BlockManager() *BlockManager - ChainManager() *ChainManager - TxPool() *TxPool - Broadcast(msgType wire.MsgType, data []interface{}) - PeerCount() int - IsMining() bool - IsListening() bool - Peers() *list.List - KeyManager() *crypto.KeyManager - ClientIdentity() wire.ClientIdentity - Db() ethutil.Database - EventMux() *event.TypeMux -} - -type BlockManager struct { - // Mutex for locking the block processor. Blocks can only be handled one at a time - mutex sync.Mutex - // Canonical block chain - bc *ChainManager - // non-persistent key/value memory storage - mem map[string]*big.Int - // Proof of work used for validating - Pow PoW - // The ethereum manager interface - eth EthManager - // The managed states - // Transiently state. The trans state isn't ever saved, validated and - // it could be used for setting account nonces without effecting - // the main states. - transState *state.State - // Mining state. The mining state is used purely and solely by the mining - // operation. - miningState *state.State - - // The last attempted block is mainly used for debugging purposes - // This does not have to be a valid block and will be set during - // 'Process' & canonical validation. - lastAttemptedBlock *types.Block - - events event.Subscription -} - -func NewBlockManager(ethereum EthManager) *BlockManager { - sm := &BlockManager{ - mem: make(map[string]*big.Int), - Pow: &EasyPow{}, - eth: ethereum, - bc: ethereum.ChainManager(), - } - sm.transState = ethereum.ChainManager().CurrentBlock.State().Copy() - sm.miningState = ethereum.ChainManager().CurrentBlock.State().Copy() - - return sm -} - -func (self *BlockManager) Start() { - statelogger.Debugln("Starting block manager") -} - -func (self *BlockManager) Stop() { - statelogger.Debugln("Stopping state manager") -} - -func (sm *BlockManager) CurrentState() *state.State { - return sm.eth.ChainManager().CurrentBlock.State() -} - -func (sm *BlockManager) TransState() *state.State { - return sm.transState -} - -func (sm *BlockManager) MiningState() *state.State { - return sm.miningState -} - -func (sm *BlockManager) NewMiningState() *state.State { - sm.miningState = sm.eth.ChainManager().CurrentBlock.State().Copy() - - return sm.miningState -} - -func (sm *BlockManager) ChainManager() *ChainManager { - return sm.bc -} - -func (sm *BlockManager) TransitionState(statedb *state.State, parent, block *types.Block) (receipts types.Receipts, err error) { - coinbase := statedb.GetOrNewStateObject(block.Coinbase) - coinbase.SetGasPool(block.CalcGasLimit(parent)) - - // Process the transactions on to current block - receipts, _, _, _, err = sm.ProcessTransactions(coinbase, statedb, block, parent, block.Transactions()) - if err != nil { - return nil, err - } - - return receipts, nil -} - -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 ( - receipts types.Receipts - handled, unhandled types.Transactions - erroneous types.Transactions - totalUsedGas = big.NewInt(0) - err error - cumulativeSum = new(big.Int) - ) - -done: - for i, tx := range txs { - // If we are mining this block and validating we want to set the logs back to 0 - state.EmptyLogs() - - txGas := new(big.Int).Set(tx.Gas) - - cb := state.GetStateObject(coinbase.Address()) - st := NewStateTransition(cb, tx, state, block) - err = st.TransitionState() - if err != nil { - statelogger.Infoln(err) - switch { - case IsNonceErr(err): - err = nil // ignore error - continue - case IsGasLimitErr(err): - unhandled = txs[i:] - - break done - default: - statelogger.Infoln(err) - erroneous = append(erroneous, tx) - err = nil - continue - } - } - - txGas.Sub(txGas, st.gas) - cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice)) - - // Update the state with pending changes - state.Update(txGas) - - cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas)) - receipt := types.NewReceipt(state.Root(), cumulative) - receipt.SetLogs(state.Logs()) - receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) - - // Notify all subscribers - go self.eth.EventMux().Post(TxPostEvent{tx}) - - receipts = append(receipts, receipt) - handled = append(handled, tx) - - if ethutil.Config.Diff && ethutil.Config.DiffType == "all" { - state.CreateOutputForDiff() - } - } - - block.Reward = cumulativeSum - block.GasUsed = totalUsedGas - - return receipts, handled, unhandled, erroneous, err -} - -func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Messages, err error) { - // Processing a blocks may never happen simultaneously - sm.mutex.Lock() - defer sm.mutex.Unlock() - - if sm.bc.HasBlock(block.Hash()) { - return nil, nil, &KnownBlockError{block.Number, block.Hash()} - } - - if !sm.bc.HasBlock(block.PrevHash) { - return nil, nil, ParentError(block.PrevHash) - } - parent := sm.bc.GetBlock(block.PrevHash) - - return sm.ProcessWithParent(block, parent) -} - -func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) { - sm.lastAttemptedBlock = block - - state := parent.State().Copy() - - // Defer the Undo on the Trie. If the block processing happened - // we don't want to undo but since undo only happens on dirty - // nodes this won't happen because Commit would have been called - // before that. - defer state.Reset() - - if ethutil.Config.Diff && ethutil.Config.DiffType == "all" { - fmt.Printf("## %x %x ##\n", block.Hash(), block.Number) - } - - _, err = sm.TransitionState(state, parent, block) - if err != nil { - return - } - - txSha := types.DeriveSha(block.Transactions()) - if bytes.Compare(txSha, block.TxSha) != 0 { - err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha) - return - } - - /* - receiptSha := types.DeriveSha(receipts) - if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { - err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) - return - } - */ - - // Block validation - if err = sm.ValidateBlock(block, parent); err != nil { - return - } - - if err = sm.AccumelateRewards(state, block, parent); err != nil { - return - } - - /* - //block.receipts = receipts // although this isn't necessary it be in the future - rbloom := types.CreateBloom(receipts) - if bytes.Compare(rbloom, block.LogsBloom) != 0 { - err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) - return - } - */ - - state.Update(ethutil.Big0) - - if !block.State().Cmp(state) { - err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root()) - return - } - - // Calculate the new total difficulty and sync back to the db - if td, ok := sm.CalculateTD(block); ok { - // Sync the current block's state to the database and cancelling out the deferred Undo - state.Sync() - - messages := state.Manifest().Messages - state.Manifest().Reset() - - chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4]) - - sm.transState = state.Copy() - - sm.eth.TxPool().RemoveSet(block.Transactions()) - - return td, messages, nil - } else { - return nil, nil, errors.New("total diff failed") - } -} - -func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) { - uncleDiff := new(big.Int) - for _, uncle := range block.Uncles { - uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty) - } - - // TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty - td := new(big.Int) - td = td.Add(sm.bc.TD, uncleDiff) - td = td.Add(td, block.Difficulty) - - // The new TD will only be accepted if the new difficulty is - // is greater than the previous. - if td.Cmp(sm.bc.TD) > 0 { - return td, true - } - - return nil, false -} - -// Validates the current block. Returns an error if the block was invalid, -// an uncle or anything that isn't on the current block chain. -// Validation validates easy over difficult (dagger takes longer time = difficult) -func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error { - expd := CalcDifficulty(block, parent) - if expd.Cmp(block.Difficulty) < 0 { - return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) - } - - diff := block.Time - parent.Time - if diff < 0 { - return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time) - } - - /* XXX - // New blocks must be within the 15 minute range of the last block. - if diff > int64(15*time.Minute) { - return ValidationError("Block is too far in the future of last block (> 15 minutes)") - } - */ - - // Verify the nonce of the block. Return an error if it's not valid - if !sm.Pow.Verify(block.HashNoNonce(), block.Difficulty, block.Nonce) { - return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce)) - } - - return nil -} - -func (sm *BlockManager) AccumelateRewards(statedb *state.State, block, parent *types.Block) error { - reward := new(big.Int).Set(BlockReward) - - knownUncles := ethutil.Set(parent.Uncles) - nonces := ethutil.NewSet(block.Nonce) - for _, uncle := range block.Uncles { - if nonces.Include(uncle.Nonce) { - // Error not unique - return UncleError("Uncle not unique") - } - - uncleParent := sm.bc.GetBlock(uncle.PrevHash) - if uncleParent == nil { - return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.PrevHash[0:4])) - } - - if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 { - return UncleError("Uncle too old") - } - - if knownUncles.Include(uncle.Hash()) { - return UncleError("Uncle in chain") - } - - nonces.Insert(uncle.Nonce) - - r := new(big.Int) - r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16)) - - uncleAccount := statedb.GetAccount(uncle.Coinbase) - uncleAccount.AddAmount(r) - - reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32))) - } - - // Get the account associated with the coinbase - account := statedb.GetAccount(block.Coinbase) - // Reward amount of ether to the coinbase address - account.AddAmount(reward) - - statedb.Manifest().AddMessage(&state.Message{ - To: block.Coinbase, From: block.Coinbase, - Input: nil, - Origin: nil, - Block: block.Hash(), Timestamp: block.Time, Coinbase: block.Coinbase, Number: block.Number, - Value: new(big.Int).Add(reward, block.Reward), - }) - - return nil -} - -func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Message, err error) { - if !sm.bc.HasBlock(block.PrevHash) { - return nil, ParentError(block.PrevHash) - } - - sm.lastAttemptedBlock = block - - var ( - parent = sm.bc.GetBlock(block.PrevHash) - state = parent.State().Copy() - ) - - defer state.Reset() - - sm.TransitionState(state, parent, block) - sm.AccumelateRewards(state, block, parent) - - return state.Manifest().Messages, nil -} diff --git a/chain/chain_manager.go b/chain/chain_manager.go deleted file mode 100644 index 9b35ce08a..000000000 --- a/chain/chain_manager.go +++ /dev/null @@ -1,276 +0,0 @@ -package chain - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/logger" -) - -var chainlogger = logger.NewLogger("CHAIN") - -func AddTestNetFunds(block *types.Block) { - for _, addr := range []string{ - "51ba59315b3a95761d0863b05ccc7a7f54703d99", - "e4157b34ea9615cfbde6b4fda419828124b70c78", - "b9c015918bdaba24b4ff057a92a3873d6eb201be", - "6c386a4b26f73c802f34673f7248bb118f97424a", - "cd2a3d9f938e13cd947ec05abc7fe734df8dd826", - "2ef47100e0787b915105fd5e3f4ff6752079d5cb", - "e6716f9544a56c530d868e4bfbacb172315bdead", - "1a26338f0d905e295fccb71fa9ea849ffa12aaf4", - } { - codedAddr := ethutil.Hex2Bytes(addr) - account := block.State().GetAccount(codedAddr) - account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200) - block.State().UpdateStateObject(account) - } -} - -func CalcDifficulty(block, parent *types.Block) *big.Int { - diff := new(big.Int) - - adjust := new(big.Int).Rsh(parent.Difficulty, 10) - if block.Time >= parent.Time+5 { - diff.Sub(parent.Difficulty, adjust) - } else { - diff.Add(parent.Difficulty, adjust) - } - - return diff -} - -type ChainManager struct { - //eth EthManager - processor types.BlockProcessor - eventMux *event.TypeMux - genesisBlock *types.Block - // Last known total difficulty - TD *big.Int - - LastBlockNumber uint64 - - CurrentBlock *types.Block - LastBlockHash []byte -} - -func NewChainManager(mux *event.TypeMux) *ChainManager { - bc := &ChainManager{} - bc.genesisBlock = types.NewBlockFromBytes(ethutil.Encode(Genesis)) - bc.eventMux = mux - - bc.setLastBlock() - - return bc -} - -func (self *ChainManager) SetProcessor(proc types.BlockProcessor) { - self.processor = proc -} - -func (bc *ChainManager) setLastBlock() { - data, _ := ethutil.Config.Db.Get([]byte("LastBlock")) - if len(data) != 0 { - // Prep genesis - AddTestNetFunds(bc.genesisBlock) - - block := types.NewBlockFromBytes(data) - bc.CurrentBlock = block - bc.LastBlockHash = block.Hash() - bc.LastBlockNumber = block.Number.Uint64() - - // Set the last know difficulty (might be 0x0 as initial value, Genesis) - bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) - } else { - bc.Reset() - } - - chainlogger.Infof("Last block (#%d) %x\n", bc.LastBlockNumber, bc.CurrentBlock.Hash()) -} - -// Block creation & chain handling -func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block { - var root interface{} - hash := ZeroHash256 - - if bc.CurrentBlock != nil { - root = bc.CurrentBlock.Root() - hash = bc.LastBlockHash - } - - block := types.CreateBlock( - root, - hash, - coinbase, - ethutil.BigPow(2, 32), - nil, - "") - - parent := bc.CurrentBlock - if parent != nil { - block.Difficulty = CalcDifficulty(block, parent) - block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1) - block.GasLimit = block.CalcGasLimit(bc.CurrentBlock) - - } - - return block -} - -func (bc *ChainManager) Reset() { - AddTestNetFunds(bc.genesisBlock) - - bc.genesisBlock.Trie().Sync() - // Prepare the genesis block - bc.add(bc.genesisBlock) - bc.CurrentBlock = bc.genesisBlock - - bc.SetTotalDifficulty(ethutil.Big("0")) - - // Set the last know difficulty (might be 0x0 as initial value, Genesis) - bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) -} - -// Add a block to the chain and record addition information -func (bc *ChainManager) add(block *types.Block) { - bc.writeBlockInfo(block) - - bc.CurrentBlock = block - bc.LastBlockHash = block.Hash() - - encodedBlock := block.RlpEncode() - ethutil.Config.Db.Put(block.Hash(), encodedBlock) - ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) - - //chainlogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4]) -} - -// Accessors -func (bc *ChainManager) Genesis() *types.Block { - return bc.genesisBlock -} - -// Block fetching methods -func (bc *ChainManager) HasBlock(hash []byte) bool { - data, _ := ethutil.Config.Db.Get(hash) - return len(data) != 0 -} - -func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain [][]byte) { - block := self.GetBlock(hash) - if block == nil { - return - } - - // XXX Could be optimised by using a different database which only holds hashes (i.e., linked list) - for i := uint64(0); i < max; i++ { - - chain = append(chain, block.Hash()) - - if block.Number.Cmp(ethutil.Big0) <= 0 { - break - } - - block = self.GetBlock(block.PrevHash) - } - - return -} - -func (self *ChainManager) GetBlock(hash []byte) *types.Block { - data, _ := ethutil.Config.Db.Get(hash) - if len(data) == 0 { - return nil - } - - return types.NewBlockFromBytes(data) -} - -func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block { - block := self.CurrentBlock - for ; block != nil; block = self.GetBlock(block.PrevHash) { - if block.Number.Uint64() == num { - break - } - } - - if block != nil && block.Number.Uint64() == 0 && num != 0 { - return nil - } - - return block -} - -func (bc *ChainManager) SetTotalDifficulty(td *big.Int) { - ethutil.Config.Db.Put([]byte("LTD"), td.Bytes()) - bc.TD = td -} - -func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) { - parent := self.GetBlock(block.PrevHash) - if parent == nil { - return nil, fmt.Errorf("Unable to calculate total diff without known parent %x", block.PrevHash) - } - - parentTd := parent.BlockInfo().TD - - uncleDiff := new(big.Int) - for _, uncle := range block.Uncles { - uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty) - } - - td := new(big.Int) - td = td.Add(parentTd, uncleDiff) - td = td.Add(td, block.Difficulty) - - return td, nil -} - -func (bc *ChainManager) BlockInfo(block *types.Block) types.BlockInfo { - bi := types.BlockInfo{} - data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...)) - bi.RlpDecode(data) - - return bi -} - -// Unexported method for writing extra non-essential block info to the db -func (bc *ChainManager) writeBlockInfo(block *types.Block) { - bc.LastBlockNumber++ - bi := types.BlockInfo{Number: bc.LastBlockNumber, Hash: block.Hash(), Parent: block.PrevHash, TD: bc.TD} - - // For now we use the block hash with the words "info" appended as key - ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.RlpEncode()) -} - -func (bc *ChainManager) Stop() { - if bc.CurrentBlock != nil { - chainlogger.Infoln("Stopped") - } -} - -func (self *ChainManager) InsertChain(chain types.Blocks) error { - for _, block := range chain { - td, messages, err := self.processor.Process(block) - if err != nil { - if IsKnownBlockErr(err) { - continue - } - - chainlogger.Infof("block #%v process failed (%x)\n", block.Number, block.Hash()[:4]) - chainlogger.Infoln(block) - chainlogger.Infoln(err) - return err - } - - self.add(block) - self.SetTotalDifficulty(td) - self.eventMux.Post(NewBlockEvent{block}) - self.eventMux.Post(messages) - } - - return nil -} diff --git a/chain/chain_manager_test.go b/chain/chain_manager_test.go deleted file mode 100644 index 0314914a9..000000000 --- a/chain/chain_manager_test.go +++ /dev/null @@ -1,116 +0,0 @@ -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)) -} diff --git a/chain/dagger.go b/chain/dagger.go deleted file mode 100644 index 507850389..000000000 --- a/chain/dagger.go +++ /dev/null @@ -1,245 +0,0 @@ -package chain - -import ( - "hash" - "math/big" - "math/rand" - "time" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/logger" - "github.com/obscuren/sha3" -) - -var powlogger = logger.NewLogger("POW") - -type PoW interface { - Search(block *types.Block, stop <-chan struct{}) []byte - Verify(hash []byte, diff *big.Int, nonce []byte) bool - GetHashrate() int64 - Turbo(bool) -} - -type EasyPow struct { - hash *big.Int - HashRate int64 - turbo bool -} - -func (pow *EasyPow) GetHashrate() int64 { - return pow.HashRate -} - -func (pow *EasyPow) Turbo(on bool) { - pow.turbo = on -} - -func (pow *EasyPow) Search(block *types.Block, stop <-chan struct{}) []byte { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - hash := block.HashNoNonce() - diff := block.Difficulty - i := int64(0) - start := time.Now().UnixNano() - t := time.Now() - - for { - select { - case <-stop: - powlogger.Infoln("Breaking from mining") - pow.HashRate = 0 - return nil - default: - i++ - - if time.Since(t) > (1 * time.Second) { - elapsed := time.Now().UnixNano() - start - hashes := ((float64(1e9) / float64(elapsed)) * float64(i)) / 1000 - pow.HashRate = int64(hashes) - powlogger.Infoln("Hashing @", pow.HashRate, "khash") - - t = time.Now() - } - - sha := crypto.Sha3(big.NewInt(r.Int63()).Bytes()) - if pow.Verify(hash, diff, sha) { - return sha - } - } - - if !pow.turbo { - time.Sleep(20 * time.Microsecond) - } - } - - return nil -} - -func (pow *EasyPow) Verify(hash []byte, diff *big.Int, nonce []byte) bool { - sha := sha3.NewKeccak256() - - d := append(hash, nonce...) - sha.Write(d) - - verification := new(big.Int).Div(ethutil.BigPow(2, 256), diff) - res := ethutil.U256(ethutil.BigD(sha.Sum(nil))) - - /* - fmt.Printf("hash w/o nonce %x\n", hash) - fmt.Printf("2**256 / %v = %v\n", diff, verification) - fmt.Printf("%v <= %v\n", res, verification) - fmt.Printf("vlen: %d rlen: %d\n", len(verification.Bytes()), len(res.Bytes())) - */ - - return res.Cmp(verification) <= 0 -} - -func (pow *EasyPow) SetHash(hash *big.Int) { -} - -type Dagger struct { - hash *big.Int - xn *big.Int -} - -var Found bool - -func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - - for i := 0; i < 1000; i++ { - rnd := r.Int63() - - res := dag.Eval(big.NewInt(rnd)) - powlogger.Infof("rnd %v\nres %v\nobj %v\n", rnd, res, obj) - if res.Cmp(obj) < 0 { - // Post back result on the channel - resChan <- rnd - // Notify other threads we've found a valid nonce - Found = true - } - - // Break out if found - if Found { - break - } - } - - resChan <- 0 -} - -func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { - // TODO fix multi threading. Somehow it results in the wrong nonce - amountOfRoutines := 1 - - dag.hash = hash - - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) - - Found = false - resChan := make(chan int64, 3) - var res int64 - - for k := 0; k < amountOfRoutines; k++ { - go dag.Find(obj, resChan) - - // Wait for each go routine to finish - } - for k := 0; k < amountOfRoutines; k++ { - // Get the result from the channel. 0 = quit - if r := <-resChan; r != 0 { - res = r - } - } - - return big.NewInt(res) -} - -func (dag *Dagger) Verify(hash, diff, nonce *big.Int) bool { - dag.hash = hash - - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) - - return dag.Eval(nonce).Cmp(obj) < 0 -} - -func DaggerVerify(hash, diff, nonce *big.Int) bool { - dagger := &Dagger{} - dagger.hash = hash - - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) - - return dagger.Eval(nonce).Cmp(obj) < 0 -} - -func (dag *Dagger) Node(L uint64, i uint64) *big.Int { - if L == i { - return dag.hash - } - - var m *big.Int - if L == 9 { - m = big.NewInt(16) - } else { - m = big.NewInt(3) - } - - sha := sha3.NewKeccak256() - sha.Reset() - d := sha3.NewKeccak256() - b := new(big.Int) - ret := new(big.Int) - - for k := 0; k < int(m.Uint64()); k++ { - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(big.NewInt(int64(L)).Bytes()) - d.Write(big.NewInt(int64(i)).Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) - - b.SetBytes(Sum(d)) - pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) - sha.Write(dag.Node(L-1, pk).Bytes()) - } - - ret.SetBytes(Sum(sha)) - - return ret -} - -func Sum(sha hash.Hash) []byte { - //in := make([]byte, 32) - return sha.Sum(nil) -} - -func (dag *Dagger) Eval(N *big.Int) *big.Int { - pow := ethutil.BigPow(2, 26) - dag.xn = pow.Div(N, pow) - - sha := sha3.NewKeccak256() - sha.Reset() - ret := new(big.Int) - - for k := 0; k < 4; k++ { - d := sha3.NewKeccak256() - b := new(big.Int) - - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(N.Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) - - b.SetBytes(Sum(d)) - pk := (b.Uint64() & 0x1ffffff) - - sha.Write(dag.Node(9, pk).Bytes()) - } - - return ret.SetBytes(Sum(sha)) -} diff --git a/chain/dagger_test.go b/chain/dagger_test.go deleted file mode 100644 index b40cd9742..000000000 --- a/chain/dagger_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package chain - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/ethutil" -) - -func BenchmarkDaggerSearch(b *testing.B) { - hash := big.NewInt(0) - diff := ethutil.BigPow(2, 36) - o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity - - // Reset timer so the big generation isn't included in the benchmark - b.ResetTimer() - // Validate - DaggerVerify(hash, diff, o) -} diff --git a/chain/error.go b/chain/error.go deleted file mode 100644 index 0c4d6e59e..000000000 --- a/chain/error.go +++ /dev/null @@ -1,141 +0,0 @@ -package chain - -import ( - "fmt" - "math/big" -) - -// Parent error. In case a parent is unknown this error will be thrown -// by the block manager -type ParentErr struct { - Message string -} - -func (err *ParentErr) Error() string { - return err.Message -} - -func ParentError(hash []byte) error { - return &ParentErr{Message: fmt.Sprintf("Block's parent unkown %x", hash)} -} - -func IsParentErr(err error) bool { - _, ok := err.(*ParentErr) - - return ok -} - -type UncleErr struct { - Message string -} - -func (err *UncleErr) Error() string { - return err.Message -} - -func UncleError(str string) error { - return &UncleErr{Message: str} -} - -func IsUncleErr(err error) bool { - _, ok := err.(*UncleErr) - - return ok -} - -// Block validation error. If any validation fails, this error will be thrown -type ValidationErr struct { - Message string -} - -func (err *ValidationErr) Error() string { - return err.Message -} - -func ValidationError(format string, v ...interface{}) *ValidationErr { - return &ValidationErr{Message: fmt.Sprintf(format, v...)} -} - -func IsValidationErr(err error) bool { - _, ok := err.(*ValidationErr) - - return ok -} - -type GasLimitErr struct { - Message string - Is, Max *big.Int -} - -func IsGasLimitErr(err error) bool { - _, ok := err.(*GasLimitErr) - - return ok -} -func (err *GasLimitErr) Error() string { - return err.Message -} -func GasLimitError(is, max *big.Int) *GasLimitErr { - return &GasLimitErr{Message: fmt.Sprintf("GasLimit error. Max %s, transaction would take it to %s", max, is), Is: is, Max: max} -} - -type NonceErr struct { - Message string - Is, Exp uint64 -} - -func (err *NonceErr) Error() string { - return err.Message -} - -func NonceError(is, exp uint64) *NonceErr { - return &NonceErr{Message: fmt.Sprintf("Nonce err. Is %d, expected %d", is, exp), Is: is, Exp: exp} -} - -func IsNonceErr(err error) bool { - _, ok := err.(*NonceErr) - - return ok -} - -type OutOfGasErr struct { - Message string -} - -func OutOfGasError() *OutOfGasErr { - return &OutOfGasErr{Message: "Out of gas"} -} -func (self *OutOfGasErr) Error() string { - return self.Message -} - -func IsOutOfGasErr(err error) bool { - _, ok := err.(*OutOfGasErr) - - return ok -} - -type TDError struct { - a, b *big.Int -} - -func (self *TDError) Error() string { - return fmt.Sprintf("incoming chain has a lower or equal TD (%v <= %v)", self.a, self.b) -} -func IsTDError(e error) bool { - _, ok := e.(*TDError) - return ok -} - -type KnownBlockError struct { - number *big.Int - hash []byte -} - -func (self *KnownBlockError) Error() string { - return fmt.Sprintf("block %v already known (%x)", self.number, self.hash[0:4]) -} -func IsKnownBlockErr(e error) bool { - _, ok := e.(*KnownBlockError) - return ok -} diff --git a/chain/events.go b/chain/events.go deleted file mode 100644 index 06ab6be79..000000000 --- a/chain/events.go +++ /dev/null @@ -1,12 +0,0 @@ -package chain - -import "github.com/ethereum/go-ethereum/chain/types" - -// TxPreEvent is posted when a transaction enters the transaction pool. -type TxPreEvent struct{ Tx *types.Transaction } - -// TxPostEvent is posted when a transaction has been processed. -type TxPostEvent struct{ Tx *types.Transaction } - -// NewBlockEvent is posted when a block has been imported. -type NewBlockEvent struct{ Block *types.Block } diff --git a/chain/execution.go b/chain/execution.go deleted file mode 100644 index 932ffa868..000000000 --- a/chain/execution.go +++ /dev/null @@ -1,80 +0,0 @@ -package chain - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/vm" -) - -type Execution struct { - vm vm.VirtualMachine - address, input []byte - Gas, price, value *big.Int - object *state.StateObject - SkipTransfer bool -} - -func NewExecution(vm vm.VirtualMachine, address, input []byte, gas, gasPrice, value *big.Int) *Execution { - return &Execution{vm: vm, address: address, input: input, Gas: gas, price: gasPrice, value: value} -} - -func (self *Execution) Addr() []byte { - return self.address -} - -func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, error) { - // Retrieve the executing code - code := self.vm.Env().State().GetCode(codeAddr) - - return self.exec(code, codeAddr, caller) -} - -func (self *Execution) exec(code, caddr []byte, caller vm.ClosureRef) (ret []byte, err error) { - env := self.vm.Env() - - chainlogger.Debugf("pre state %x\n", env.State().Root()) - snapshot := env.State().Copy() - defer func() { - if vm.IsDepthErr(err) || vm.IsOOGErr(err) { - env.State().Set(snapshot) - } - chainlogger.Debugf("post state %x\n", env.State().Root()) - }() - - from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(self.address) - // Skipping transfer is used on testing for the initial call - if !self.SkipTransfer { - err = env.Transfer(from, to, self.value) - } - - if err != nil { - caller.ReturnGas(self.Gas, self.price) - - err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance) - } else { - self.object = to - // Pre-compiled contracts (address.go) 1, 2 & 3. - naddr := ethutil.BigD(caddr).Uint64() - if p := vm.Precompiled[naddr]; p != nil { - if self.Gas.Cmp(p.Gas) >= 0 { - ret = p.Call(self.input) - self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret) - self.vm.Endl() - } - } else { - ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) - } - } - - return -} - -func (self *Execution) Create(caller vm.ClosureRef) (ret []byte, err error, account *state.StateObject) { - ret, err = self.exec(self.input, nil, caller) - account = self.vm.Env().State().GetStateObject(self.address) - - return -} diff --git a/chain/fees.go b/chain/fees.go deleted file mode 100644 index 4df6d365d..000000000 --- a/chain/fees.go +++ /dev/null @@ -1,7 +0,0 @@ -package chain - -import ( - "math/big" -) - -var BlockReward *big.Int = big.NewInt(1.5e+18) diff --git a/chain/filter.go b/chain/filter.go deleted file mode 100644 index bb8db38a5..000000000 --- a/chain/filter.go +++ /dev/null @@ -1,200 +0,0 @@ -package chain - -import ( - "bytes" - "math" - "math/big" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" -) - -type AccountChange struct { - Address, StateAddress []byte -} - -// Filtering interface -type Filter struct { - eth EthManager - earliest int64 - latest int64 - skip int - from, to [][]byte - max int - - Altered []AccountChange - - BlockCallback func(*types.Block) - MessageCallback func(state.Messages) -} - -// Create a new filter which uses a bloom filter on blocks to figure out whether a particular block -// is interesting or not. -func NewFilter(eth EthManager) *Filter { - return &Filter{eth: eth} -} - -func (self *Filter) AddAltered(address, stateAddress []byte) { - self.Altered = append(self.Altered, AccountChange{address, stateAddress}) -} - -// Set the earliest and latest block for filtering. -// -1 = latest block (i.e., the current block) -// hash = particular hash from-to -func (self *Filter) SetEarliestBlock(earliest int64) { - self.earliest = earliest -} - -func (self *Filter) SetLatestBlock(latest int64) { - self.latest = latest -} - -func (self *Filter) SetFrom(addr [][]byte) { - self.from = addr -} - -func (self *Filter) AddFrom(addr []byte) { - self.from = append(self.from, addr) -} - -func (self *Filter) SetTo(addr [][]byte) { - self.to = addr -} - -func (self *Filter) AddTo(addr []byte) { - self.to = append(self.to, addr) -} - -func (self *Filter) SetMax(max int) { - self.max = max -} - -func (self *Filter) SetSkip(skip int) { - self.skip = skip -} - -// Run filters messages with the current parameters set -func (self *Filter) Find() []*state.Message { - var earliestBlockNo uint64 = uint64(self.earliest) - if self.earliest == -1 { - earliestBlockNo = self.eth.ChainManager().CurrentBlock.Number.Uint64() - } - var latestBlockNo uint64 = uint64(self.latest) - if self.latest == -1 { - latestBlockNo = self.eth.ChainManager().CurrentBlock.Number.Uint64() - } - - var ( - messages []*state.Message - block = self.eth.ChainManager().GetBlockByNumber(latestBlockNo) - quit bool - ) - for i := 0; !quit && block != nil; i++ { - // Quit on latest - switch { - case block.Number.Uint64() == earliestBlockNo, block.Number.Uint64() == 0: - quit = true - case self.max <= len(messages): - break - } - - // Use bloom filtering to see if this block is interesting given the - // current parameters - if self.bloomFilter(block) { - // Get the messages of the block - msgs, err := self.eth.BlockManager().GetMessages(block) - if err != nil { - chainlogger.Warnln("err: filter get messages ", err) - - break - } - - messages = append(messages, self.FilterMessages(msgs)...) - } - - block = self.eth.ChainManager().GetBlock(block.PrevHash) - } - - skip := int(math.Min(float64(len(messages)), float64(self.skip))) - - return messages[skip:] -} - -func includes(addresses [][]byte, a []byte) (found bool) { - for _, addr := range addresses { - if bytes.Compare(addr, a) == 0 { - return true - } - } - - return -} - -func (self *Filter) FilterMessages(msgs []*state.Message) []*state.Message { - var messages []*state.Message - - // Filter the messages for interesting stuff - for _, message := range msgs { - if len(self.to) > 0 && !includes(self.to, message.To) { - continue - } - - if len(self.from) > 0 && !includes(self.from, message.From) { - continue - } - - var match bool - if len(self.Altered) == 0 { - match = true - } - - for _, accountChange := range self.Altered { - if len(accountChange.Address) > 0 && bytes.Compare(message.To, accountChange.Address) != 0 { - continue - } - - if len(accountChange.StateAddress) > 0 && !includes(message.ChangedAddresses, accountChange.StateAddress) { - continue - } - - match = true - break - } - - if !match { - continue - } - - messages = append(messages, message) - } - - return messages -} - -func (self *Filter) bloomFilter(block *types.Block) bool { - var fromIncluded, toIncluded bool - if len(self.from) > 0 { - for _, from := range self.from { - if types.BloomLookup(block.LogsBloom, from) || bytes.Equal(block.Coinbase, from) { - fromIncluded = true - break - } - } - } else { - fromIncluded = true - } - - if len(self.to) > 0 { - for _, to := range self.to { - if types.BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) || bytes.Equal(block.Coinbase, to) { - toIncluded = true - break - } - } - } else { - toIncluded = true - } - - return fromIncluded && toIncluded -} diff --git a/chain/filter_test.go b/chain/filter_test.go deleted file mode 100644 index c63bb5a2d..000000000 --- a/chain/filter_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package chain - -// import "testing" - -// func TestFilter(t *testing.T) { -// NewFilter(NewTestManager()) -// } diff --git a/chain/genesis.go b/chain/genesis.go deleted file mode 100644 index 85e85d1ed..000000000 --- a/chain/genesis.go +++ /dev/null @@ -1,52 +0,0 @@ -package chain - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethutil" -) - -/* - * This is the special genesis block. - */ - -var ZeroHash256 = make([]byte, 32) -var ZeroHash160 = make([]byte, 20) -var ZeroHash512 = make([]byte, 64) -var EmptyShaList = crypto.Sha3(ethutil.Encode([]interface{}{})) -var EmptyListRoot = crypto.Sha3(ethutil.Encode("")) - -var GenesisHeader = []interface{}{ - // Previous hash (none) - ZeroHash256, - // Empty uncles - EmptyShaList, - // Coinbase - ZeroHash160, - // Root state - EmptyShaList, - // tx root - EmptyListRoot, - // receipt root - EmptyListRoot, - // bloom - ZeroHash512, - // Difficulty - //ethutil.BigPow(2, 22), - big.NewInt(131072), - // Number - ethutil.Big0, - // Block upper gas bound - big.NewInt(1000000), - // Block gas used - ethutil.Big0, - // Time - ethutil.Big0, - // Extra - nil, - // Nonce - crypto.Sha3(big.NewInt(42).Bytes()), -} - -var Genesis = []interface{}{GenesisHeader, []interface{}{}, []interface{}{}} diff --git a/chain/helper_test.go b/chain/helper_test.go deleted file mode 100644 index 8c7532111..000000000 --- a/chain/helper_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package chain - -import ( - "container/list" - "fmt" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/wire" -) - -// Implement our EthTest Manager -type TestManager struct { - // stateManager *StateManager - eventMux *event.TypeMux - - db ethutil.Database - txPool *TxPool - blockChain *ChainManager - Blocks []*types.Block -} - -func (s *TestManager) IsListening() bool { - return false -} - -func (s *TestManager) IsMining() bool { - return false -} - -func (s *TestManager) PeerCount() int { - return 0 -} - -func (s *TestManager) Peers() *list.List { - return list.New() -} - -func (s *TestManager) ChainManager() *ChainManager { - return s.blockChain -} - -func (tm *TestManager) TxPool() *TxPool { - return tm.txPool -} - -// func (tm *TestManager) StateManager() *StateManager { -// return tm.stateManager -// } - -func (tm *TestManager) EventMux() *event.TypeMux { - return tm.eventMux -} -func (tm *TestManager) Broadcast(msgType wire.MsgType, data []interface{}) { - fmt.Println("Broadcast not implemented") -} - -func (tm *TestManager) ClientIdentity() wire.ClientIdentity { - return nil -} -func (tm *TestManager) KeyManager() *crypto.KeyManager { - return nil -} - -func (tm *TestManager) Db() ethutil.Database { - return tm.db -} - -func NewTestManager() *TestManager { - ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "ETH") - - db, err := ethdb.NewMemDatabase() - if err != nil { - fmt.Println("Could not create mem-db, failing") - return nil - } - ethutil.Config.Db = db - - testManager := &TestManager{} - testManager.eventMux = new(event.TypeMux) - testManager.db = db - // testManager.txPool = NewTxPool(testManager) - // testManager.blockChain = NewChainManager(testManager) - // testManager.stateManager = NewStateManager(testManager) - - // Start the tx pool - testManager.txPool.Start() - - return testManager -} diff --git a/chain/state_transition.go b/chain/state_transition.go deleted file mode 100644 index b2ba4f22a..000000000 --- a/chain/state_transition.go +++ /dev/null @@ -1,198 +0,0 @@ -package chain - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/vm" -) - -/* - * The State transitioning model - * - * A state transition is a change made when a transaction is applied to the current world state - * The state transitioning model does all all the necessary work to work out a valid new state root. - * 1) Nonce handling - * 2) Pre pay / buy gas of the coinbase (miner) - * 3) Create a new state object if the recipient is \0*32 - * 4) Value transfer - * == If contract creation == - * 4a) Attempt to run transaction data - * 4b) If valid, use result as code for the new state object - * == end == - * 5) Run Script section - * 6) Derive new state root - */ -type StateTransition struct { - coinbase, receiver []byte - tx *types.Transaction - gas, gasPrice *big.Int - value *big.Int - data []byte - state *state.State - block *types.Block - - cb, rec, sen *state.StateObject -} - -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} -} - -func (self *StateTransition) Coinbase() *state.StateObject { - if self.cb != nil { - return self.cb - } - - self.cb = self.state.GetOrNewStateObject(self.coinbase) - return self.cb -} -func (self *StateTransition) Sender() *state.StateObject { - if self.sen != nil { - return self.sen - } - - self.sen = self.state.GetOrNewStateObject(self.tx.Sender()) - - return self.sen -} -func (self *StateTransition) Receiver() *state.StateObject { - if self.tx != nil && self.tx.CreatesContract() { - return nil - } - - if self.rec != nil { - return self.rec - } - - self.rec = self.state.GetOrNewStateObject(self.tx.Recipient) - return self.rec -} - -func (self *StateTransition) UseGas(amount *big.Int) error { - if self.gas.Cmp(amount) < 0 { - return OutOfGasError() - } - self.gas.Sub(self.gas, amount) - - return nil -} - -func (self *StateTransition) AddGas(amount *big.Int) { - self.gas.Add(self.gas, amount) -} - -func (self *StateTransition) BuyGas() error { - var err error - - sender := self.Sender() - if sender.Balance().Cmp(self.tx.GasValue()) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance()) - } - - coinbase := self.Coinbase() - err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice) - if err != nil { - return err - } - - self.AddGas(self.tx.Gas) - sender.SubAmount(self.tx.GasValue()) - - return nil -} - -func (self *StateTransition) RefundGas() { - coinbase, sender := self.Coinbase(), self.Sender() - coinbase.RefundGas(self.gas, self.tx.GasPrice) - - // Return remaining gas - remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice) - sender.AddAmount(remaining) -} - -func (self *StateTransition) preCheck() (err error) { - var ( - tx = self.tx - sender = self.Sender() - ) - - // Make sure this transaction's nonce is correct - if sender.Nonce != tx.Nonce { - return NonceError(tx.Nonce, sender.Nonce) - } - - // Pre-pay gas / Buy gas of the coinbase account - if err = self.BuyGas(); err != nil { - return err - } - - return nil -} - -func (self *StateTransition) TransitionState() (err error) { - statelogger.Debugf("(~) %x\n", self.tx.Hash()) - - // XXX Transactions after this point are considered valid. - if err = self.preCheck(); err != nil { - return - } - - var ( - tx = self.tx - sender = self.Sender() - receiver *state.StateObject - ) - - defer self.RefundGas() - - // Increment the nonce for the next transaction - sender.Nonce += 1 - - // Transaction gas - if err = self.UseGas(vm.GasTx); err != nil { - return - } - - // Pay data gas - var dgas int64 - for _, byt := range self.data { - if byt != 0 { - dgas += vm.GasData.Int64() - } else { - dgas += 1 // This is 1/5. If GasData changes this fails - } - } - if err = self.UseGas(big.NewInt(dgas)); err != nil { - return - } - - var ret []byte - vmenv := NewEnv(self.state, self.tx, self.block) - var ref vm.ClosureRef - if tx.CreatesContract() { - self.rec = MakeContract(tx, self.state) - - ret, err, ref = vmenv.Create(sender, receiver.Address(), self.tx.Data, self.gas, self.gasPrice, self.value) - ref.SetCode(ret) - } else { - ret, err = vmenv.Call(self.Sender(), self.Receiver().Address(), self.tx.Data, self.gas, self.gasPrice, self.value) - } - if err != nil { - statelogger.Debugln(err) - } - - return -} - -// Converts an transaction in to a state object -func MakeContract(tx *types.Transaction, state *state.State) *state.StateObject { - addr := tx.CreationAddress(state) - - contract := state.GetOrNewStateObject(addr) - contract.InitCode = tx.Data - - return contract -} diff --git a/chain/transaction_pool.go b/chain/transaction_pool.go deleted file mode 100644 index ad89c0a98..000000000 --- a/chain/transaction_pool.go +++ /dev/null @@ -1,236 +0,0 @@ -package chain - -import ( - "bytes" - "container/list" - "fmt" - "math/big" - "sync" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/wire" -) - -var txplogger = logger.NewLogger("TXP") - -const txPoolQueueSize = 50 - -type TxPoolHook chan *types.Transaction -type TxMsgTy byte - -const ( - minGasPrice = 1000000 -) - -var MinGasPrice = big.NewInt(10000000000000) - -type TxMsg struct { - Tx *types.Transaction - Type TxMsgTy -} - -func EachTx(pool *list.List, it func(*types.Transaction, *list.Element) bool) { - for e := pool.Front(); e != nil; e = e.Next() { - if it(e.Value.(*types.Transaction), e) { - break - } - } -} - -func FindTx(pool *list.List, finder func(*types.Transaction, *list.Element) bool) *types.Transaction { - for e := pool.Front(); e != nil; e = e.Next() { - if tx, ok := e.Value.(*types.Transaction); ok { - if finder(tx, e) { - return tx - } - } - } - - return nil -} - -type TxProcessor interface { - ProcessTransaction(tx *types.Transaction) -} - -// The tx pool a thread safe transaction pool handler. In order to -// guarantee a non blocking pool we use a queue channel which can be -// independently read without needing access to the actual pool. If the -// pool is being drained or synced for whatever reason the transactions -// will simple queue up and handled when the mutex is freed. -type TxPool struct { - Ethereum EthManager - // The mutex for accessing the Tx pool. - mutex sync.Mutex - // Queueing channel for reading and writing incoming - // transactions to - queueChan chan *types.Transaction - // Quiting channel - quit chan bool - // The actual pool - pool *list.List - - SecondaryProcessor TxProcessor - - subscribers []chan TxMsg -} - -func NewTxPool(ethereum EthManager) *TxPool { - return &TxPool{ - pool: list.New(), - queueChan: make(chan *types.Transaction, txPoolQueueSize), - quit: make(chan bool), - Ethereum: ethereum, - } -} - -// Blocking function. Don't use directly. Use QueueTransaction instead -func (pool *TxPool) addTransaction(tx *types.Transaction) { - pool.mutex.Lock() - defer pool.mutex.Unlock() - - pool.pool.PushBack(tx) - - // Broadcast the transaction to the rest of the peers - pool.Ethereum.Broadcast(wire.MsgTxTy, []interface{}{tx.RlpData()}) -} - -func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { - // Get the last block so we can retrieve the sender and receiver from - // the merkle trie - block := pool.Ethereum.ChainManager().CurrentBlock - // Something has gone horribly wrong if this happens - if block == nil { - return fmt.Errorf("No last block on the block chain") - } - - if len(tx.Recipient) != 0 && len(tx.Recipient) != 20 { - return fmt.Errorf("Invalid recipient. len = %d", len(tx.Recipient)) - } - - v, _, _ := tx.Curve() - if v > 28 || v < 27 { - return fmt.Errorf("tx.v != (28 || 27)") - } - - if tx.GasPrice.Cmp(MinGasPrice) < 0 { - return fmt.Errorf("Gas price to low. Require %v > Got %v", MinGasPrice, tx.GasPrice) - } - - // Get the sender - sender := pool.Ethereum.BlockManager().CurrentState().GetAccount(tx.Sender()) - - totAmount := new(big.Int).Set(tx.Value) - // Make sure there's enough in the sender's account. Having insufficient - // funds won't invalidate this transaction but simple ignores it. - if sender.Balance().Cmp(totAmount) < 0 { - return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.Sender()) - } - - if tx.IsContract() { - if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 { - return fmt.Errorf("Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice) - } - } - - // Increment the nonce making each tx valid only once to prevent replay - // attacks - - return nil -} - -func (self *TxPool) Add(tx *types.Transaction) error { - hash := tx.Hash() - foundTx := FindTx(self.pool, func(tx *types.Transaction, e *list.Element) bool { - return bytes.Compare(tx.Hash(), hash) == 0 - }) - - if foundTx != nil { - return fmt.Errorf("Known transaction (%x)", hash[0:4]) - } - - err := self.ValidateTransaction(tx) - if err != nil { - return err - } - - self.addTransaction(tx) - - tmp := make([]byte, 4) - copy(tmp, tx.Recipient) - - txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash()) - - // Notify the subscribers - self.Ethereum.EventMux().Post(TxPreEvent{tx}) - - return nil -} - -func (pool *TxPool) CurrentTransactions() []*types.Transaction { - pool.mutex.Lock() - defer pool.mutex.Unlock() - - txList := make([]*types.Transaction, pool.pool.Len()) - i := 0 - for e := pool.pool.Front(); e != nil; e = e.Next() { - tx := e.Value.(*types.Transaction) - - txList[i] = tx - - i++ - } - - return txList -} - -func (pool *TxPool) RemoveInvalid(state *state.State) { - pool.mutex.Lock() - defer pool.mutex.Unlock() - - for e := pool.pool.Front(); e != nil; e = e.Next() { - tx := e.Value.(*types.Transaction) - sender := state.GetAccount(tx.Sender()) - err := pool.ValidateTransaction(tx) - if err != nil || sender.Nonce >= tx.Nonce { - pool.pool.Remove(e) - } - } -} - -func (self *TxPool) RemoveSet(txs types.Transactions) { - self.mutex.Lock() - defer self.mutex.Unlock() - - for _, tx := range txs { - EachTx(self.pool, func(t *types.Transaction, element *list.Element) bool { - if t == tx { - self.pool.Remove(element) - return true // To stop the loop - } - return false - }) - } -} - -func (pool *TxPool) Flush() []*types.Transaction { - txList := pool.CurrentTransactions() - - // Recreate a new list all together - // XXX Is this the fastest way? - pool.pool = list.New() - - return txList -} - -func (pool *TxPool) Start() { - //go pool.queueHandler() -} - -func (pool *TxPool) Stop() { - pool.Flush() - - txplogger.Infoln("Stopped") -} diff --git a/chain/types/block.go b/chain/types/block.go deleted file mode 100644 index feab7072f..000000000 --- a/chain/types/block.go +++ /dev/null @@ -1,413 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "math/big" - "sort" - "time" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/trie" -) - -type BlockInfo struct { - Number uint64 - Hash []byte - Parent []byte - TD *big.Int -} - -func (bi *BlockInfo) RlpDecode(data []byte) { - decoder := ethutil.NewValueFromBytes(data) - - bi.Number = decoder.Get(0).Uint() - bi.Hash = decoder.Get(1).Bytes() - bi.Parent = decoder.Get(2).Bytes() - bi.TD = decoder.Get(3).BigInt() -} - -func (bi *BlockInfo) RlpEncode() []byte { - return ethutil.Encode([]interface{}{bi.Number, bi.Hash, bi.Parent, bi.TD}) -} - -type Blocks []*Block - -func (self Blocks) AsSet() ethutil.UniqueSet { - set := make(ethutil.UniqueSet) - for _, block := range self { - set.Insert(block.Hash()) - } - - return set -} - -type BlockBy func(b1, b2 *Block) bool - -func (self BlockBy) Sort(blocks Blocks) { - bs := blockSorter{ - blocks: blocks, - by: self, - } - sort.Sort(bs) -} - -type blockSorter struct { - blocks Blocks - by func(b1, b2 *Block) bool -} - -func (self blockSorter) Len() int { return len(self.blocks) } -func (self blockSorter) Swap(i, j int) { - self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i] -} -func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) } - -func Number(b1, b2 *Block) bool { return b1.Number.Cmp(b2.Number) < 0 } - -type Block struct { - // Hash to the previous block - PrevHash ethutil.Bytes - // Uncles of this block - Uncles Blocks - UncleSha []byte - // The coin base address - Coinbase []byte - // Block Trie state - //state *ethutil.Trie - state *state.State - // Difficulty for the current block - Difficulty *big.Int - // Creation time - Time int64 - // The block number - Number *big.Int - // Gas limit - GasLimit *big.Int - // Gas used - GasUsed *big.Int - // Extra data - Extra string - // Block Nonce for verification - Nonce ethutil.Bytes - // List of transactions and/or contracts - transactions Transactions - receipts Receipts - TxSha, ReceiptSha []byte - LogsBloom []byte - - Reward *big.Int -} - -func NewBlockFromBytes(raw []byte) *Block { - block := &Block{} - block.RlpDecode(raw) - - return block -} - -// New block takes a raw encoded string -func NewBlockFromRlpValue(rlpValue *ethutil.Value) *Block { - block := &Block{} - block.RlpValueDecode(rlpValue) - - return block -} - -func CreateBlock(root interface{}, - prevHash []byte, - base []byte, - Difficulty *big.Int, - Nonce []byte, - extra string) *Block { - - block := &Block{ - PrevHash: prevHash, - Coinbase: base, - Difficulty: Difficulty, - Nonce: Nonce, - Time: time.Now().Unix(), - Extra: extra, - UncleSha: nil, - GasUsed: new(big.Int), - GasLimit: new(big.Int), - } - block.SetUncles([]*Block{}) - - block.state = state.New(trie.New(ethutil.Config.Db, root)) - - return block -} - -// Returns a hash of the block -func (block *Block) Hash() ethutil.Bytes { - return crypto.Sha3(ethutil.NewValue(block.header()).Encode()) - //return crypto.Sha3(block.Value().Encode()) -} - -func (block *Block) HashNoNonce() []byte { - return crypto.Sha3(ethutil.Encode(block.miningHeader())) -} - -func (block *Block) State() *state.State { - return block.state -} - -func (block *Block) Transactions() Transactions { - return block.transactions -} - -func (block *Block) CalcGasLimit(parent *Block) *big.Int { - if block.Number.Cmp(big.NewInt(0)) == 0 { - return ethutil.BigPow(10, 6) - } - - // ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024 - - previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit) - current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed), big.NewRat(6, 5)) - curInt := new(big.Int).Div(current.Num(), current.Denom()) - - result := new(big.Int).Add(previous, curInt) - result.Div(result, big.NewInt(1024)) - - min := big.NewInt(125000) - - return ethutil.BigMax(min, result) -} - -func (block *Block) BlockInfo() BlockInfo { - bi := BlockInfo{} - data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...)) - bi.RlpDecode(data) - - return bi -} - -func (self *Block) GetTransaction(hash []byte) *Transaction { - for _, tx := range self.transactions { - if bytes.Compare(tx.Hash(), hash) == 0 { - return tx - } - } - - return nil -} - -// Sync the block's state and contract respectively -func (block *Block) Sync() { - block.state.Sync() -} - -func (block *Block) Undo() { - // Sync the block state itself - block.state.Reset() -} - -/////// Block Encoding -func (block *Block) rlpReceipts() interface{} { - // Marshal the transactions of this block - encR := make([]interface{}, len(block.receipts)) - for i, r := range block.receipts { - // Cast it to a string (safe) - encR[i] = r.RlpData() - } - - return encR -} - -func (block *Block) rlpUncles() interface{} { - // Marshal the transactions of this block - uncles := make([]interface{}, len(block.Uncles)) - for i, uncle := range block.Uncles { - // Cast it to a string (safe) - uncles[i] = uncle.header() - } - - return uncles -} - -func (block *Block) SetUncles(uncles []*Block) { - block.Uncles = uncles - block.UncleSha = crypto.Sha3(ethutil.Encode(block.rlpUncles())) -} - -func (self *Block) SetReceipts(receipts Receipts) { - self.receipts = receipts - self.ReceiptSha = DeriveSha(receipts) - self.LogsBloom = CreateBloom(receipts) -} - -func (self *Block) SetTransactions(txs Transactions) { - self.transactions = txs - self.TxSha = DeriveSha(txs) -} - -func (block *Block) Value() *ethutil.Value { - return ethutil.NewValue([]interface{}{block.header(), block.transactions, block.rlpUncles()}) -} - -func (block *Block) RlpEncode() []byte { - // Encode a slice interface which contains the header and the list of - // transactions. - return block.Value().Encode() -} - -func (block *Block) RlpDecode(data []byte) { - rlpValue := ethutil.NewValueFromBytes(data) - block.RlpValueDecode(rlpValue) -} - -func (block *Block) RlpValueDecode(decoder *ethutil.Value) { - block.setHeader(decoder.Get(0)) - - // Tx list might be empty if this is an uncle. Uncles only have their - // header set. - if decoder.Get(1).IsNil() == false { // Yes explicitness - //receipts := decoder.Get(1) - //block.receipts = make([]*Receipt, receipts.Len()) - txs := decoder.Get(1) - block.transactions = make(Transactions, txs.Len()) - for i := 0; i < txs.Len(); i++ { - block.transactions[i] = NewTransactionFromValue(txs.Get(i)) - //receipt := NewRecieptFromValue(receipts.Get(i)) - //block.transactions[i] = receipt.Tx - //block.receipts[i] = receipt - } - - } - - if decoder.Get(2).IsNil() == false { // Yes explicitness - uncles := decoder.Get(2) - block.Uncles = make([]*Block, uncles.Len()) - for i := 0; i < uncles.Len(); i++ { - block.Uncles[i] = NewUncleBlockFromValue(uncles.Get(i)) - } - } - -} - -func (self *Block) setHeader(header *ethutil.Value) { - self.PrevHash = header.Get(0).Bytes() - self.UncleSha = header.Get(1).Bytes() - self.Coinbase = header.Get(2).Bytes() - self.state = state.New(trie.New(ethutil.Config.Db, header.Get(3).Val)) - self.TxSha = header.Get(4).Bytes() - self.ReceiptSha = header.Get(5).Bytes() - self.LogsBloom = header.Get(6).Bytes() - self.Difficulty = header.Get(7).BigInt() - self.Number = header.Get(8).BigInt() - self.GasLimit = header.Get(9).BigInt() - self.GasUsed = header.Get(10).BigInt() - self.Time = int64(header.Get(11).BigInt().Uint64()) - self.Extra = header.Get(12).Str() - self.Nonce = header.Get(13).Bytes() -} - -func NewUncleBlockFromValue(header *ethutil.Value) *Block { - block := &Block{} - block.setHeader(header) - - return block -} - -func (block *Block) Trie() *trie.Trie { - return block.state.Trie -} - -func (block *Block) Root() interface{} { - return block.state.Root() -} - -func (block *Block) Diff() *big.Int { - return block.Difficulty -} - -func (self *Block) Receipts() []*Receipt { - return self.receipts -} - -func (block *Block) miningHeader() []interface{} { - return []interface{}{ - // Sha of the previous block - block.PrevHash, - // Sha of uncles - block.UncleSha, - // Coinbase address - block.Coinbase, - // root state - block.Root(), - // tx root - block.TxSha, - // Sha of tx - block.ReceiptSha, - // Bloom - block.LogsBloom, - // Current block Difficulty - block.Difficulty, - // The block number - block.Number, - // Block upper gas bound - block.GasLimit, - // Block gas used - block.GasUsed, - // Time the block was found? - block.Time, - // Extra data - block.Extra, - } -} - -func (block *Block) header() []interface{} { - return append(block.miningHeader(), block.Nonce) -} - -func (block *Block) String() string { - return fmt.Sprintf(` - BLOCK(%x): Size: %v - PrevHash: %x - UncleSha: %x - Coinbase: %x - Root: %x - TxSha %x - ReceiptSha: %x - Bloom: %x - Difficulty: %v - Number: %v - MaxLimit: %v - GasUsed: %v - Time: %v - Extra: %v - Nonce: %x - NumTx: %v -`, - block.Hash(), - block.Size(), - block.PrevHash, - block.UncleSha, - block.Coinbase, - block.Root(), - block.TxSha, - block.ReceiptSha, - block.LogsBloom, - block.Difficulty, - block.Number, - block.GasLimit, - block.GasUsed, - block.Time, - block.Extra, - block.Nonce, - len(block.transactions), - ) -} - -func (self *Block) Size() ethutil.StorageSize { - return ethutil.StorageSize(len(self.RlpEncode())) -} - -// Implement RlpEncodable -func (self *Block) RlpData() interface{} { - return self.Value().Val -} diff --git a/chain/types/bloom9.go b/chain/types/bloom9.go deleted file mode 100644 index 77aa6eef5..000000000 --- a/chain/types/bloom9.go +++ /dev/null @@ -1,56 +0,0 @@ -package types - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" -) - -func CreateBloom(receipts Receipts) []byte { - bin := new(big.Int) - for _, receipt := range receipts { - bin.Or(bin, LogsBloom(receipt.logs)) - } - - return ethutil.LeftPadBytes(bin.Bytes(), 64) -} - -func LogsBloom(logs state.Logs) *big.Int { - bin := new(big.Int) - for _, log := range logs { - data := [][]byte{log.Address} - for _, topic := range log.Topics { - data = append(data, topic) - } - - for _, b := range data { - bin.Or(bin, ethutil.BigD(bloom9(crypto.Sha3(b)).Bytes())) - } - - //if log.Data != nil { - // data = append(data, log.Data) - //} - } - - return bin -} - -func bloom9(b []byte) *big.Int { - r := new(big.Int) - for _, i := range []int{0, 2, 4} { - t := big.NewInt(1) - b := uint(b[i+1]) + 256*(uint(b[i])&1) - r.Or(r, t.Lsh(t, b)) - } - - return r -} - -func BloomLookup(bin, topic []byte) bool { - bloom := ethutil.BigD(bin) - cmp := bloom9(crypto.Sha3(topic)) - - return bloom.And(bloom, cmp).Cmp(cmp) == 0 -} diff --git a/chain/types/bloom9_test.go b/chain/types/bloom9_test.go deleted file mode 100644 index 74e00cac6..000000000 --- a/chain/types/bloom9_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package types - -/* -import ( - "testing" - - "github.com/ethereum/go-ethereum/state" -) - -func TestBloom9(t *testing.T) { - testCase := []byte("testtest") - bin := LogsBloom([]state.Log{ - {testCase, [][]byte{[]byte("hellohello")}, nil}, - }).Bytes() - res := BloomLookup(bin, testCase) - - if !res { - t.Errorf("Bloom lookup failed") - } -} - - -func TestAddress(t *testing.T) { - block := &Block{} - block.Coinbase = ethutil.Hex2Bytes("22341ae42d6dd7384bc8584e50419ea3ac75b83f") - fmt.Printf("%x\n", crypto.Sha3(block.Coinbase)) - - bin := CreateBloom(block) - fmt.Printf("bin = %x\n", ethutil.LeftPadBytes(bin, 64)) -} -*/ diff --git a/chain/types/common.go b/chain/types/common.go deleted file mode 100644 index ba88b77e1..000000000 --- a/chain/types/common.go +++ /dev/null @@ -1,11 +0,0 @@ -package types - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/state" -) - -type BlockProcessor interface { - Process(*Block) (*big.Int, state.Messages, error) -} diff --git a/chain/types/derive_sha.go b/chain/types/derive_sha.go deleted file mode 100644 index 1897ff198..000000000 --- a/chain/types/derive_sha.go +++ /dev/null @@ -1,20 +0,0 @@ -package types - -import ( - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/trie" -) - -type DerivableList interface { - Len() int - GetRlp(i int) []byte -} - -func DeriveSha(list DerivableList) []byte { - trie := trie.New(ethutil.Config.Db, "") - for i := 0; i < list.Len(); i++ { - trie.Update(string(ethutil.NewValue(i).Encode()), string(list.GetRlp(i))) - } - - return trie.GetRoot() -} diff --git a/chain/types/receipt.go b/chain/types/receipt.go deleted file mode 100644 index 25fa8fb07..000000000 --- a/chain/types/receipt.go +++ /dev/null @@ -1,68 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" -) - -type Receipt struct { - PostState []byte - CumulativeGasUsed *big.Int - Bloom []byte - 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 { - r := &Receipt{} - r.RlpValueDecode(val) - - return r -} - -func (self *Receipt) SetLogs(logs state.Logs) { - self.logs = logs -} - -func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) { - self.PostState = decoder.Get(0).Bytes() - self.CumulativeGasUsed = decoder.Get(1).BigInt() - self.Bloom = decoder.Get(2).Bytes() - - it := decoder.Get(3).NewIterator() - for it.Next() { - self.logs = append(self.logs, state.NewLogFromValue(it.Value())) - } -} - -func (self *Receipt) RlpData() interface{} { - return []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs.RlpData()} -} - -func (self *Receipt) RlpEncode() []byte { - return ethutil.Encode(self.RlpData()) -} - -func (self *Receipt) Cmp(other *Receipt) bool { - if bytes.Compare(self.PostState, other.PostState) != 0 { - return false - } - - return true -} - -func (self *Receipt) String() string { - return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs) -} - -type Receipts []*Receipt - -func (self Receipts) Len() int { return len(self) } -func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) } diff --git a/chain/types/transaction.go b/chain/types/transaction.go deleted file mode 100644 index efc90b6f2..000000000 --- a/chain/types/transaction.go +++ /dev/null @@ -1,225 +0,0 @@ -package types - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" - "github.com/obscuren/secp256k1-go" -) - -var ContractAddr = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - -func IsContractAddr(addr []byte) bool { - return len(addr) == 0 - //return bytes.Compare(addr, ContractAddr) == 0 -} - -type Transaction struct { - Nonce uint64 - Recipient []byte - Value *big.Int - Gas *big.Int - GasPrice *big.Int - Data []byte - v byte - r, s []byte - - // Indicates whether this tx is a contract creation transaction - contractCreation bool -} - -func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction { - return &Transaction{Recipient: nil, Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true} -} - -func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction { - return &Transaction{Recipient: to, Value: value, GasPrice: gasPrice, Gas: gas, Data: data, contractCreation: IsContractAddr(to)} -} - -func NewTransactionFromBytes(data []byte) *Transaction { - tx := &Transaction{} - tx.RlpDecode(data) - - return tx -} - -func NewTransactionFromValue(val *ethutil.Value) *Transaction { - tx := &Transaction{} - tx.RlpValueDecode(val) - - return tx -} - -func (self *Transaction) GasValue() *big.Int { - return new(big.Int).Mul(self.Gas, self.GasPrice) -} - -func (self *Transaction) TotalValue() *big.Int { - v := self.GasValue() - return v.Add(v, self.Value) -} - -func (tx *Transaction) Hash() []byte { - data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data} - - return crypto.Sha3(ethutil.NewValue(data).Encode()) -} - -func (tx *Transaction) CreatesContract() bool { - return tx.contractCreation -} - -/* Deprecated */ -func (tx *Transaction) IsContract() bool { - return tx.CreatesContract() -} - -func (tx *Transaction) CreationAddress(state *state.State) []byte { - // Generate a new address - return crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:] -} - -func (tx *Transaction) Curve() (v byte, r []byte, s []byte) { - v = tx.v - r = ethutil.LeftPadBytes(tx.r, 32) - s = ethutil.LeftPadBytes(tx.s, 32) - - return -} - -func (tx *Transaction) Signature(key []byte) []byte { - hash := tx.Hash() - - sig, _ := secp256k1.Sign(hash, key) - - return sig -} - -func (tx *Transaction) PublicKey() []byte { - hash := tx.Hash() - - v, r, s := tx.Curve() - - sig := append(r, s...) - sig = append(sig, v-27) - - pubkey := crypto.Ecrecover(append(hash, sig...)) - //pubkey, _ := secp256k1.RecoverPubkey(hash, sig) - - return pubkey -} - -func (tx *Transaction) Sender() []byte { - pubkey := tx.PublicKey() - - // Validate the returned key. - // Return nil if public key isn't in full format - if len(pubkey) != 0 && pubkey[0] != 4 { - return nil - } - - return crypto.Sha3(pubkey[1:])[12:] -} - -func (tx *Transaction) Sign(privk []byte) error { - - sig := tx.Signature(privk) - - tx.r = sig[:32] - tx.s = sig[32:64] - tx.v = sig[64] + 27 - - return nil -} - -func (tx *Transaction) RlpData() interface{} { - data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data} - - // TODO Remove prefixing zero's - - return append(data, tx.v, new(big.Int).SetBytes(tx.r).Bytes(), new(big.Int).SetBytes(tx.s).Bytes()) -} - -func (tx *Transaction) RlpValue() *ethutil.Value { - return ethutil.NewValue(tx.RlpData()) -} - -func (tx *Transaction) RlpEncode() []byte { - return tx.RlpValue().Encode() -} - -func (tx *Transaction) RlpDecode(data []byte) { - tx.RlpValueDecode(ethutil.NewValueFromBytes(data)) -} - -func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) { - tx.Nonce = decoder.Get(0).Uint() - tx.GasPrice = decoder.Get(1).BigInt() - tx.Gas = decoder.Get(2).BigInt() - tx.Recipient = decoder.Get(3).Bytes() - tx.Value = decoder.Get(4).BigInt() - tx.Data = decoder.Get(5).Bytes() - tx.v = byte(decoder.Get(6).Uint()) - - tx.r = decoder.Get(7).Bytes() - tx.s = decoder.Get(8).Bytes() - - if IsContractAddr(tx.Recipient) { - tx.contractCreation = true - } -} - -func (tx *Transaction) String() string { - return fmt.Sprintf(` - TX(%x) - Contract: %v - From: %x - To: %x - Nonce: %v - GasPrice: %v - Gas: %v - Value: %v - Data: 0x%x - V: 0x%x - R: 0x%x - S: 0x%x - `, - tx.Hash(), - len(tx.Recipient) == 0, - tx.Sender(), - tx.Recipient, - tx.Nonce, - tx.GasPrice, - tx.Gas, - tx.Value, - tx.Data, - tx.v, - tx.r, - tx.s) -} - -// Transaction slice type for basic sorting -type Transactions []*Transaction - -func (self Transactions) RlpData() interface{} { - // Marshal the transactions of this block - enc := make([]interface{}, len(self)) - for i, tx := range self { - // Cast it to a string (safe) - enc[i] = tx.RlpData() - } - - return enc -} -func (s Transactions) Len() int { return len(s) } -func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) } - -type TxByNonce struct{ Transactions } - -func (s TxByNonce) Less(i, j int) bool { - return s.Transactions[i].Nonce < s.Transactions[j].Nonce -} diff --git a/chain/types/transaction_test.go b/chain/types/transaction_test.go deleted file mode 100644 index ab1254f4c..000000000 --- a/chain/types/transaction_test.go +++ /dev/null @@ -1 +0,0 @@ -package types diff --git a/chain/vm_env.go b/chain/vm_env.go deleted file mode 100644 index c2428c234..000000000 --- a/chain/vm_env.go +++ /dev/null @@ -1,63 +0,0 @@ -package chain - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/chain/types" - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/vm" -) - -type VMEnv struct { - state *state.State - block *types.Block - tx *types.Transaction - depth int -} - -func NewEnv(state *state.State, tx *types.Transaction, block *types.Block) *VMEnv { - return &VMEnv{ - state: state, - block: block, - tx: tx, - } -} - -func (self *VMEnv) Origin() []byte { return self.tx.Sender() } -func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number } -func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash } -func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase } -func (self *VMEnv) Time() int64 { return self.block.Time } -func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty } -func (self *VMEnv) BlockHash() []byte { return self.block.Hash() } -func (self *VMEnv) Value() *big.Int { return self.tx.Value } -func (self *VMEnv) State() *state.State { return self.state } -func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit } -func (self *VMEnv) Depth() int { return self.depth } -func (self *VMEnv) SetDepth(i int) { self.depth = i } -func (self *VMEnv) AddLog(log *state.Log) { - self.state.AddLog(log) -} -func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { - return vm.Transfer(from, to, amount) -} - -func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *Execution { - evm := vm.New(self, vm.DebugVmTy) - - return NewExecution(evm, addr, data, gas, price, value) -} - -func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { - exe := self.vm(addr, data, gas, price, value) - return exe.Call(addr, me) -} -func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { - exe := self.vm(me.Address(), data, gas, price, value) - return exe.Call(addr, me) -} - -func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) { - exe := self.vm(addr, data, gas, price, value) - return exe.Create(me) -} |