From d5efeab8f92509dec3cafcafb36e1856bb084f12 Mon Sep 17 00:00:00 2001 From: Maran Date: Mon, 10 Mar 2014 11:53:02 +0100 Subject: Initial smart-miner stuff --- ethchain/block_chain.go | 1 + ethchain/dagger.go | 24 ++++++++++++++++-------- ethchain/state_manager.go | 15 +++++++++++++++ ethchain/transaction_pool.go | 8 +++++++- ethereum.go | 8 ++++++++ 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 2865e0a21..93970a2c5 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -136,6 +136,7 @@ func AddTestNetFunds(block *Block) { "e6716f9544a56c530d868e4bfbacb172315bdead", // Jeffrey "1e12515ce3e0f817a4ddef9ca55788a1d66bd2df", // Vit "1a26338f0d905e295fccb71fa9ea849ffa12aaf4", // Alex + "2ef47100e0787b915105fd5e3f4ff6752079d5cb", // Maran } { //log.Println("2^200 Wei to", addr) codedAddr := ethutil.FromHex(addr) diff --git a/ethchain/dagger.go b/ethchain/dagger.go index 5b4f8b2cd..c33b3c14e 100644 --- a/ethchain/dagger.go +++ b/ethchain/dagger.go @@ -11,7 +11,7 @@ import ( ) type PoW interface { - Search(block *Block) []byte + Search(block *Block, breakChan chan bool) []byte Verify(hash []byte, diff *big.Int, nonce []byte) bool } @@ -19,15 +19,23 @@ type EasyPow struct { hash *big.Int } -func (pow *EasyPow) Search(block *Block) []byte { +func (pow *EasyPow) Search(block *Block, breakChan chan bool) []byte { r := rand.New(rand.NewSource(time.Now().UnixNano())) - hash := block.HashNoNonce() diff := block.Difficulty + for { - sha := ethutil.Sha3Bin(big.NewInt(r.Int63()).Bytes()) - if pow.Verify(hash, diff, sha) { - return sha + select { + case shouldbreak := <-breakChan: + if shouldbreak { + log.Println("Got signal: Breaking out mining.") + return nil + } + default: + sha := ethutil.Sha3Bin(big.NewInt(r.Int63()).Bytes()) + if pow.Verify(hash, diff, sha) { + return sha + } } } @@ -98,9 +106,9 @@ func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { for k := 0; k < amountOfRoutines; k++ { go dag.Find(obj, resChan) - } - // Wait for each go routine to finish + // 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 { diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 7085146df..2652f3f29 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -19,6 +19,7 @@ type EthManager interface { BlockChain() *BlockChain TxPool() *TxPool Broadcast(msgType ethwire.MsgType, data []interface{}) + Reactor() *ethutil.ReactorEngine } // TODO rename to state manager @@ -50,6 +51,9 @@ type StateManager struct { // Comparative state it used for comparing and validating end // results compState *State + + // Mining state, solely used for mining + miningState *State } func NewStateManager(ethereum EthManager) *StateManager { @@ -69,6 +73,10 @@ func (sm *StateManager) ProcState() *State { return sm.procState } +func (sm *StateManager) MiningState() *State { + return sm.miningState +} + // Watches any given address and puts it in the address state store func (sm *StateManager) WatchAddr(addr []byte) *AccountState { //FIXME account := sm.procState.GetAccount(addr) @@ -97,6 +105,8 @@ func (sm *StateManager) MakeContract(tx *Transaction) { sm.procState.states[string(tx.Hash()[12:])] = contract.state } } +func (sm *StateManager) ApplyTransaction(block *Block, tx *Transaction) { +} func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) { // Process each transaction/contract @@ -126,6 +136,10 @@ func (sm *StateManager) Prepare(processer *State, comparative *State) { sm.procState = processer } +func (sm *StateManager) PrepareMiningState() { + sm.miningState = sm.BlockChain().CurrentBlock.State() +} + // Default prepare function func (sm *StateManager) PrepareDefault(block *Block) { sm.Prepare(sm.BlockChain().CurrentBlock.State(), block.State()) @@ -193,6 +207,7 @@ func (sm *StateManager) ProcessBlock(block *Block) error { } ethutil.Config.Log.Infof("[smGR] Added block #%d (%x)\n", block.BlockInfo().Number, block.Hash()) + sm.Ethereum.Reactor().Post("newBlock", block) } else { fmt.Println("total diff failed") } diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go index 2c9a26936..345764d09 100644 --- a/ethchain/transaction_pool.go +++ b/ethchain/transaction_pool.go @@ -91,6 +91,7 @@ func (pool *TxPool) addTransaction(tx *Transaction) { // Process transaction validates the Tx and processes funds from the // sender to the recipient. func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block) (err error) { + log.Println("Processing TX") defer func() { if r := recover(); r != nil { log.Println(r) @@ -137,7 +138,6 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block) (err error log.Printf("[TXPL] Processed Tx %x\n", tx.Hash()) - // Notify the subscribers pool.notifySubscribers(TxPost, tx) return @@ -174,6 +174,7 @@ out: for { select { case tx := <-pool.queueChan: + log.Println("Received new Tx to queue") hash := tx.Hash() foundTx := FindTx(pool.pool, func(tx *Transaction, e *list.Element) bool { return bytes.Compare(tx.Hash(), hash) == 0 @@ -190,9 +191,14 @@ out: log.Println("Validating Tx failed", err) } } else { + log.Println("Transaction ok, adding") // Call blocking version. At this point it // doesn't matter since this is a goroutine pool.addTransaction(tx) + log.Println("Added") + + // Notify the subscribers + pool.Ethereum.Reactor().Post("newTx", tx) // Notify the subscribers pool.notifySubscribers(TxPre, tx) diff --git a/ethereum.go b/ethereum.go index 342f4f573..302f3c04f 100644 --- a/ethereum.go +++ b/ethereum.go @@ -60,6 +60,8 @@ type Ethereum struct { // Specifies the desired amount of maximum peers MaxPeers int + + reactor *ethutil.ReactorEngine } func New(caps Caps, usePnp bool) (*Ethereum, error) { @@ -89,6 +91,8 @@ func New(caps Caps, usePnp bool) (*Ethereum, error) { serverCaps: caps, nat: nat, } + ethereum.reactor = ethutil.NewReactorEngine() + ethereum.txPool = ethchain.NewTxPool(ethereum) ethereum.blockChain = ethchain.NewBlockChain(ethereum) ethereum.stateManager = ethchain.NewStateManager(ethereum) @@ -99,6 +103,10 @@ func New(caps Caps, usePnp bool) (*Ethereum, error) { return ethereum, nil } +func (s *Ethereum) Reactor() *ethutil.ReactorEngine { + return s.reactor +} + func (s *Ethereum) BlockChain() *ethchain.BlockChain { return s.blockChain } -- cgit