Merge branch 'release/poc5-rc6'
This commit is contained in:
commit
6efdd21633
|
@ -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 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
|
||||
individual package for more information.
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package ethchain
|
||||
|
||||
import (
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
"github.com/obscuren/secp256k1-go"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type KeyPair struct {
|
||||
PrivateKey []byte
|
||||
PublicKey []byte
|
||||
|
||||
// The associated account
|
||||
account *StateObject
|
||||
state *State
|
||||
}
|
||||
|
||||
func NewKeyPairFromSec(seckey []byte) (*KeyPair, error) {
|
||||
pubkey, err := secp256k1.GeneratePubKey(seckey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &KeyPair{PrivateKey: seckey, PublicKey: pubkey}, nil
|
||||
}
|
||||
|
||||
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() *StateObject {
|
||||
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 {
|
||||
/* TODO
|
||||
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
|
||||
*/
|
||||
return nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
|
@ -200,6 +200,7 @@ func (sm *StateManager) ProcessBlock(block *Block, dontReact bool) error {
|
|||
|
||||
sm.Ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val})
|
||||
|
||||
sm.Ethereum.TxPool().RemoveInvalid(sm.procState)
|
||||
} else {
|
||||
fmt.Println("total diff failed")
|
||||
}
|
||||
|
|
|
@ -210,9 +210,9 @@ func (pool *TxPool) CurrentTransactions() []*Transaction {
|
|||
txList := make([]*Transaction, pool.pool.Len())
|
||||
i := 0
|
||||
for e := pool.pool.Front(); e != nil; e = e.Next() {
|
||||
if tx, ok := e.Value.(*Transaction); ok {
|
||||
tx := e.Value.(*Transaction)
|
||||
|
||||
txList[i] = tx
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
|
@ -220,6 +220,17 @@ func (pool *TxPool) CurrentTransactions() []*Transaction {
|
|||
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 {
|
||||
txList := pool.CurrentTransactions()
|
||||
|
||||
|
|
|
@ -54,11 +54,13 @@ func (db *LDBDatabase) LastKnownTD() []byte {
|
|||
return data
|
||||
}
|
||||
|
||||
/*
|
||||
func (db *LDBDatabase) GetKeys() []*ethutil.Key {
|
||||
data, _ := db.Get([]byte("KeyRing"))
|
||||
|
||||
return []*ethutil.Key{ethutil.NewKeyFromBytes(data)}
|
||||
}
|
||||
*/
|
||||
|
||||
func (db *LDBDatabase) Close() {
|
||||
// Close the leveldb database
|
||||
|
|
|
@ -26,11 +26,13 @@ func (db *MemDatabase) Get(key []byte) ([]byte, error) {
|
|||
return db.db[string(key)], nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (db *MemDatabase) GetKeys() []*ethutil.Key {
|
||||
data, _ := db.Get([]byte("KeyRing"))
|
||||
|
||||
return []*ethutil.Key{ethutil.NewKeyFromBytes(data)}
|
||||
}
|
||||
*/
|
||||
|
||||
func (db *MemDatabase) Delete(key []byte) error {
|
||||
delete(db.db, string(key))
|
||||
|
|
12
ethereum.go
12
ethereum.go
|
@ -138,6 +138,18 @@ func (s *Ethereum) IsMining() bool {
|
|||
func (s *Ethereum) PeerCount() int {
|
||||
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 {
|
||||
return s.listening
|
||||
}
|
||||
|
|
|
@ -39,10 +39,7 @@ func (lib *PEthereum) GetBlock(hexHash string) *PBlock {
|
|||
}
|
||||
|
||||
func (lib *PEthereum) GetKey() *PKey {
|
||||
keyPair, err := ethchain.NewKeyPairFromSec(ethutil.Config.Db.GetKeys()[0].PrivateKey)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
keyPair := ethutil.GetKeyRing().Get(0)
|
||||
|
||||
return NewPKey(keyPair)
|
||||
}
|
||||
|
@ -90,7 +87,7 @@ func (lib *PEthereum) IsContract(address string) bool {
|
|||
}
|
||||
|
||||
func (lib *PEthereum) SecretToAddress(key string) string {
|
||||
pair, err := ethchain.NewKeyPairFromSec(ethutil.FromHex(key))
|
||||
pair, err := ethutil.NewKeyPairFromSec(ethutil.FromHex(key))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -115,12 +112,12 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
|
|||
hash = ethutil.FromHex(recipient)
|
||||
}
|
||||
|
||||
var keyPair *ethchain.KeyPair
|
||||
var keyPair *ethutil.KeyPair
|
||||
var err error
|
||||
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 {
|
||||
keyPair, err = ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
|
||||
keyPair, err = ethutil.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -39,7 +39,7 @@ type PKey struct {
|
|||
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)}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.SetClientString("/Ethereum(G)")
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ package ethutil
|
|||
type Database interface {
|
||||
Put(key []byte, value []byte)
|
||||
Get(key []byte) ([]byte, error)
|
||||
GetKeys() []*Key
|
||||
//GetKeys() []*Key
|
||||
Delete(key []byte) error
|
||||
LastKnownTD() []byte
|
||||
Close()
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
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()
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package ethutil
|
||||
|
||||
import (
|
||||
"github.com/obscuren/secp256k1-go"
|
||||
)
|
||||
|
||||
type KeyPair struct {
|
||||
PrivateKey []byte
|
||||
PublicKey []byte
|
||||
|
||||
// The associated account
|
||||
account *StateObject
|
||||
}
|
||||
|
||||
func NewKeyPairFromSec(seckey []byte) (*KeyPair, error) {
|
||||
pubkey, err := secp256k1.GeneratePubKey(seckey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &KeyPair{PrivateKey: seckey, PublicKey: pubkey}, nil
|
||||
}
|
||||
|
||||
func NewKeyPairFromValue(val *Value) *KeyPair {
|
||||
v, _ := NewKeyPairFromSec(val.Bytes())
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (k *KeyPair) Address() []byte {
|
||||
return Sha3Bin(k.PublicKey[1:])[12:]
|
||||
}
|
||||
|
||||
func (k *KeyPair) RlpEncode() []byte {
|
||||
return k.RlpValue().Encode()
|
||||
}
|
||||
|
||||
func (k *KeyPair) RlpValue() *Value {
|
||||
return NewValue(k.PrivateKey)
|
||||
}
|
||||
|
||||
type KeyRing struct {
|
||||
keys []*KeyPair
|
||||
}
|
||||
|
||||
func (k *KeyRing) Add(pair *KeyPair) {
|
||||
k.keys = append(k.keys, pair)
|
||||
}
|
||||
|
||||
func (k *KeyRing) Get(i int) *KeyPair {
|
||||
if len(k.keys) > i {
|
||||
return k.keys[i]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *KeyRing) Len() int {
|
||||
return len(k.keys)
|
||||
}
|
||||
|
||||
func (k *KeyRing) NewKeyPair(sec []byte) (*KeyPair, error) {
|
||||
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) Reset() {
|
||||
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
|
||||
var keyRing *KeyRing
|
||||
|
||||
func GetKeyRing() *KeyRing {
|
||||
if keyRing == nil {
|
||||
keyRing = &KeyRing{}
|
||||
|
||||
data, _ := Config.Db.Get([]byte("KeyRing"))
|
||||
it := NewValueFromBytes(data).NewIterator()
|
||||
for it.Next() {
|
||||
v := it.Value()
|
||||
|
||||
key, err := NewKeyPairFromSec(v.Bytes())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
keyRing.Add(key)
|
||||
}
|
||||
}
|
||||
|
||||
return keyRing
|
||||
}
|
|
@ -124,7 +124,7 @@ func ReadMessages(conn net.Conn) (msgs []*Msg, err error) {
|
|||
var totalBytes int
|
||||
for {
|
||||
// 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
|
||||
b := make([]byte, 1440)
|
||||
// Wait for a message from this peer
|
||||
|
@ -134,7 +134,6 @@ func ReadMessages(conn net.Conn) (msgs []*Msg, err error) {
|
|||
fmt.Println("err now", err)
|
||||
return nil, err
|
||||
} else {
|
||||
fmt.Println("IOF NOW")
|
||||
break
|
||||
}
|
||||
|
||||
|
|
48
peer.go
48
peer.go
|
@ -187,6 +187,10 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
|
|||
|
||||
// Outputs any RLP encoded data to the peer
|
||||
func (p *Peer) QueueMessage(msg *ethwire.Msg) {
|
||||
if atomic.LoadInt32(&p.connected) != 1 {
|
||||
return
|
||||
}
|
||||
|
||||
p.outputQueue <- msg
|
||||
}
|
||||
|
||||
|
@ -295,28 +299,6 @@ func (p *Peer) HandleInbound() {
|
|||
var block, lastBlock *ethchain.Block
|
||||
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
|
||||
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
|
||||
|
@ -338,7 +320,6 @@ func (p *Peer) HandleInbound() {
|
|||
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!
|
||||
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) {
|
||||
return
|
||||
}
|
||||
|
@ -371,7 +352,8 @@ func (p *Peer) HandleInbound() {
|
|||
p.catchingUp = false
|
||||
p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash())
|
||||
} else if ethchain.IsValidationErr(err) {
|
||||
// TODO
|
||||
fmt.Println(err)
|
||||
p.catchingUp = false
|
||||
}
|
||||
} else {
|
||||
// XXX Do we want to catch up if there were errors?
|
||||
|
@ -381,10 +363,19 @@ func (p *Peer) HandleInbound() {
|
|||
blockInfo := lastBlock.BlockInfo()
|
||||
ethutil.Config.Log.Infof("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash)
|
||||
}
|
||||
|
||||
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:
|
||||
// If the message was a transaction queue the transaction
|
||||
// in the TxPool where it will undergo validation and
|
||||
|
@ -447,7 +438,10 @@ func (p *Peer) HandleInbound() {
|
|||
if len(chain) > 0 {
|
||||
ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash())
|
||||
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain))
|
||||
} else {
|
||||
p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{}))
|
||||
}
|
||||
|
||||
} else {
|
||||
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
|
||||
|
@ -577,8 +571,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
|
|||
p.port = uint16(c.Get(4).Uint())
|
||||
|
||||
// Self connect detection
|
||||
key := ethutil.Config.Db.GetKeys()[0]
|
||||
if bytes.Compare(key.PublicKey, p.pubkey) == 0 {
|
||||
keyPair := ethutil.GetKeyRing().Get(0)
|
||||
if bytes.Compare(keyPair.PublicKey, p.pubkey) == 0 {
|
||||
p.Stop()
|
||||
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue