From e7770b2332067ab0492fe46374713dbdf4ea1ac0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 6 Mar 2014 13:06:54 +0100 Subject: [PATCH 1/9] Added miner state --- ethchain/state_manager.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 7085146dfb..0923b017e5 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -21,7 +21,6 @@ type EthManager interface { Broadcast(msgType ethwire.MsgType, data []interface{}) } -// TODO rename to state manager type StateManager struct { // Mutex for locking the block processor. Blocks can only be handled one at a time mutex sync.Mutex @@ -50,6 +49,8 @@ type StateManager struct { // Comparative state it used for comparing and validating end // results compState *State + + miningState *State } func NewStateManager(ethereum EthManager) *StateManager { From f80984491a503f2e6cc0b5845744e943854ecade Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 6 Mar 2014 13:09:55 +0100 Subject: [PATCH 2/9] Removed comments --- ethutil/trie.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/ethutil/trie.go b/ethutil/trie.go index a17dc37ad9..c67f750bc7 100644 --- a/ethutil/trie.go +++ b/ethutil/trie.go @@ -219,18 +219,6 @@ func (t *Trie) UpdateState(node interface{}, key []int, value string) interface{ } func (t *Trie) Put(node interface{}) interface{} { - /* - enc := Encode(node) - if len(enc) >= 32 { - var sha []byte - sha = Sha3Bin(enc) - //t.db.Put([]byte(sha), enc) - - return sha - } - return node - */ - /* TODO? c := Conv(t.Root) From ea873304cad4b6a9f02a6686df44da8364304905 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 6 Mar 2014 13:10:39 +0100 Subject: [PATCH 3/9] No longer dev --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f6c49cc2dc..3553a5e351 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Ethereum Ethereum Go Development package (C) Jeffrey Wilcke Ethereum is currently in its testing phase. The current state is "Proof -of Concept 2". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). +of Concept 3". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)). Ethereum Go is split up in several sub packages Please refer to each individual package for more information. @@ -35,7 +35,7 @@ get a node and connectivity going. Build ======= -This is the Developer package. For the development client please see +This is the Developer package. For the Ethereal client please see [Ethereum(G)](https://github.com/ethereum/go-ethereum). `go get -u github.com/ethereum/eth-go` From 8162aff8cfb76bf53dd06a19cf12208f7946349d Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Thu, 6 Mar 2014 19:01:38 +0100 Subject: [PATCH 4/9] Add DNS Bootstrapping --- ethereum.go | 53 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/ethereum.go b/ethereum.go index 342f4f573e..4dd29f2e66 100644 --- a/ethereum.go +++ b/ethereum.go @@ -262,21 +262,46 @@ func (s *Ethereum) Start() { go s.ReapDeadPeerHandler() if ethutil.Config.Seed { - ethutil.Config.Log.Debugln("Seeding") - // Testnet seed bootstrapping - resp, err := http.Get("https://www.ethereum.org/servers.poc3.txt") - if err != nil { - log.Println("Fetching seed failed:", err) - return - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Println("Reading seed failed:", err) - return - } + ethutil.Config.Log.Debugln("Seeding") + // DNS Bootstrapping + _, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org") + if(err == nil) { + peers := []string{} + // Iterate SRV nodes + for _, n := range nodes { + target := n.Target + port := n.Port + // Resolve target to ip (Go returns list, so may resolve to multiple ips?) + addr, err := net.LookupHost(target) + if(err == nil) { + for _, a := range addr { + // Build string out of SRV port and Resolved IP + peer := net.JoinHostPort(a, strconv.Itoa(int(port))) + log.Println("Found DNS Bootstrap Peer:", peer) + peers = append(peers, peer) + } + } else { + log.Println("Couldn't resolve :", target) + } + } + // Connect to Peer list + s.ProcessPeerList(peers) + } else { + // Fallback to servers.poc3.txt + resp, err := http.Get("http://www.ethereum.org/servers.poc3.txt") + if err != nil { + log.Println("Fetching seed failed:", err) + return + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println("Reading seed failed:", err) + return + } - s.ConnectToPeer(string(body)) + s.ConnectToPeer(string(body)) + } } } From e2e338929f8c1fb0bc424d0f5ca3353c6f36ec77 Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Thu, 6 Mar 2014 19:03:26 +0100 Subject: [PATCH 5/9] Fix Whitespace --- ethereum.go | 74 ++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/ethereum.go b/ethereum.go index 4dd29f2e66..6c19a13f97 100644 --- a/ethereum.go +++ b/ethereum.go @@ -262,46 +262,46 @@ func (s *Ethereum) Start() { go s.ReapDeadPeerHandler() if ethutil.Config.Seed { - ethutil.Config.Log.Debugln("Seeding") - // DNS Bootstrapping - _, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org") - if(err == nil) { - peers := []string{} - // Iterate SRV nodes - for _, n := range nodes { - target := n.Target - port := n.Port - // Resolve target to ip (Go returns list, so may resolve to multiple ips?) - addr, err := net.LookupHost(target) - if(err == nil) { - for _, a := range addr { - // Build string out of SRV port and Resolved IP - peer := net.JoinHostPort(a, strconv.Itoa(int(port))) - log.Println("Found DNS Bootstrap Peer:", peer) - peers = append(peers, peer) - } - } else { - log.Println("Couldn't resolve :", target) + ethutil.Config.Log.Debugln("Seeding") + // DNS Bootstrapping + _, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org") + if(err == nil) { + peers := []string{} + // Iterate SRV nodes + for _, n := range nodes { + target := n.Target + port := n.Port + // Resolve target to ip (Go returns list, so may resolve to multiple ips?) + addr, err := net.LookupHost(target) + if(err == nil) { + for _, a := range addr { + // Build string out of SRV port and Resolved IP + peer := net.JoinHostPort(a, strconv.Itoa(int(port))) + log.Println("Found DNS Bootstrap Peer:", peer) + peers = append(peers, peer) } + } else { + log.Println("Couldn't resolve :", target) } - // Connect to Peer list - s.ProcessPeerList(peers) - } else { - // Fallback to servers.poc3.txt - resp, err := http.Get("http://www.ethereum.org/servers.poc3.txt") - if err != nil { - log.Println("Fetching seed failed:", err) - return - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Println("Reading seed failed:", err) - return - } - - s.ConnectToPeer(string(body)) } + // Connect to Peer list + s.ProcessPeerList(peers) + } else { + // Fallback to servers.poc3.txt + resp, err := http.Get("http://www.ethereum.org/servers.poc3.txt") + if err != nil { + log.Println("Fetching seed failed:", err) + return + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println("Reading seed failed:", err) + return + } + + s.ConnectToPeer(string(body)) + } } } From 9d887234eafb5884df9b2a90e3cb876688af0c21 Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Thu, 6 Mar 2014 19:11:38 +0100 Subject: [PATCH 6/9] Small Optimization on port --- ethereum.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethereum.go b/ethereum.go index 6c19a13f97..795f2cd527 100644 --- a/ethereum.go +++ b/ethereum.go @@ -270,13 +270,13 @@ func (s *Ethereum) Start() { // Iterate SRV nodes for _, n := range nodes { target := n.Target - port := n.Port + port := strconv.Itoa(int(n.Port)) // Resolve target to ip (Go returns list, so may resolve to multiple ips?) addr, err := net.LookupHost(target) if(err == nil) { for _, a := range addr { // Build string out of SRV port and Resolved IP - peer := net.JoinHostPort(a, strconv.Itoa(int(port))) + peer := net.JoinHostPort(a, port) log.Println("Found DNS Bootstrap Peer:", peer) peers = append(peers, peer) } From 694ef4704176c4c2329b56e4cd5320f558513efb Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Fri, 7 Mar 2014 11:11:11 +0100 Subject: [PATCH 7/9] gofmt -w ethereum.go --- ethereum.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ethereum.go b/ethereum.go index 795f2cd527..fb97c34b1a 100644 --- a/ethereum.go +++ b/ethereum.go @@ -264,8 +264,8 @@ func (s *Ethereum) Start() { if ethutil.Config.Seed { ethutil.Config.Log.Debugln("Seeding") // DNS Bootstrapping - _, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org") - if(err == nil) { + _, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org") + if err == nil { peers := []string{} // Iterate SRV nodes for _, n := range nodes { @@ -273,7 +273,7 @@ func (s *Ethereum) Start() { port := strconv.Itoa(int(n.Port)) // Resolve target to ip (Go returns list, so may resolve to multiple ips?) addr, err := net.LookupHost(target) - if(err == nil) { + if err == nil { for _, a := range addr { // Build string out of SRV port and Resolved IP peer := net.JoinHostPort(a, port) From 685ea3e9a944cc982bf5afc5b3e29c935a6e4c0b Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 7 Mar 2014 11:26:35 +0100 Subject: [PATCH 8/9] Wip keychains --- ethchain/keypair.go | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 ethchain/keypair.go diff --git a/ethchain/keypair.go b/ethchain/keypair.go new file mode 100644 index 0000000000..9fdc95972b --- /dev/null +++ b/ethchain/keypair.go @@ -0,0 +1,74 @@ +package ethchain + +import ( + "github.com/ethereum/eth-go/ethutil" + "math/big" +) + +type KeyPair struct { + PrivateKey []byte + PublicKey []byte + + // The associated account + account *Account + state *State +} + +func NewKeyPairFromValue(val *ethutil.Value) *KeyPair { + keyPair := &KeyPair{PrivateKey: val.Get(0).Bytes(), PublicKey: val.Get(1).Bytes()} + + return keyPair +} + +func (k *KeyPair) Address() []byte { + return ethutil.Sha3Bin(k.PublicKey[1:])[12:] +} + +func (k *KeyPair) Account() *Account { + if k.account == nil { + k.account = k.state.GetAccount(k.Address()) + } + + return k.account +} + +// Create transaction, creates a new and signed transaction, ready for processing +func (k *KeyPair) CreateTx(receiver []byte, value *big.Int, data []string) *Transaction { + tx := NewTransaction(receiver, value, data) + tx.Nonce = k.account.Nonce + + // Sign the transaction with the private key in this key chain + tx.Sign(k.PrivateKey) + + return tx +} + +func (k *KeyPair) RlpEncode() []byte { + return ethutil.EmptyValue().Append(k.PrivateKey).Append(k.PublicKey).Encode() +} + +type KeyRing struct { + keys []*KeyPair +} + +func (k *KeyRing) Add(pair *KeyPair) { + k.keys = append(k.keys, pair) +} + +// The public "singleton" keyring +var keyRing *KeyRing + +func GetKeyRing(state *State) *KeyRing { + if keyRing == nil { + keyRing = &KeyRing{} + + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + it := ethutil.NewValueFromBytes(data).NewIterator() + for it.Next() { + v := it.Value() + keyRing.Add(NewKeyPairFromValue(v)) + } + } + + return keyRing +} From b15a4985e89b1fbf67731bde2e4cef45b3fdf347 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 17 Mar 2014 10:33:03 +0100 Subject: [PATCH 9/9] Moved on to the state manager --- ethchain/state_manager.go | 49 ++++++++++++++++++------------------ ethchain/transaction_pool.go | 4 +-- peer.go | 3 ++- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 0923b017e5..c2a31ff6c8 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -62,6 +62,7 @@ func NewStateManager(ethereum EthManager) *StateManager { addrStateStore: NewAddrStateStore(), bc: ethereum.BlockChain(), } + sm.procState = ethereum.BlockChain().CurrentBlock.State() return sm } @@ -72,8 +73,8 @@ func (sm *StateManager) ProcState() *State { // 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) - account := sm.bc.CurrentBlock.state.GetAccount(addr) + //XXX account := sm.bc.CurrentBlock.state.GetAccount(addr) + account := sm.procState.GetAccount(addr) return sm.addrStateStore.Add(addr, account) } @@ -104,16 +105,16 @@ func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) { for _, tx := range txs { // If there's no recipient, it's a contract if tx.IsContract() { - //FIXME sm.MakeContract(tx) - block.MakeContract(tx) + sm.MakeContract(tx) + //XXX block.MakeContract(tx) } else { - //FIXME if contract := procState.GetContract(tx.Recipient); contract != nil { - if contract := block.state.GetContract(tx.Recipient); contract != nil { + if contract := sm.procState.GetContract(tx.Recipient); contract != nil { + //XXX if contract := block.state.GetContract(tx.Recipient); contract != nil { sm.ProcessContract(contract, tx, block) } else { err := sm.Ethereum.TxPool().ProcessTransaction(tx, block) if err != nil { - ethutil.Config.Log.Infoln("[smGR]", err) + ethutil.Config.Log.Infoln("[STATE]", err) } } } @@ -165,21 +166,21 @@ func (sm *StateManager) ProcessBlock(block *Block) error { // I'm not sure, but I don't know if there should be thrown // any errors at this time. - if err := sm.AccumelateRewards(sm.bc.CurrentBlock, block); err != nil { + if err := sm.AccumelateRewards(block); err != nil { return err } // if !sm.compState.Cmp(sm.procState) - if !block.state.Cmp(sm.bc.CurrentBlock.state) { - return fmt.Errorf("Invalid merkle root. Expected %x, got %x", block.State().trie.Root, sm.bc.CurrentBlock.State().trie.Root) - //FIXME return fmt.Errorf("Invalid merkle root. Expected %x, got %x", sm.compState.trie.Root, sm.procState.trie.Root) + if !sm.compState.Cmp(sm.procState) { + //XXX return fmt.Errorf("Invalid merkle root. Expected %x, got %x", block.State().trie.Root, sm.bc.CurrentBlock.State().trie.Root) + return fmt.Errorf("Invalid merkle root. Expected %x, got %x", sm.compState.trie.Root, sm.procState.trie.Root) } // Calculate the new total difficulty and sync back to the db if sm.CalculateTD(block) { // Sync the current block's state to the database and cancelling out the deferred Undo - sm.bc.CurrentBlock.Sync() - //FIXME sm.procState.Sync() + //XXX sm.bc.CurrentBlock.Sync() + sm.procState.Sync() // Broadcast the valid block back to the wire //sm.Ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) @@ -193,7 +194,7 @@ func (sm *StateManager) ProcessBlock(block *Block) error { sm.SecondaryBlockProcessor.ProcessBlock(block) } - ethutil.Config.Log.Infof("[smGR] Added block #%d (%x)\n", block.BlockInfo().Number, block.Hash()) + ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.BlockInfo().Number, block.Hash()) } else { fmt.Println("total diff failed") } @@ -270,22 +271,22 @@ func CalculateUncleReward(block *Block) *big.Int { return UncleReward } -func (sm *StateManager) AccumelateRewards(processor *Block, block *Block) error { +func (sm *StateManager) AccumelateRewards(block *Block) error { // Get the coinbase rlp data - addr := processor.state.GetAccount(block.Coinbase) - //FIXME addr := proc.GetAccount(block.Coinbase) + //XXX addr := processor.state.GetAccount(block.Coinbase) + addr := sm.procState.GetAccount(block.Coinbase) // Reward amount of ether to the coinbase address addr.AddFee(CalculateBlockReward(block, len(block.Uncles))) - processor.state.UpdateAccount(block.Coinbase, addr) - //FIXME proc.UpdateAccount(block.Coinbase, addr) + //XXX processor.state.UpdateAccount(block.Coinbase, addr) + sm.procState.UpdateAccount(block.Coinbase, addr) for _, uncle := range block.Uncles { - uncleAddr := processor.state.GetAccount(uncle.Coinbase) + uncleAddr := sm.procState.GetAccount(uncle.Coinbase) uncleAddr.AddFee(CalculateUncleReward(uncle)) - processor.state.UpdateAccount(uncle.Coinbase, uncleAddr) - //FIXME proc.UpdateAccount(uncle.Coinbase, uncleAddr) + //processor.state.UpdateAccount(uncle.Coinbase, uncleAddr) + sm.procState.UpdateAccount(uncle.Coinbase, uncleAddr) } return nil @@ -306,8 +307,8 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo */ vm := &Vm{} - //vm.Process(contract, sm.procState, RuntimeVars{ - vm.Process(contract, block.state, RuntimeVars{ + //vm.Process(contract, block.state, RuntimeVars{ + vm.Process(contract, sm.procState, RuntimeVars{ address: tx.Hash()[12:], blockNumber: block.BlockInfo().Number, sender: tx.Sender(), diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go index 2c9a26936d..fdc3863036 100644 --- a/ethchain/transaction_pool.go +++ b/ethchain/transaction_pool.go @@ -233,11 +233,11 @@ func (pool *TxPool) Start() { } func (pool *TxPool) Stop() { - log.Println("[TXP] Stopping...") - close(pool.quit) pool.Flush() + + log.Println("[TXP] Stopped") } func (pool *TxPool) Subscribe(channel chan TxMsg) { diff --git a/peer.go b/peer.go index 22a4c32fd5..89b567fb63 100644 --- a/peer.go +++ b/peer.go @@ -293,7 +293,8 @@ func (p *Peer) HandleInbound() { var err error for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - // FIXME p.ethereum.BlockManager.DefaultPrepare(block) + + p.ethereum.StateManager().PrepareDefault(block) err = p.ethereum.StateManager().ProcessBlock(block) if err != nil {