Commit 6efdd216 authored by obscuren's avatar obscuren

Merge branch 'release/poc5-rc6'

parents 283f4d8e ad4ffdc9
...@@ -6,7 +6,7 @@ Ethereum ...@@ -6,7 +6,7 @@ Ethereum
Ethereum Go Development package (C) Jeffrey Wilcke Ethereum Go Development package (C) Jeffrey Wilcke
Ethereum is currently in its testing phase. The current state is "Proof Ethereum is currently in its testing phase. The current state is "Proof
of Concept 5.0 RC4". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)). of Concept 5.0 RC6". 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 Ethereum Go is split up in several sub packages Please refer to each
individual package for more information. individual package for more information.
......
...@@ -200,6 +200,7 @@ func (sm *StateManager) ProcessBlock(block *Block, dontReact bool) error { ...@@ -200,6 +200,7 @@ func (sm *StateManager) ProcessBlock(block *Block, dontReact bool) error {
sm.Ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) sm.Ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val})
sm.Ethereum.TxPool().RemoveInvalid(sm.procState)
} else { } else {
fmt.Println("total diff failed") fmt.Println("total diff failed")
} }
......
...@@ -210,9 +210,9 @@ func (pool *TxPool) CurrentTransactions() []*Transaction { ...@@ -210,9 +210,9 @@ func (pool *TxPool) CurrentTransactions() []*Transaction {
txList := make([]*Transaction, pool.pool.Len()) txList := make([]*Transaction, pool.pool.Len())
i := 0 i := 0
for e := pool.pool.Front(); e != nil; e = e.Next() { for e := pool.pool.Front(); e != nil; e = e.Next() {
if tx, ok := e.Value.(*Transaction); ok { tx := e.Value.(*Transaction)
txList[i] = tx txList[i] = tx
}
i++ i++
} }
...@@ -220,6 +220,17 @@ func (pool *TxPool) CurrentTransactions() []*Transaction { ...@@ -220,6 +220,17 @@ func (pool *TxPool) CurrentTransactions() []*Transaction {
return txList return txList
} }
func (pool *TxPool) RemoveInvalid(state *State) {
for e := pool.pool.Front(); e != nil; e = e.Next() {
tx := e.Value.(*Transaction)
sender := state.GetAccount(tx.Sender())
err := pool.ValidateTransaction(tx)
if err != nil || sender.Nonce != tx.Nonce {
pool.pool.Remove(e)
}
}
}
func (pool *TxPool) Flush() []*Transaction { func (pool *TxPool) Flush() []*Transaction {
txList := pool.CurrentTransactions() txList := pool.CurrentTransactions()
......
...@@ -54,11 +54,13 @@ func (db *LDBDatabase) LastKnownTD() []byte { ...@@ -54,11 +54,13 @@ func (db *LDBDatabase) LastKnownTD() []byte {
return data return data
} }
/*
func (db *LDBDatabase) GetKeys() []*ethutil.Key { func (db *LDBDatabase) GetKeys() []*ethutil.Key {
data, _ := db.Get([]byte("KeyRing")) data, _ := db.Get([]byte("KeyRing"))
return []*ethutil.Key{ethutil.NewKeyFromBytes(data)} return []*ethutil.Key{ethutil.NewKeyFromBytes(data)}
} }
*/
func (db *LDBDatabase) Close() { func (db *LDBDatabase) Close() {
// Close the leveldb database // Close the leveldb database
......
...@@ -26,11 +26,13 @@ func (db *MemDatabase) Get(key []byte) ([]byte, error) { ...@@ -26,11 +26,13 @@ func (db *MemDatabase) Get(key []byte) ([]byte, error) {
return db.db[string(key)], nil return db.db[string(key)], nil
} }
/*
func (db *MemDatabase) GetKeys() []*ethutil.Key { func (db *MemDatabase) GetKeys() []*ethutil.Key {
data, _ := db.Get([]byte("KeyRing")) data, _ := db.Get([]byte("KeyRing"))
return []*ethutil.Key{ethutil.NewKeyFromBytes(data)} return []*ethutil.Key{ethutil.NewKeyFromBytes(data)}
} }
*/
func (db *MemDatabase) Delete(key []byte) error { func (db *MemDatabase) Delete(key []byte) error {
delete(db.db, string(key)) delete(db.db, string(key))
......
...@@ -138,6 +138,18 @@ func (s *Ethereum) IsMining() bool { ...@@ -138,6 +138,18 @@ func (s *Ethereum) IsMining() bool {
func (s *Ethereum) PeerCount() int { func (s *Ethereum) PeerCount() int {
return s.peers.Len() return s.peers.Len()
} }
func (s *Ethereum) IsUpToDate() bool {
upToDate := true
eachPeer(s.peers, func(peer *Peer, e *list.Element) {
if atomic.LoadInt32(&peer.connected) == 1 {
if peer.catchingUp == true {
upToDate = false
}
}
})
return upToDate
}
func (s *Ethereum) IsListening() bool { func (s *Ethereum) IsListening() bool {
return s.listening return s.listening
} }
......
...@@ -39,10 +39,7 @@ func (lib *PEthereum) GetBlock(hexHash string) *PBlock { ...@@ -39,10 +39,7 @@ func (lib *PEthereum) GetBlock(hexHash string) *PBlock {
} }
func (lib *PEthereum) GetKey() *PKey { func (lib *PEthereum) GetKey() *PKey {
keyPair, err := ethchain.NewKeyPairFromSec(ethutil.Config.Db.GetKeys()[0].PrivateKey) keyPair := ethutil.GetKeyRing().Get(0)
if err != nil {
return nil
}
return NewPKey(keyPair) return NewPKey(keyPair)
} }
...@@ -90,7 +87,7 @@ func (lib *PEthereum) IsContract(address string) bool { ...@@ -90,7 +87,7 @@ func (lib *PEthereum) IsContract(address string) bool {
} }
func (lib *PEthereum) SecretToAddress(key string) string { func (lib *PEthereum) SecretToAddress(key string) string {
pair, err := ethchain.NewKeyPairFromSec(ethutil.FromHex(key)) pair, err := ethutil.NewKeyPairFromSec(ethutil.FromHex(key))
if err != nil { if err != nil {
return "" return ""
} }
...@@ -115,12 +112,12 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in ...@@ -115,12 +112,12 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
hash = ethutil.FromHex(recipient) hash = ethutil.FromHex(recipient)
} }
var keyPair *ethchain.KeyPair var keyPair *ethutil.KeyPair
var err error var err error
if key[0:2] == "0x" { if key[0:2] == "0x" {
keyPair, err = ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key[0:2]))) keyPair, err = ethutil.NewKeyPairFromSec([]byte(ethutil.FromHex(key[0:2])))
} else { } else {
keyPair, err = ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key))) keyPair, err = ethutil.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
} }
if err != nil { if err != nil {
......
...@@ -39,7 +39,7 @@ type PKey struct { ...@@ -39,7 +39,7 @@ type PKey struct {
PublicKey string `json:"publicKey"` PublicKey string `json:"publicKey"`
} }
func NewPKey(key *ethchain.KeyPair) *PKey { func NewPKey(key *ethutil.KeyPair) *PKey {
return &PKey{ethutil.Hex(key.Address()), ethutil.Hex(key.PrivateKey), ethutil.Hex(key.PublicKey)} return &PKey{ethutil.Hex(key.Address()), ethutil.Hex(key.PrivateKey), ethutil.Hex(key.PublicKey)}
} }
......
...@@ -50,7 +50,7 @@ func ReadConfig(base string) *config { ...@@ -50,7 +50,7 @@ func ReadConfig(base string) *config {
} }
} }
Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC4"} Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC6"}
Config.Log = NewLogger(LogFile|LogStd, LogLevelDebug) Config.Log = NewLogger(LogFile|LogStd, LogLevelDebug)
Config.SetClientString("/Ethereum(G)") Config.SetClientString("/Ethereum(G)")
} }
......
...@@ -4,7 +4,7 @@ package ethutil ...@@ -4,7 +4,7 @@ package ethutil
type Database interface { type Database interface {
Put(key []byte, value []byte) Put(key []byte, value []byte)
Get(key []byte) ([]byte, error) Get(key []byte) ([]byte, error)
GetKeys() []*Key //GetKeys() []*Key
Delete(key []byte) error Delete(key []byte) error
LastKnownTD() []byte LastKnownTD() []byte
Close() Close()
......
package ethutil
type Key struct {
PrivateKey []byte
PublicKey []byte
}
func NewKeyFromBytes(data []byte) *Key {
val := NewValueFromBytes(data)
return &Key{val.Get(0).Bytes(), val.Get(1).Bytes()}
}
func (k *Key) Address() []byte {
return Sha3Bin(k.PublicKey[1:])[12:]
}
func (k *Key) RlpEncode() []byte {
return EmptyValue().Append(k.PrivateKey).Append(k.PublicKey).Encode()
}
package ethchain package ethutil
import ( import (
"github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/secp256k1-go" "github.com/obscuren/secp256k1-go"
"math/big"
) )
type KeyPair struct { type KeyPair struct {
...@@ -12,7 +10,6 @@ type KeyPair struct { ...@@ -12,7 +10,6 @@ type KeyPair struct {
// The associated account // The associated account
account *StateObject account *StateObject
state *State
} }
func NewKeyPairFromSec(seckey []byte) (*KeyPair, error) { func NewKeyPairFromSec(seckey []byte) (*KeyPair, error) {
...@@ -24,62 +21,87 @@ func NewKeyPairFromSec(seckey []byte) (*KeyPair, error) { ...@@ -24,62 +21,87 @@ func NewKeyPairFromSec(seckey []byte) (*KeyPair, error) {
return &KeyPair{PrivateKey: seckey, PublicKey: pubkey}, nil return &KeyPair{PrivateKey: seckey, PublicKey: pubkey}, nil
} }
func NewKeyPairFromValue(val *ethutil.Value) *KeyPair { func NewKeyPairFromValue(val *Value) *KeyPair {
keyPair := &KeyPair{PrivateKey: val.Get(0).Bytes(), PublicKey: val.Get(1).Bytes()} v, _ := NewKeyPairFromSec(val.Bytes())
return keyPair return v
} }
func (k *KeyPair) Address() []byte { func (k *KeyPair) Address() []byte {
return ethutil.Sha3Bin(k.PublicKey[1:])[12:] return Sha3Bin(k.PublicKey[1:])[12:]
} }
func (k *KeyPair) Account() *StateObject { func (k *KeyPair) RlpEncode() []byte {
if k.account == nil { return k.RlpValue().Encode()
k.account = k.state.GetAccount(k.Address()) }
}
return k.account func (k *KeyPair) RlpValue() *Value {
return NewValue(k.PrivateKey)
}
type KeyRing struct {
keys []*KeyPair
} }
// Create transaction, creates a new and signed transaction, ready for processing func (k *KeyRing) Add(pair *KeyPair) {
func (k *KeyPair) CreateTx(receiver []byte, value *big.Int, data []string) *Transaction { k.keys = append(k.keys, pair)
/* TODO }
tx := NewTransaction(receiver, value, data)
tx.Nonce = k.account.Nonce
// Sign the transaction with the private key in this key chain func (k *KeyRing) Get(i int) *KeyPair {
tx.Sign(k.PrivateKey) if len(k.keys) > i {
return k.keys[i]
}
return tx
*/
return nil return nil
} }
func (k *KeyPair) RlpEncode() []byte { func (k *KeyRing) Len() int {
return ethutil.EmptyValue().Append(k.PrivateKey).Append(k.PublicKey).Encode() return len(k.keys)
} }
type KeyRing struct { func (k *KeyRing) NewKeyPair(sec []byte) (*KeyPair, error) {
keys []*KeyPair keyPair, err := NewKeyPairFromSec(sec)
if err != nil {
return nil, err
}
k.Add(keyPair)
Config.Db.Put([]byte("KeyRing"), k.RlpValue().Encode())
return keyPair, nil
} }
func (k *KeyRing) Add(pair *KeyPair) { func (k *KeyRing) Reset() {
k.keys = append(k.keys, pair) Config.Db.Put([]byte("KeyRing"), nil)
k.keys = nil
}
func (k *KeyRing) RlpValue() *Value {
v := EmptyValue()
for _, keyPair := range k.keys {
v.Append(keyPair.RlpValue())
}
return v
} }
// The public "singleton" keyring // The public "singleton" keyring
var keyRing *KeyRing var keyRing *KeyRing
func GetKeyRing(state *State) *KeyRing { func GetKeyRing() *KeyRing {
if keyRing == nil { if keyRing == nil {
keyRing = &KeyRing{} keyRing = &KeyRing{}
data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) data, _ := Config.Db.Get([]byte("KeyRing"))
it := ethutil.NewValueFromBytes(data).NewIterator() it := NewValueFromBytes(data).NewIterator()
for it.Next() { for it.Next() {
v := it.Value() v := it.Value()
keyRing.Add(NewKeyPairFromValue(v))
key, err := NewKeyPairFromSec(v.Bytes())
if err != nil {
panic(err)
}
keyRing.Add(key)
} }
} }
......
...@@ -124,7 +124,7 @@ func ReadMessages(conn net.Conn) (msgs []*Msg, err error) { ...@@ -124,7 +124,7 @@ func ReadMessages(conn net.Conn) (msgs []*Msg, err error) {
var totalBytes int var totalBytes int
for { for {
// Give buffering some time // Give buffering some time
conn.SetReadDeadline(time.Now().Add(20 * time.Millisecond)) conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
// Create a new temporarily buffer // Create a new temporarily buffer
b := make([]byte, 1440) b := make([]byte, 1440)
// Wait for a message from this peer // Wait for a message from this peer
...@@ -134,7 +134,6 @@ func ReadMessages(conn net.Conn) (msgs []*Msg, err error) { ...@@ -134,7 +134,6 @@ func ReadMessages(conn net.Conn) (msgs []*Msg, err error) {
fmt.Println("err now", err) fmt.Println("err now", err)
return nil, err return nil, err
} else { } else {
fmt.Println("IOF NOW")
break break
} }
......
...@@ -187,6 +187,10 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { ...@@ -187,6 +187,10 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
// Outputs any RLP encoded data to the peer // Outputs any RLP encoded data to the peer
func (p *Peer) QueueMessage(msg *ethwire.Msg) { func (p *Peer) QueueMessage(msg *ethwire.Msg) {
if atomic.LoadInt32(&p.connected) != 1 {
return
}
p.outputQueue <- msg p.outputQueue <- msg
} }
...@@ -295,28 +299,6 @@ func (p *Peer) HandleInbound() { ...@@ -295,28 +299,6 @@ func (p *Peer) HandleInbound() {
var block, lastBlock *ethchain.Block var block, lastBlock *ethchain.Block
var err error var err error
// 1. Compare the first block over the wire's prev-hash with the hash of your last block
// 2. If these two values are the same you can just link the chains together.
// [1:0,2:1,3:2] <- Current blocks (format block:previous_block)
// [1:0,2:1,3:2,4:3,5:4] <- incoming blocks
// == [1,2,3,4,5]
// 3. If the values are not the same we will have to go back and calculate the chain with the highest total difficulty
// [1:0,2:1,3:2,11:3,12:11,13:12]
// [1:0,2:1,3:2,4:3,5:4,6:5]
// [3:2,11:3,12:11,13:12]
// [3:2,4:3,5:4,6:5]
// Heb ik dit blok?
// Nee: heb ik een blok met PrevHash 3?
// Ja: DIVERSION
// Nee; Adding to chain
// See if we can find a common ancestor
// 1. Get the earliest block in the package.
// 2. Do we have this block?
// 3. Yes: Let's continue what we are doing
// 4. No: Let's request more blocks back.
// Make sure we are actually receiving anything // Make sure we are actually receiving anything
if msg.Data.Len()-1 > 1 && p.catchingUp { if msg.Data.Len()-1 > 1 && p.catchingUp {
// We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find
...@@ -338,7 +320,6 @@ func (p *Peer) HandleInbound() { ...@@ -338,7 +320,6 @@ func (p *Peer) HandleInbound() {
if !p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { if !p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) {
// We don't have this block, but we do have a block with the same prevHash, diversion time! // We don't have this block, but we do have a block with the same prevHash, diversion time!
if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) {
//ethutil.Config.Log.Infof("[PEER] Local and foreign chain have diverted after %x, finding best chain!\n", block.PrevHash)
if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) {
return return
} }
...@@ -371,7 +352,8 @@ func (p *Peer) HandleInbound() { ...@@ -371,7 +352,8 @@ func (p *Peer) HandleInbound() {
p.catchingUp = false p.catchingUp = false
p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash())
} else if ethchain.IsValidationErr(err) { } else if ethchain.IsValidationErr(err) {
// TODO fmt.Println(err)
p.catchingUp = false
} }
} else { } else {
// XXX Do we want to catch up if there were errors? // XXX Do we want to catch up if there were errors?
...@@ -381,10 +363,19 @@ func (p *Peer) HandleInbound() { ...@@ -381,10 +363,19 @@ func (p *Peer) HandleInbound() {
blockInfo := lastBlock.BlockInfo() blockInfo := lastBlock.BlockInfo()
ethutil.Config.Log.Infof("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) ethutil.Config.Log.Infof("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash)
} }
p.catchingUp = false p.catchingUp = false
p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash())
hash := p.ethereum.BlockChain().CurrentBlock.Hash()
p.CatchupWithPeer(hash)
} }
} }
if msg.Data.Len() == 0 {
// Set catching up to false if
// the peer has nothing left to give
p.catchingUp = false
}
case ethwire.MsgTxTy: case ethwire.MsgTxTy:
// If the message was a transaction queue the transaction // If the message was a transaction queue the transaction
// in the TxPool where it will undergo validation and // in the TxPool where it will undergo validation and
...@@ -447,7 +438,10 @@ func (p *Peer) HandleInbound() { ...@@ -447,7 +438,10 @@ func (p *Peer) HandleInbound() {
if len(chain) > 0 { if len(chain) > 0 {
ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash())
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain))
} else {
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{}))
} }
} else { } else {
ethutil.Config.Log.Debugf("[PEER] Could not find a similar block") ethutil.Config.Log.Debugf("[PEER] Could not find a similar block")
// If no blocks are found we send back a reply with msg not in chain // If no blocks are found we send back a reply with msg not in chain
...@@ -577,8 +571,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { ...@@ -577,8 +571,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
p.port = uint16(c.Get(4).Uint()) p.port = uint16(c.Get(4).Uint())
// Self connect detection // Self connect detection
key := ethutil.Config.Db.GetKeys()[0] keyPair := ethutil.GetKeyRing().Get(0)
if bytes.Compare(key.PublicKey, p.pubkey) == 0 { if bytes.Compare(keyPair.PublicKey, p.pubkey) == 0 {
p.Stop() p.Stop()
return return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment