mirror of https://github.com/poanetwork/quorum.git
Merge branch 'goeth-1.8.18' into geth-upgrade-1.8.18
# Conflicts: # .github/CONTRIBUTING.md # .travis.yml # core/blockchain.go # core/vm/evm.go # core/vm/logger_test.go # eth/handler_test.go # eth/tracers/tracer_test.go # internal/ethapi/api.go # internal/web3ext/web3ext.go # p2p/discover/node.go # p2p/server.go # swarm/network/simulations/discovery/discovery_test.go
This commit is contained in:
parent
bc529a509d
commit
4dbd95947d
|
@ -26,13 +26,13 @@ import (
|
|||
"time"
|
||||
"unicode"
|
||||
|
||||
cli "gopkg.in/urfave/cli.v1"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/dashboard"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/raft"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
|
||||
|
@ -218,7 +218,7 @@ func RegisterRaftService(stack *node.Node, ctx *cli.Context, cfg gethConfig, eth
|
|||
|
||||
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||
privkey := cfg.Node.NodeKey()
|
||||
strId := discover.PubkeyID(&privkey.PublicKey).String()
|
||||
strId := enode.PubkeyToIDV4(&privkey.PublicKey).String()
|
||||
blockTimeNanos := time.Duration(blockTimeMillis) * time.Millisecond
|
||||
peers := cfg.Node.StaticNodes()
|
||||
|
||||
|
@ -238,7 +238,7 @@ func RegisterRaftService(stack *node.Node, ctx *cli.Context, cfg gethConfig, eth
|
|||
utils.Fatalf("raftport querystring parameter not specified in static-node enode ID: %v. please check your static-nodes.json file.", peer.String())
|
||||
}
|
||||
|
||||
peerId := peer.ID.String()
|
||||
peerId := peer.ID().String()
|
||||
peerIds[peerIdx] = peerId
|
||||
if peerId == strId {
|
||||
myId = uint16(peerIdx) + 1
|
||||
|
|
|
@ -673,7 +673,7 @@ func (ethash *Ethash) SetThreads(threads int) {
|
|||
// Note the returned hashrate includes local hashrate, but also includes the total
|
||||
// hashrate of all remote miner.
|
||||
func (ethash *Ethash) Hashrate() float64 {
|
||||
if(ethash.hashrate == nil){
|
||||
if ethash.hashrate == nil {
|
||||
return 0
|
||||
}
|
||||
// Short circuit if we are run the ethash in normal/test mode.
|
||||
|
|
|
@ -428,6 +428,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
return nil, common.Address{}, gas, ErrInsufficientBalance
|
||||
}
|
||||
|
||||
// Quorum
|
||||
// Get the right state in case of a dual state environment. If a sender
|
||||
// is a transaction (depth == 0) use the public state to derive the address
|
||||
// and increment the nonce of the public state. If the sender is a contract
|
||||
|
@ -447,16 +448,15 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
creatorStateDb.SetNonce(caller.Address(), nonce+1)
|
||||
|
||||
// Ensure there's no existing contract already at the designated address
|
||||
contractAddr := crypto.CreateAddress(caller.Address(), nonce)
|
||||
contractHash := evm.StateDB.GetCodeHash(contractAddr)
|
||||
if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {
|
||||
contractHash := evm.StateDB.GetCodeHash(address)
|
||||
if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {
|
||||
return nil, common.Address{}, 0, ErrContractAddressCollision
|
||||
}
|
||||
// Create a new account on the state
|
||||
snapshot := evm.StateDB.Snapshot()
|
||||
evm.StateDB.CreateAccount(contractAddr)
|
||||
evm.StateDB.CreateAccount(address)
|
||||
if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
|
||||
evm.StateDB.SetNonce(contractAddr, 1)
|
||||
evm.StateDB.SetNonce(address, 1)
|
||||
}
|
||||
if evm.ChainConfig().IsQuorum {
|
||||
// skip transfer if value /= 0 (see note: Quorum, States, and Value Transfer)
|
||||
|
@ -464,10 +464,10 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
if evm.quorumReadOnly {
|
||||
return nil, common.Address{}, gas, ErrReadOnlyValueTransfer
|
||||
}
|
||||
evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)
|
||||
evm.Transfer(evm.StateDB, caller.Address(), address, value)
|
||||
}
|
||||
} else {
|
||||
evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)
|
||||
evm.Transfer(evm.StateDB, caller.Address(), address, value)
|
||||
}
|
||||
|
||||
// initialise a new contract and set the code that is to be used by the
|
||||
|
@ -477,7 +477,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
contract.SetCodeOptionalHash(&address, codeAndHash)
|
||||
|
||||
if evm.vmConfig.NoRecursion && evm.depth > 0 {
|
||||
return nil, contractAddr, gas, nil
|
||||
return nil, address, gas, nil
|
||||
}
|
||||
|
||||
if evm.vmConfig.Debug && evm.depth == 0 {
|
||||
|
@ -496,7 +496,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
if err == nil && !maxCodeSizeExceeded {
|
||||
createDataGas := uint64(len(ret)) * params.CreateDataGas
|
||||
if contract.UseGas(createDataGas) {
|
||||
evm.StateDB.SetCode(contractAddr, ret)
|
||||
evm.StateDB.SetCode(address, ret)
|
||||
} else {
|
||||
err = ErrCodeStoreOutOfGas
|
||||
}
|
||||
|
@ -518,13 +518,31 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
if evm.vmConfig.Debug && evm.depth == 0 {
|
||||
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
|
||||
}
|
||||
return ret, contractAddr, contract.Gas, err
|
||||
return ret, address, contract.Gas, err
|
||||
|
||||
}
|
||||
|
||||
// Create creates a new contract using code as deployment code.
|
||||
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
||||
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
|
||||
// Quorum
|
||||
// Get the right state in case of a dual state environment. If a sender
|
||||
// is a transaction (depth == 0) use the public state to derive the address
|
||||
// and increment the nonce of the public state. If the sender is a contract
|
||||
// (depth > 0) use the private state to derive the nonce and increment the
|
||||
// nonce on the private state only.
|
||||
//
|
||||
// If the transaction went to a public contract the private and public state
|
||||
// are the same.
|
||||
var creatorStateDb StateDB
|
||||
if evm.depth > 0 {
|
||||
creatorStateDb = evm.privateState
|
||||
} else {
|
||||
creatorStateDb = evm.publicState
|
||||
}
|
||||
|
||||
// Ensure there's no existing contract already at the designated address
|
||||
nonce := creatorStateDb.GetNonce(caller.Address())
|
||||
contractAddr = crypto.CreateAddress(caller.Address(), nonce)
|
||||
return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr)
|
||||
}
|
||||
|
||||
|
@ -582,6 +600,8 @@ func (env *EVM) Pop() {
|
|||
env.StateDB = env.states[env.currentStateDepth-1]
|
||||
}
|
||||
|
||||
func (env *EVM) Depth() int { return env.depth }
|
||||
|
||||
// We only need to revert the current state because when we call from private
|
||||
// public state it's read only, there wouldn't be anything to reset.
|
||||
// (A)->(B)->C->(B): A failure in (B) wouldn't need to reset C, as C was flagged
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
|
@ -30,6 +31,11 @@ type MinimalApiState interface {
|
|||
GetCode(addr common.Address) []byte
|
||||
GetState(a common.Address, b common.Hash) common.Hash
|
||||
GetNonce(addr common.Address) uint64
|
||||
GetProof(common.Address) ([][]byte, error)
|
||||
GetStorageProof(common.Address, common.Hash) ([][]byte, error)
|
||||
StorageTrie(addr common.Address) state.Trie
|
||||
Error() error
|
||||
GetCodeHash(common.Address) common.Hash
|
||||
}
|
||||
|
||||
// StateDB is an EVM database for full state querying.
|
||||
|
@ -44,7 +50,7 @@ type StateDB interface {
|
|||
//GetNonce(common.Address) uint64
|
||||
SetNonce(common.Address, uint64)
|
||||
|
||||
GetCodeHash(common.Address) common.Hash
|
||||
//GetCodeHash(common.Address) common.Hash
|
||||
//GetCode(common.Address) []byte
|
||||
SetCode(common.Address, []byte)
|
||||
GetCodeSize(common.Address) int
|
||||
|
|
|
@ -89,6 +89,7 @@ func (s *PublicEthereumAPI) StorageRoot(addr common.Address, blockNr *rpc.BlockN
|
|||
}
|
||||
return pub.GetStorageRoot(addr)
|
||||
}
|
||||
|
||||
// Hashrate returns the POW hashrate
|
||||
func (api *PublicEthereumAPI) Hashrate() hexutil.Uint64 {
|
||||
return hexutil.Uint64(api.e.Miner().HashRate())
|
||||
|
|
|
@ -255,6 +255,7 @@ func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma
|
|||
}
|
||||
}
|
||||
|
||||
// used by Quorum
|
||||
type EthAPIState struct {
|
||||
state, privateState *state.StateDB
|
||||
}
|
||||
|
@ -287,4 +288,25 @@ func (s EthAPIState) GetNonce(addr common.Address) uint64 {
|
|||
return s.state.GetNonce(addr)
|
||||
}
|
||||
|
||||
// TODO: implement the following methods for Quorum
|
||||
func (s EthAPIState) GetProof(common.Address) ([][]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s EthAPIState) GetStorageProof(common.Address, common.Hash) ([][]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s EthAPIState) StorageTrie(addr common.Address) state.Trie {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s EthAPIState) Error() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s EthAPIState) GetCodeHash(common.Address) common.Hash {
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
//func (s MinimalApiState) Error
|
||||
|
|
|
@ -360,10 +360,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
|||
return nil
|
||||
}
|
||||
} else if handler, ok := pm.engine.(consensus.Handler); ok {
|
||||
pubKey, err := p.ID().Pubkey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pubKey := p.Node().Pubkey()
|
||||
addr := crypto.PubkeyToAddress(*pubKey)
|
||||
handled, err := handler.HandleMsg(addr, msg)
|
||||
if handled {
|
||||
|
@ -777,7 +774,6 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// BroadcastTxs will propagate a batch of transactions to all peers which are not known to
|
||||
// already have the given transaction.
|
||||
func (pm *ProtocolManager) BroadcastTxs(txs types.Transactions) {
|
||||
|
@ -852,10 +848,7 @@ func (pm *ProtocolManager) NodeInfo() *NodeInfo {
|
|||
func (self *ProtocolManager) FindPeers(targets map[common.Address]bool) map[common.Address]consensus.Peer {
|
||||
m := make(map[common.Address]consensus.Peer)
|
||||
for _, p := range self.peers.Peers() {
|
||||
pubKey, err := p.ID().Pubkey()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
pubKey := p.Node().Pubkey()
|
||||
addr := crypto.PubkeyToAddress(*pubKey)
|
||||
if targets[addr] {
|
||||
m[addr] = p
|
||||
|
|
|
@ -191,7 +191,7 @@ func (pool *serverPool) discoverNodes() {
|
|||
if err != nil {
|
||||
continue
|
||||
}
|
||||
pool.discNodes <- enode.NewV4(pubkey, n.IP, int(n.TCP), int(n.UDP))
|
||||
pool.discNodes <- enode.NewV4(pubkey, n.IP, int(n.TCP), int(n.UDP), 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -667,7 +667,7 @@ func (e *poolEntry) DecodeRLP(s *rlp.Stream) error {
|
|||
return err
|
||||
}
|
||||
addr := &poolEntryAddress{ip: entry.IP, port: entry.Port, fails: entry.Fails, lastSeen: mclock.Now()}
|
||||
e.node = enode.NewV4(pubkey, entry.IP, int(entry.Port), int(entry.Port))
|
||||
e.node = enode.NewV4(pubkey, entry.IP, int(entry.Port), int(entry.Port), 0)
|
||||
e.addr = make(map[string]*poolEntryAddress)
|
||||
e.addr[addr.strKey()] = addr
|
||||
e.addrSelect = *newWeightedRandomSelect()
|
||||
|
|
|
@ -368,7 +368,9 @@ func (c *Config) parsePersistentNodes(path string) []*enode.Node {
|
|||
if url == "" {
|
||||
continue
|
||||
}
|
||||
log.Info("AJ-parsePersistentNodes1", "url", url)
|
||||
node, err := enode.ParseV4(url)
|
||||
log.Info("AJ-parsePersistentNodes2", "url", url, "ID", node.ID().String(), "EnodeID", node.EnodeID())
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Node URL %s: %v\n", url, err))
|
||||
continue
|
||||
|
|
|
@ -57,7 +57,7 @@ func testPingReplace(t *testing.T, newNodeIsResponding, lastInBucketIsResponding
|
|||
|
||||
// Fill up the sender's bucket.
|
||||
pingKey, _ := crypto.HexToECDSA("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8")
|
||||
pingSender := wrapNode(enode.NewV4(&pingKey.PublicKey, net.IP{}, 99, 99))
|
||||
pingSender := wrapNode(enode.NewV4(&pingKey.PublicKey, net.IP{}, 99, 99, 0))
|
||||
last := fillBucket(tab, pingSender)
|
||||
|
||||
// Add the sender as if it just pinged us. Revalidate should replace the last node in
|
||||
|
@ -289,7 +289,7 @@ func TestTable_Lookup(t *testing.T) {
|
|||
}
|
||||
// seed table with initial node (otherwise lookup will terminate immediately)
|
||||
seedKey, _ := decodePubkey(lookupTestnet.dists[256][0])
|
||||
seed := wrapNode(enode.NewV4(seedKey, net.IP{}, 0, 256))
|
||||
seed := wrapNode(enode.NewV4(seedKey, net.IP{}, 0, 256, 0))
|
||||
tab.stuff([]*node{seed})
|
||||
|
||||
results := tab.lookup(lookupTestnet.target, true)
|
||||
|
@ -524,7 +524,7 @@ func (tn *preminedTestnet) findnode(toid enode.ID, toaddr *net.UDPAddr, target e
|
|||
var result []*node
|
||||
for i, ekey := range tn.dists[toaddr.Port] {
|
||||
key, _ := decodePubkey(ekey)
|
||||
node := wrapNode(enode.NewV4(key, net.ParseIP("127.0.0.1"), i, next))
|
||||
node := wrapNode(enode.NewV4(key, net.ParseIP("127.0.0.1"), i, next, 0))
|
||||
result = append(result, node)
|
||||
}
|
||||
return result, nil
|
||||
|
|
|
@ -141,7 +141,7 @@ func (t *udp) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*node, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n := wrapNode(enode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP)))
|
||||
n := wrapNode(enode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP), 0))
|
||||
err = n.ValidateComplete()
|
||||
return n, err
|
||||
}
|
||||
|
@ -628,7 +628,7 @@ func (req *ping) handle(t *udp, from *net.UDPAddr, fromKey encPubkey, mac []byte
|
|||
ReplyTok: mac,
|
||||
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
||||
})
|
||||
n := wrapNode(enode.NewV4(key, from.IP, int(req.From.TCP), from.Port))
|
||||
n := wrapNode(enode.NewV4(key, from.IP, int(req.From.TCP), from.Port, 0))
|
||||
t.handleReply(n.ID(), pingPacket, req)
|
||||
if time.Since(t.db.LastPongReceived(n.ID())) > bondExpiration {
|
||||
t.sendPing(n.ID(), from, func() { t.tab.addThroughPing(n) })
|
||||
|
|
|
@ -244,7 +244,7 @@ func TestUDP_findnode(t *testing.T) {
|
|||
nodes := &nodesByDistance{target: testTarget.id()}
|
||||
for i := 0; i < bucketSize; i++ {
|
||||
key := newkey()
|
||||
n := wrapNode(enode.NewV4(&key.PublicKey, net.IP{10, 13, 0, 1}, 0, i))
|
||||
n := wrapNode(enode.NewV4(&key.PublicKey, net.IP{10, 13, 0, 1}, 0, i, 0))
|
||||
nodes.push(n, bucketSize)
|
||||
}
|
||||
test.table.stuff(nodes.entries)
|
||||
|
|
|
@ -82,6 +82,20 @@ func (n *Node) UDP() int {
|
|||
return int(port)
|
||||
}
|
||||
|
||||
// RAFTPORT returns the RAFT PORT of the node
|
||||
func (n *Node) RAFTPORT() int {
|
||||
var port enr.RAFTPORT
|
||||
err := n.Load(&port)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int(port)
|
||||
}
|
||||
|
||||
func (n *Node) HasRaftPort() bool {
|
||||
return n.RAFTPORT() > 0
|
||||
}
|
||||
|
||||
// UDP returns the TCP port of the node.
|
||||
func (n *Node) TCP() int {
|
||||
var port enr.TCP
|
||||
|
|
|
@ -105,6 +105,7 @@ func TestDBFetchStore(t *testing.T) {
|
|||
net.IP{192, 168, 0, 1},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
)
|
||||
inst := time.Now()
|
||||
num := 314
|
||||
|
@ -168,6 +169,7 @@ var nodeDBSeedQueryNodes = []struct {
|
|||
net.IP{127, 0, 0, 3},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-3 * time.Hour),
|
||||
},
|
||||
|
@ -179,6 +181,7 @@ var nodeDBSeedQueryNodes = []struct {
|
|||
net.IP{127, 0, 0, 3},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-4 * time.Second),
|
||||
},
|
||||
|
@ -190,6 +193,7 @@ var nodeDBSeedQueryNodes = []struct {
|
|||
net.IP{127, 0, 0, 1},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-2 * time.Second),
|
||||
},
|
||||
|
@ -199,6 +203,7 @@ var nodeDBSeedQueryNodes = []struct {
|
|||
net.IP{127, 0, 0, 2},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-3 * time.Second),
|
||||
},
|
||||
|
@ -208,6 +213,7 @@ var nodeDBSeedQueryNodes = []struct {
|
|||
net.IP{127, 0, 0, 3},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-1 * time.Second),
|
||||
},
|
||||
|
@ -217,6 +223,7 @@ var nodeDBSeedQueryNodes = []struct {
|
|||
net.IP{127, 0, 0, 3},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-2 * time.Second),
|
||||
},
|
||||
|
@ -226,6 +233,7 @@ var nodeDBSeedQueryNodes = []struct {
|
|||
net.IP{127, 0, 0, 3},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-2 * time.Second),
|
||||
},
|
||||
|
@ -331,6 +339,7 @@ var nodeDBExpirationNodes = []struct {
|
|||
net.IP{127, 0, 0, 1},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-dbNodeExpiration + time.Minute),
|
||||
exp: false,
|
||||
|
@ -340,6 +349,7 @@ var nodeDBExpirationNodes = []struct {
|
|||
net.IP{127, 0, 0, 2},
|
||||
30303,
|
||||
30303,
|
||||
0,
|
||||
),
|
||||
pong: time.Now().Add(-dbNodeExpiration - time.Minute),
|
||||
exp: true,
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
)
|
||||
|
||||
|
@ -72,14 +73,14 @@ func ParseV4(rawurl string) (*Node, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid node ID (%v)", err)
|
||||
}
|
||||
return NewV4(id, nil, 0, 0), nil
|
||||
return NewV4(id, nil, 0, 0, 0), nil
|
||||
}
|
||||
return parseComplete(rawurl)
|
||||
}
|
||||
|
||||
// NewV4 creates a node from discovery v4 node information. The record
|
||||
// contained in the node has a zero-length signature.
|
||||
func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp int) *Node {
|
||||
func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp, raftPort int) *Node {
|
||||
var r enr.Record
|
||||
if ip != nil {
|
||||
r.Set(enr.IP(ip))
|
||||
|
@ -90,11 +91,17 @@ func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp int) *Node {
|
|||
if tcp != 0 {
|
||||
r.Set(enr.TCP(tcp))
|
||||
}
|
||||
|
||||
if raftPort != 0 {
|
||||
r.Set(enr.RAFTPORT(tcp))
|
||||
}
|
||||
|
||||
signV4Compat(&r, pubkey)
|
||||
n, err := New(v4CompatID{}, &r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Info("NewV4", "raftPort", raftPort, "nodeId", n.ID().String(), "NodeId.bytes", n.ID().Bytes())
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -115,9 +122,11 @@ func parseComplete(rawurl string) (*Node, error) {
|
|||
if u.User == nil {
|
||||
return nil, errors.New("does not contain node ID")
|
||||
}
|
||||
log.Info("AJ-parseComplete1", "u.User", u.User.String())
|
||||
if id, err = parsePubkey(u.User.String()); err != nil {
|
||||
return nil, fmt.Errorf("invalid node ID (%v)", err)
|
||||
}
|
||||
log.Info("AJ-parseComplete2", "id", id)
|
||||
// Parse the IP address.
|
||||
host, port, err := net.SplitHostPort(u.Host)
|
||||
if err != nil {
|
||||
|
@ -142,7 +151,28 @@ func parseComplete(rawurl string) (*Node, error) {
|
|||
return nil, errors.New("invalid discport in query")
|
||||
}
|
||||
}
|
||||
return NewV4(id, ip, int(tcpPort), int(udpPort)), nil
|
||||
|
||||
var node *Node
|
||||
|
||||
if qv.Get("raftport") != "" {
|
||||
raftPort, err := strconv.ParseUint(qv.Get("raftport"), 10, 16)
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid raftport in query")
|
||||
}
|
||||
node = NewV4(id, ip, int(tcpPort), int(udpPort), int(raftPort))
|
||||
} else {
|
||||
node = NewV4(id, ip, int(tcpPort), int(udpPort), 0)
|
||||
}
|
||||
return node, nil
|
||||
|
||||
}
|
||||
|
||||
func HexPubkey(h string) (*ecdsa.PublicKey, error) {
|
||||
k, err := parsePubkey(h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return k, err
|
||||
}
|
||||
|
||||
// parsePubkey parses a hex-encoded secp256k1 public key.
|
||||
|
@ -157,7 +187,8 @@ func parsePubkey(in string) (*ecdsa.PublicKey, error) {
|
|||
return crypto.UnmarshalPubkey(b)
|
||||
}
|
||||
|
||||
func (n *Node) v4URL() string {
|
||||
// TODO: Amal to review it - added for RAFT
|
||||
func (n *Node) EnodeID() string {
|
||||
var (
|
||||
scheme enr.ID
|
||||
nodeid string
|
||||
|
@ -171,6 +202,25 @@ func (n *Node) v4URL() string {
|
|||
default:
|
||||
nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:])
|
||||
}
|
||||
return nodeid
|
||||
}
|
||||
|
||||
func (n *Node) v4URL() string {
|
||||
var (
|
||||
scheme enr.ID
|
||||
nodeid string
|
||||
key ecdsa.PublicKey
|
||||
)
|
||||
n.Load(&scheme)
|
||||
n.Load((*Secp256k1)(&key))
|
||||
switch {
|
||||
case scheme == "v4" || key != ecdsa.PublicKey{}:
|
||||
log.Info("AJ-schemeV4")
|
||||
nodeid = fmt.Sprintf("%x", crypto.FromECDSAPub(&key)[1:])
|
||||
default:
|
||||
log.Info("AJ-NOT schemeV4")
|
||||
nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:])
|
||||
}
|
||||
u := url.URL{Scheme: "enode"}
|
||||
if n.Incomplete() {
|
||||
u.Host = nodeid
|
||||
|
@ -181,6 +231,15 @@ func (n *Node) v4URL() string {
|
|||
if n.UDP() != n.TCP() {
|
||||
u.RawQuery = "discport=" + strconv.Itoa(n.UDP())
|
||||
}
|
||||
raftPort := n.RAFTPORT()
|
||||
if raftPort != 0 {
|
||||
raftQuery := "raftport=" + strconv.Itoa(raftPort)
|
||||
if len(u.RawQuery) > 0 {
|
||||
u.RawQuery = u.RawQuery + "&" + raftQuery
|
||||
} else {
|
||||
u.RawQuery = raftQuery
|
||||
}
|
||||
}
|
||||
}
|
||||
return u.String()
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ var parseNodeTests = []struct {
|
|||
net.IP{0x7f, 0x0, 0x0, 0x1},
|
||||
52150,
|
||||
52150,
|
||||
0,
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -69,6 +70,7 @@ var parseNodeTests = []struct {
|
|||
net.ParseIP("::"),
|
||||
52150,
|
||||
52150,
|
||||
0,
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -78,6 +80,7 @@ var parseNodeTests = []struct {
|
|||
net.ParseIP("2001:db8:3c4d:15::abcd:ef12"),
|
||||
52150,
|
||||
52150,
|
||||
0,
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -87,6 +90,7 @@ var parseNodeTests = []struct {
|
|||
net.IP{0x7f, 0x0, 0x0, 0x1},
|
||||
52150,
|
||||
22334,
|
||||
0,
|
||||
),
|
||||
},
|
||||
// Incomplete nodes with no address.
|
||||
|
@ -94,14 +98,14 @@ var parseNodeTests = []struct {
|
|||
rawurl: "1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439",
|
||||
wantResult: NewV4(
|
||||
hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
|
||||
nil, 0, 0,
|
||||
nil, 0, 0, 0,
|
||||
),
|
||||
},
|
||||
{
|
||||
rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439",
|
||||
wantResult: NewV4(
|
||||
hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
|
||||
nil, 0, 0,
|
||||
nil, 0, 0, 0,
|
||||
),
|
||||
},
|
||||
// Invalid URLs
|
||||
|
|
|
@ -40,6 +40,7 @@ import (
|
|||
"io"
|
||||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
|
@ -120,6 +121,7 @@ func (r *Record) Load(e Entry) error {
|
|||
if err := rlp.DecodeBytes(r.pairs[i].v, e); err != nil {
|
||||
return &KeyError{Key: e.ENRKey(), Err: err}
|
||||
}
|
||||
log.Info("AJ-Load", "key", e.ENRKey(), "value", r.pairs[i].v)
|
||||
return nil
|
||||
}
|
||||
return &KeyError{Key: e.ENRKey(), Err: errNotFound}
|
||||
|
|
|
@ -77,6 +77,11 @@ type IP net.IP
|
|||
|
||||
func (v IP) ENRKey() string { return "ip" }
|
||||
|
||||
// RaftPort is the "raftport" key, which holds the raftport of the node
|
||||
type RAFTPORT uint16
|
||||
|
||||
func (v RAFTPORT) ENRKey() string { return "raftport" }
|
||||
|
||||
// EncodeRLP implements rlp.Encoder.
|
||||
func (v IP) EncodeRLP(w io.Writer) error {
|
||||
if ip4 := net.IP(v).To4(); ip4 != nil {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -21,7 +21,7 @@ func isNodePermissioned(nodename string, currentNode string, datadir string, dir
|
|||
var permissionedList []string
|
||||
nodes := parsePermissionedNodes(datadir)
|
||||
for _, v := range nodes {
|
||||
permissionedList = append(permissionedList, v.ID.String())
|
||||
permissionedList = append(permissionedList, v.ID().String())
|
||||
}
|
||||
|
||||
log.Debug("isNodePermissioned", "permissionedList", permissionedList)
|
||||
|
@ -38,7 +38,7 @@ func isNodePermissioned(nodename string, currentNode string, datadir string, dir
|
|||
//this is a shameless copy from the config.go. It is a duplication of the code
|
||||
//for the timebeing to allow reload of the permissioned nodes while the server is running
|
||||
|
||||
func parsePermissionedNodes(DataDir string) []*discover.Node {
|
||||
func parsePermissionedNodes(DataDir string) []*enode.Node {
|
||||
|
||||
log.Debug("parsePermissionedNodes", "DataDir", DataDir, "file", PERMISSIONED_CONFIG)
|
||||
|
||||
|
@ -60,13 +60,13 @@ func parsePermissionedNodes(DataDir string) []*discover.Node {
|
|||
return nil
|
||||
}
|
||||
// Interpret the list as a discovery node array
|
||||
var nodes []*discover.Node
|
||||
var nodes []*enode.Node
|
||||
for _, url := range nodelist {
|
||||
if url == "" {
|
||||
log.Error("parsePermissionedNodes: Node URL blank")
|
||||
continue
|
||||
}
|
||||
node, err := discover.ParseNode(url)
|
||||
node, err := enode.ParseV4(url)
|
||||
if err != nil {
|
||||
log.Error("parsePermissionedNodes: Node URL", "url", url, "err", err)
|
||||
continue
|
||||
|
|
|
@ -360,7 +360,7 @@ func (srv *Server) Self() *enode.Node {
|
|||
srv.lock.Unlock()
|
||||
|
||||
if ln == nil {
|
||||
return enode.NewV4(&srv.PrivateKey.PublicKey, net.ParseIP("0.0.0.0"), 0, 0)
|
||||
return enode.NewV4(&srv.PrivateKey.PublicKey, net.ParseIP("0.0.0.0"), 0, 0, 0)
|
||||
}
|
||||
return ln.Node()
|
||||
}
|
||||
|
@ -916,6 +916,17 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) erro
|
|||
return err
|
||||
}
|
||||
|
||||
if dialDest != nil {
|
||||
// For dialed connections, check that the remote public key matches.
|
||||
if dialPubkey.X.Cmp(remotePubkey.X) != 0 || dialPubkey.Y.Cmp(remotePubkey.Y) != 0 {
|
||||
return DiscUnexpectedIdentity
|
||||
}
|
||||
c.node = dialDest
|
||||
} else {
|
||||
c.node = nodeFromConn(remotePubkey, c.fd)
|
||||
}
|
||||
log.Info("AJ-setupConn1", "remotePubkey", remotePubkey)
|
||||
log.Info("AJ-setupConn2", "c.node.ID", c.node.ID(), "c.node.ID.Bytes", c.node.ID().Bytes(), "node", c.node.String())
|
||||
clog := srv.log.New("id", c.node.ID(), "addr", c.fd.RemoteAddr(), "conn", c.flags)
|
||||
|
||||
//START - QUORUM Permissioning
|
||||
|
@ -949,16 +960,6 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) erro
|
|||
|
||||
//END - QUORUM Permissioning
|
||||
|
||||
if dialDest != nil {
|
||||
// For dialed connections, check that the remote public key matches.
|
||||
if dialPubkey.X.Cmp(remotePubkey.X) != 0 || dialPubkey.Y.Cmp(remotePubkey.Y) != 0 {
|
||||
return DiscUnexpectedIdentity
|
||||
}
|
||||
c.node = dialDest
|
||||
} else {
|
||||
c.node = nodeFromConn(remotePubkey, c.fd)
|
||||
}
|
||||
|
||||
if conn, ok := c.fd.(*meteredConn); ok {
|
||||
conn.handshakeDone(c.node.ID())
|
||||
}
|
||||
|
@ -997,7 +998,7 @@ func nodeFromConn(pubkey *ecdsa.PublicKey, conn net.Conn) *enode.Node {
|
|||
ip = tcp.IP
|
||||
port = tcp.Port
|
||||
}
|
||||
return enode.NewV4(pubkey, ip, port, port)
|
||||
return enode.NewV4(pubkey, ip, port, port, 0)
|
||||
}
|
||||
|
||||
func truncateName(s string) string {
|
||||
|
|
|
@ -147,7 +147,7 @@ func TestServerDial(t *testing.T) {
|
|||
|
||||
// tell the server to connect
|
||||
tcpAddr := listener.Addr().(*net.TCPAddr)
|
||||
node := enode.NewV4(remid, tcpAddr.IP, tcpAddr.Port, 0)
|
||||
node := enode.NewV4(remid, tcpAddr.IP, tcpAddr.Port, 0, 0)
|
||||
srv.AddPeer(node)
|
||||
|
||||
select {
|
||||
|
@ -417,7 +417,7 @@ func TestServerAtCap(t *testing.T) {
|
|||
func TestServerPeerLimits(t *testing.T) {
|
||||
srvkey := newkey()
|
||||
clientkey := newkey()
|
||||
clientnode := enode.NewV4(&clientkey.PublicKey, nil, 0, 0)
|
||||
clientnode := enode.NewV4(&clientkey.PublicKey, nil, 0, 0, 0)
|
||||
|
||||
var tp = &setupTransport{
|
||||
pubkey: &clientkey.PublicKey,
|
||||
|
@ -507,21 +507,21 @@ func TestServerSetupConn(t *testing.T) {
|
|||
},
|
||||
{
|
||||
tt: &setupTransport{pubkey: clientpub},
|
||||
dialDest: enode.NewV4(&newkey().PublicKey, nil, 0, 0),
|
||||
dialDest: enode.NewV4(&newkey().PublicKey, nil, 0, 0, 0),
|
||||
flags: dynDialedConn,
|
||||
wantCalls: "doEncHandshake,close,",
|
||||
wantCloseErr: DiscUnexpectedIdentity,
|
||||
},
|
||||
{
|
||||
tt: &setupTransport{pubkey: clientpub, phs: protoHandshake{ID: randomID().Bytes()}},
|
||||
dialDest: enode.NewV4(clientpub, nil, 0, 0),
|
||||
dialDest: enode.NewV4(clientpub, nil, 0, 0, 0),
|
||||
flags: dynDialedConn,
|
||||
wantCalls: "doEncHandshake,doProtoHandshake,close,",
|
||||
wantCloseErr: DiscUnexpectedIdentity,
|
||||
},
|
||||
{
|
||||
tt: &setupTransport{pubkey: clientpub, protoHandshakeErr: errors.New("foo")},
|
||||
dialDest: enode.NewV4(clientpub, nil, 0, 0),
|
||||
dialDest: enode.NewV4(clientpub, nil, 0, 0, 0),
|
||||
flags: dynDialedConn,
|
||||
wantCalls: "doEncHandshake,doProtoHandshake,close,",
|
||||
wantCloseErr: errors.New("foo"),
|
||||
|
|
|
@ -165,7 +165,7 @@ func (n *NodeConfig) UnmarshalJSON(data []byte) error {
|
|||
|
||||
// Node returns the node descriptor represented by the config.
|
||||
func (n *NodeConfig) Node() *enode.Node {
|
||||
return enode.NewV4(&n.PrivateKey.PublicKey, net.IP{127, 0, 0, 1}, int(n.Port), int(n.Port))
|
||||
return enode.NewV4(&n.PrivateKey.PublicKey, net.IP{127, 0, 0, 1}, int(n.Port), int(n.Port), 0)
|
||||
}
|
||||
|
||||
// RandomNodeConfig returns node configuration with a randomly generated ID and
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@ type RaftService struct {
|
|||
downloader *downloader.Downloader
|
||||
|
||||
raftProtocolManager *ProtocolManager
|
||||
startPeers []*discover.Node
|
||||
startPeers []*enode.Node
|
||||
|
||||
// we need an event mux to instantiate the blockchain
|
||||
eventMux *event.TypeMux
|
||||
|
@ -36,7 +36,7 @@ type RaftService struct {
|
|||
nodeKey *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
func New(ctx *node.ServiceContext, chainConfig *params.ChainConfig, raftId, raftPort uint16, joinExisting bool, blockTime time.Duration, e *eth.Ethereum, startPeers []*discover.Node, datadir string) (*RaftService, error) {
|
||||
func New(ctx *node.ServiceContext, chainConfig *params.ChainConfig, raftId, raftPort uint16, joinExisting bool, blockTime time.Duration, e *eth.Ethereum, startPeers []*enode.Node, datadir string) (*RaftService, error) {
|
||||
service := &RaftService{
|
||||
eventMux: ctx.EventMux,
|
||||
chainDb: e.ChainDb(),
|
||||
|
|
|
@ -21,14 +21,17 @@ import (
|
|||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
|
||||
"crypto/ecdsa"
|
||||
"github.com/coreos/etcd/etcdserver/stats"
|
||||
raftTypes "github.com/coreos/etcd/pkg/types"
|
||||
etcdRaft "github.com/coreos/etcd/raft"
|
||||
"github.com/coreos/etcd/raft/raftpb"
|
||||
"github.com/coreos/etcd/rafthttp"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"gopkg.in/fatih/set.v0"
|
||||
)
|
||||
|
@ -40,7 +43,7 @@ type ProtocolManager struct {
|
|||
|
||||
// Static configuration
|
||||
joinExisting bool // Whether to join an existing cluster when a WAL doesn't already exist
|
||||
bootstrapNodes []*discover.Node
|
||||
bootstrapNodes []*enode.Node
|
||||
raftId uint16
|
||||
raftPort uint16
|
||||
|
||||
|
@ -95,7 +98,7 @@ type ProtocolManager struct {
|
|||
// Public interface
|
||||
//
|
||||
|
||||
func NewProtocolManager(raftId uint16, raftPort uint16, blockchain *core.BlockChain, mux *event.TypeMux, bootstrapNodes []*discover.Node, joinExisting bool, datadir string, minter *minter, downloader *downloader.Downloader) (*ProtocolManager, error) {
|
||||
func NewProtocolManager(raftId uint16, raftPort uint16, blockchain *core.BlockChain, mux *event.TypeMux, bootstrapNodes []*enode.Node, joinExisting bool, datadir string, minter *minter, downloader *downloader.Downloader) (*ProtocolManager, error) {
|
||||
waldir := fmt.Sprintf("%s/raft-wal", datadir)
|
||||
snapdir := fmt.Sprintf("%s/raft-snap", datadir)
|
||||
quorumRaftDbLoc := fmt.Sprintf("%s/quorum-raft-state", datadir)
|
||||
|
@ -274,7 +277,7 @@ func (pm *ProtocolManager) isRaftIdUsed(raftId uint16) bool {
|
|||
return pm.peers[raftId] != nil
|
||||
}
|
||||
|
||||
func (pm *ProtocolManager) isNodeAlreadyInCluster(node *discover.Node) error {
|
||||
func (pm *ProtocolManager) isNodeAlreadyInCluster(node *enode.Node) error {
|
||||
pm.mu.RLock()
|
||||
defer pm.mu.RUnlock()
|
||||
|
||||
|
@ -282,15 +285,15 @@ func (pm *ProtocolManager) isNodeAlreadyInCluster(node *discover.Node) error {
|
|||
peerRaftId := peer.address.RaftId
|
||||
peerNode := peer.p2pNode
|
||||
|
||||
if peerNode.ID == node.ID {
|
||||
if peerNode.ID() == node.ID() {
|
||||
return fmt.Errorf("node with this enode has already been added to the cluster: %v", node.ID)
|
||||
}
|
||||
|
||||
if peerNode.IP.Equal(node.IP) {
|
||||
if peerNode.TCP == node.TCP {
|
||||
if peerNode.IP().Equal(node.IP()) {
|
||||
if peerNode.TCP() == node.TCP() {
|
||||
return fmt.Errorf("existing node %v with raft ID %v is already using eth p2p at %v:%v", peerNode.ID, peerRaftId, node.IP, node.TCP)
|
||||
} else if peer.address.RaftPort == node.RaftPort {
|
||||
return fmt.Errorf("existing node %v with raft ID %v is already using raft at %v:%v", peerNode.ID, peerRaftId, node.IP, node.RaftPort)
|
||||
} else if peer.address.RaftPort == enr.RAFTPORT(node.RAFTPORT()) {
|
||||
return fmt.Errorf("existing node %v with raft ID %v is already using raft at %v:%v", peerNode.ID, peerRaftId, node.IP, node.RAFTPORT())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,13 +302,13 @@ func (pm *ProtocolManager) isNodeAlreadyInCluster(node *discover.Node) error {
|
|||
}
|
||||
|
||||
func (pm *ProtocolManager) ProposeNewPeer(enodeId string) (uint16, error) {
|
||||
node, err := discover.ParseNode(enodeId)
|
||||
node, err := enode.ParseV4(enodeId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(node.IP) != 4 {
|
||||
return 0, fmt.Errorf("expected IPv4 address (with length 4), but got IP of length %v", len(node.IP))
|
||||
if len(node.IP()) != 4 {
|
||||
return 0, fmt.Errorf("expected IPv4 address (with length 4), but got IP of length %v", len(node.IP()))
|
||||
}
|
||||
|
||||
if !node.HasRaftPort() {
|
||||
|
@ -317,7 +320,7 @@ func (pm *ProtocolManager) ProposeNewPeer(enodeId string) (uint16, error) {
|
|||
}
|
||||
|
||||
raftId := pm.nextRaftId()
|
||||
address := newAddress(raftId, node.RaftPort, node)
|
||||
address := newAddress(raftId, node.RAFTPORT(), node)
|
||||
|
||||
pm.confChangeProposalC <- raftpb.ConfChange{
|
||||
Type: raftpb.ConfChangeAddNode,
|
||||
|
@ -638,14 +641,31 @@ func raftUrl(address *Address) string {
|
|||
return fmt.Sprintf("http://%s:%d", address.Ip, address.RaftPort)
|
||||
}
|
||||
|
||||
func decodePubkey64(b []byte) (*ecdsa.PublicKey, error) {
|
||||
return crypto.UnmarshalPubkey(append([]byte{0x04}, b...))
|
||||
}
|
||||
|
||||
func (pm *ProtocolManager) addPeer(address *Address) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
raftId := address.RaftId
|
||||
|
||||
log.Info("AJ-addPeer:", "raftId", raftId, "nodeId", address.NodeId.String(), "bytes", address.NodeId.Bytes(), "address", address)
|
||||
|
||||
//TODO: Amal to confirm if this decoding is correct
|
||||
//pubKey, err := decodePubkey64(address.NodeId.Bytes())
|
||||
|
||||
/*if err != nil {
|
||||
log.Error("AJ-error decoding pub key", "nodeId", address.NodeId.String(), "err", err)
|
||||
return
|
||||
}*/
|
||||
|
||||
log.Info("addPeer: decoded pub key", "pubKey", address.PubKey)
|
||||
|
||||
// Add P2P connection:
|
||||
p2pNode := discover.NewNode(address.NodeId, address.Ip, 0, uint16(address.P2pPort))
|
||||
p2pNode := enode.NewV4(address.PubKey, address.Ip, 0, int(address.P2pPort), 0)
|
||||
log.Info("AJ-p2pNode", "ID1", address.NodeId.String(), "ID2", p2pNode.ID().String())
|
||||
pm.p2pServer.AddPeer(p2pNode)
|
||||
|
||||
// Add raft transport connection:
|
||||
|
@ -837,7 +857,7 @@ func (pm *ProtocolManager) makeInitialRaftPeers() (raftPeers []etcdRaft.Peer, pe
|
|||
// We initially get the raftPort from the enode ID's query string. As an alternative, we can move away from
|
||||
// requiring the use of static peers for the initial set, and load them from e.g. another JSON file which
|
||||
// contains pairs of enodes and raft ports, or we can get this initial peer list from commandline flags.
|
||||
address := newAddress(raftId, node.RaftPort, node)
|
||||
address := newAddress(raftId, node.RAFTPORT(), node)
|
||||
|
||||
raftPeers[i] = etcdRaft.Peer{
|
||||
ID: uint64(raftId),
|
||||
|
|
35
raft/peer.go
35
raft/peer.go
|
@ -7,34 +7,43 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"crypto/ecdsa"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
const nodeIDBits = 512
|
||||
|
||||
type EnodeID [nodeIDBits / 8]byte
|
||||
|
||||
// Serializable information about a Peer. Sufficient to build `etcdRaft.Peer`
|
||||
// or `discover.Node`.
|
||||
type Address struct {
|
||||
RaftId uint16 `json:"raftId"`
|
||||
NodeId discover.NodeID `json:"nodeId"`
|
||||
NodeId [64]byte `json:"nodeId"`
|
||||
Ip net.IP `json:"ip"`
|
||||
P2pPort uint16 `json:"p2pPort"`
|
||||
RaftPort uint16 `json:"raftPort"`
|
||||
P2pPort enr.TCP `json:"p2pPort"`
|
||||
RaftPort enr.RAFTPORT `json:"raftPort"`
|
||||
PubKey *ecdsa.PublicKey
|
||||
}
|
||||
|
||||
func newAddress(raftId uint16, raftPort uint16, node *discover.Node) *Address {
|
||||
func newAddress(raftId uint16, raftPort int, node *enode.Node) *Address {
|
||||
node.ID().Bytes()
|
||||
return &Address{
|
||||
RaftId: raftId,
|
||||
NodeId: node.ID,
|
||||
Ip: node.IP,
|
||||
P2pPort: node.TCP,
|
||||
RaftPort: raftPort,
|
||||
NodeId: []byte(node.EnodeID()),
|
||||
Ip: node.IP(),
|
||||
P2pPort: enr.TCP(node.TCP()),
|
||||
RaftPort: enr.RAFTPORT(raftPort),
|
||||
PubKey: node.Pubkey(),
|
||||
}
|
||||
}
|
||||
|
||||
// A peer that we're connected to via both raft's http transport, and ethereum p2p
|
||||
type Peer struct {
|
||||
address *Address // For raft transport
|
||||
p2pNode *discover.Node // For ethereum transport
|
||||
p2pNode *enode.Node // For ethereum transport
|
||||
}
|
||||
|
||||
func (addr *Address) EncodeRLP(w io.Writer) error {
|
||||
|
@ -45,10 +54,10 @@ func (addr *Address) DecodeRLP(s *rlp.Stream) error {
|
|||
// These fields need to be public:
|
||||
var temp struct {
|
||||
RaftId uint16
|
||||
NodeId discover.NodeID
|
||||
NodeId enode.ID
|
||||
Ip net.IP
|
||||
P2pPort uint16
|
||||
RaftPort uint16
|
||||
P2pPort enr.TCP
|
||||
RaftPort enr.RAFTPORT
|
||||
}
|
||||
|
||||
if err := s.Decode(&temp); err != nil {
|
||||
|
|
|
@ -37,6 +37,8 @@ func (pm *ProtocolManager) buildSnapshot() *Snapshot {
|
|||
defer pm.mu.RUnlock()
|
||||
|
||||
numNodes := len(pm.confState.Nodes)
|
||||
log.Info("AJ-numNodes", "nodesSize", numNodes, "nodes", pm.confState.Nodes)
|
||||
log.Info("AJ-peers", "pm.peers", pm.peers)
|
||||
numRemovedNodes := pm.removedPeers.Size()
|
||||
|
||||
snapshot := &Snapshot{
|
||||
|
@ -298,8 +300,8 @@ func (pm *ProtocolManager) syncBlockchainUntil(hash common.Hash) {
|
|||
for peerId, peer := range peerMap {
|
||||
log.Info("synchronizing with peer", "peer id", peerId, "hash", hash)
|
||||
|
||||
peerId := peer.p2pNode.ID.String()
|
||||
peerIdPrefix := fmt.Sprintf("%x", peer.p2pNode.ID[:8])
|
||||
peerId := peer.p2pNode.ID().String()
|
||||
peerIdPrefix := fmt.Sprintf("%x", peer.p2pNode.ID().Bytes()[:8])
|
||||
|
||||
if err := pm.downloader.Synchronise(peerIdPrefix, hash, big.NewInt(0), downloader.BoundedFullSync); err != nil {
|
||||
log.Info("failed to synchronize with peer", "peer id", peerId)
|
||||
|
|
|
@ -378,7 +378,7 @@ func RandomAddr() *BzzAddr {
|
|||
if err != nil {
|
||||
panic("unable to generate key")
|
||||
}
|
||||
node := enode.NewV4(&key.PublicKey, net.IP{127, 0, 0, 1}, 30303, 30303)
|
||||
node := enode.NewV4(&key.PublicKey, net.IP{127, 0, 0, 1}, 30303, 30303, 0)
|
||||
return NewAddr(node)
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ func initialize(t *testing.T) {
|
|||
peerNodeId := nodes[j].id
|
||||
address, _ := net.ResolveTCPAddr("tcp", nodes[j].server.ListenAddr)
|
||||
peerPort := uint16(address.Port)
|
||||
peer := enode.NewV4(&peerNodeId.PublicKey, address.IP, int(peerPort), int(peerPort))
|
||||
peer := enode.NewV4(&peerNodeId.PublicKey, address.IP, int(peerPort), int(peerPort), 0)
|
||||
node.server.AddPeer(peer)
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ func initialize(t *testing.T) {
|
|||
for j := 0; j < i; j++ {
|
||||
peerNodeId := nodes[j].id
|
||||
address, _ := net.ResolveTCPAddr("tcp", nodes[j].server.ListenAddr)
|
||||
peer := enode.NewV4(&peerNodeId.PublicKey, address.IP, address.Port, address.Port)
|
||||
peer := enode.NewV4(&peerNodeId.PublicKey, address.IP, address.Port, address.Port, 0)
|
||||
nodes[i].server.AddPeer(peer)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue