mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
CLO 1.8.11
This commit is contained in:
commit
9b418eecda
19 changed files with 201 additions and 89 deletions
|
|
@ -140,8 +140,8 @@ func processArgs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if *asymmetricMode && len(*argPub) > 0 {
|
if *asymmetricMode && len(*argPub) > 0 {
|
||||||
pub = crypto.ToECDSAPub(common.FromHex(*argPub))
|
var err error
|
||||||
if !isKeyValid(pub) {
|
if pub, err = crypto.UnmarshalPubkey(common.FromHex(*argPub)); err != nil {
|
||||||
utils.Fatalf("invalid public key")
|
utils.Fatalf("invalid public key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -321,10 +321,6 @@ func startServer() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func isKeyValid(k *ecdsa.PublicKey) bool {
|
|
||||||
return k.X != nil && k.Y != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func configureNode() {
|
func configureNode() {
|
||||||
var err error
|
var err error
|
||||||
var p2pAccept bool
|
var p2pAccept bool
|
||||||
|
|
@ -340,9 +336,8 @@ func configureNode() {
|
||||||
if b == nil {
|
if b == nil {
|
||||||
utils.Fatalf("Error: can not convert hexadecimal string")
|
utils.Fatalf("Error: can not convert hexadecimal string")
|
||||||
}
|
}
|
||||||
pub = crypto.ToECDSAPub(b)
|
if pub, err = crypto.UnmarshalPubkey(b); err != nil {
|
||||||
if !isKeyValid(pub) {
|
utils.Fatalf("Error: invalid peer public key")
|
||||||
utils.Fatalf("Error: invalid public key")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1524,6 +1524,18 @@ func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []com
|
||||||
return bc.hc.GetBlockHashesFromHash(hash, max)
|
return bc.hc.GetBlockHashesFromHash(hash, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
|
||||||
|
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
|
||||||
|
// number of blocks to be individually checked before we reach the canonical chain.
|
||||||
|
//
|
||||||
|
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
|
||||||
|
func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
|
||||||
|
bc.chainmu.Lock()
|
||||||
|
defer bc.chainmu.Unlock()
|
||||||
|
|
||||||
|
return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
|
||||||
|
}
|
||||||
|
|
||||||
// GetHeaderByNumber retrieves a block header from the database by number,
|
// GetHeaderByNumber retrieves a block header from the database by number,
|
||||||
// caching it (associated with its hash) if found.
|
// caching it (associated with its hash) if found.
|
||||||
func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,43 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co
|
||||||
return chain
|
return chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
|
||||||
|
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
|
||||||
|
// number of blocks to be individually checked before we reach the canonical chain.
|
||||||
|
//
|
||||||
|
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
|
||||||
|
func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
|
||||||
|
if ancestor > number {
|
||||||
|
return common.Hash{}, 0
|
||||||
|
}
|
||||||
|
if ancestor == 1 {
|
||||||
|
// in this case it is cheaper to just read the header
|
||||||
|
if header := hc.GetHeader(hash, number); header != nil {
|
||||||
|
return header.ParentHash, number - 1
|
||||||
|
} else {
|
||||||
|
return common.Hash{}, 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ancestor != 0 {
|
||||||
|
if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash {
|
||||||
|
number -= ancestor
|
||||||
|
return rawdb.ReadCanonicalHash(hc.chainDb, number), number
|
||||||
|
}
|
||||||
|
if *maxNonCanonical == 0 {
|
||||||
|
return common.Hash{}, 0
|
||||||
|
}
|
||||||
|
*maxNonCanonical--
|
||||||
|
ancestor--
|
||||||
|
header := hc.GetHeader(hash, number)
|
||||||
|
if header == nil {
|
||||||
|
return common.Hash{}, 0
|
||||||
|
}
|
||||||
|
hash = header.ParentHash
|
||||||
|
number--
|
||||||
|
}
|
||||||
|
return hash, number
|
||||||
|
}
|
||||||
|
|
||||||
// GetTd retrieves a block's total difficulty in the canonical chain from the
|
// GetTd retrieves a block's total difficulty in the canonical chain from the
|
||||||
// database by hash and number, caching it if found.
|
// database by hash and number, caching it if found.
|
||||||
func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
|
func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ var (
|
||||||
secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
|
secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var errInvalidPubkey = errors.New("invalid secp256k1 public key")
|
||||||
|
|
||||||
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
||||||
func Keccak256(data ...[]byte) []byte {
|
func Keccak256(data ...[]byte) []byte {
|
||||||
d := sha3.NewKeccak256()
|
d := sha3.NewKeccak256()
|
||||||
|
|
@ -122,12 +124,13 @@ func FromECDSA(priv *ecdsa.PrivateKey) []byte {
|
||||||
return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
|
return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
|
// UnmarshalPubkey converts bytes to a secp256k1 public key.
|
||||||
if len(pub) == 0 {
|
func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
|
||||||
return nil
|
|
||||||
}
|
|
||||||
x, y := elliptic.Unmarshal(S256(), pub)
|
x, y := elliptic.Unmarshal(S256(), pub)
|
||||||
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}
|
if x == nil {
|
||||||
|
return nil, errInvalidPubkey
|
||||||
|
}
|
||||||
|
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
|
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,11 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/EthereumCommonwealth/go-callisto/common"
|
"github.com/EthereumCommonwealth/go-callisto/common"
|
||||||
|
"github.com/EthereumCommonwealth/go-callisto/common/hexutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
|
var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
|
||||||
|
|
@ -56,6 +58,33 @@ func BenchmarkSha3(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalPubkey(t *testing.T) {
|
||||||
|
key, err := UnmarshalPubkey(nil)
|
||||||
|
if err != errInvalidPubkey || key != nil {
|
||||||
|
t.Fatalf("expected error, got %v, %v", err, key)
|
||||||
|
}
|
||||||
|
key, err = UnmarshalPubkey([]byte{1, 2, 3})
|
||||||
|
if err != errInvalidPubkey || key != nil {
|
||||||
|
t.Fatalf("expected error, got %v, %v", err, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d")
|
||||||
|
dec = &ecdsa.PublicKey{
|
||||||
|
Curve: S256(),
|
||||||
|
X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"),
|
||||||
|
Y: hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
key, err = UnmarshalPubkey(enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(key, dec) {
|
||||||
|
t.Fatal("wrong result")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSign(t *testing.T) {
|
func TestSign(t *testing.T) {
|
||||||
key, _ := HexToECDSA(testPrivHex)
|
key, _ := HexToECDSA(testPrivHex)
|
||||||
addr := common.HexToAddress(testAddrHex)
|
addr := common.HexToAddress(testAddrHex)
|
||||||
|
|
@ -69,7 +98,7 @@ func TestSign(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("ECRecover error: %s", err)
|
t.Errorf("ECRecover error: %s", err)
|
||||||
}
|
}
|
||||||
pubKey := ToECDSAPub(recoveredPub)
|
pubKey, _ := UnmarshalPubkey(recoveredPub)
|
||||||
recoveredAddr := PubkeyToAddress(*pubKey)
|
recoveredAddr := PubkeyToAddress(*pubKey)
|
||||||
if addr != recoveredAddr {
|
if addr != recoveredAddr {
|
||||||
t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
|
t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
return errResp(ErrDecode, "%v: %v", msg, err)
|
return errResp(ErrDecode, "%v: %v", msg, err)
|
||||||
}
|
}
|
||||||
hashMode := query.Origin.Hash != (common.Hash{})
|
hashMode := query.Origin.Hash != (common.Hash{})
|
||||||
|
first := true
|
||||||
|
maxNonCanonical := uint64(100)
|
||||||
|
|
||||||
// Gather headers until the fetch or network limits is reached
|
// Gather headers until the fetch or network limits is reached
|
||||||
var (
|
var (
|
||||||
|
|
@ -351,31 +353,36 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
// Retrieve the next header satisfying the query
|
// Retrieve the next header satisfying the query
|
||||||
var origin *types.Header
|
var origin *types.Header
|
||||||
if hashMode {
|
if hashMode {
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash)
|
origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash)
|
||||||
|
if origin != nil {
|
||||||
|
query.Origin.Number = origin.Number.Uint64()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
origin = pm.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number)
|
origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number)
|
||||||
}
|
}
|
||||||
if origin == nil {
|
if origin == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
number := origin.Number.Uint64()
|
|
||||||
headers = append(headers, origin)
|
headers = append(headers, origin)
|
||||||
bytes += estHeaderRlpSize
|
bytes += estHeaderRlpSize
|
||||||
|
|
||||||
// Advance to the next header of the query
|
// Advance to the next header of the query
|
||||||
switch {
|
switch {
|
||||||
case query.Origin.Hash != (common.Hash{}) && query.Reverse:
|
case hashMode && query.Reverse:
|
||||||
// Hash based traversal towards the genesis block
|
// Hash based traversal towards the genesis block
|
||||||
for i := 0; i < int(query.Skip)+1; i++ {
|
ancestor := query.Skip + 1
|
||||||
if header := pm.blockchain.GetHeader(query.Origin.Hash, number); header != nil {
|
if ancestor == 0 {
|
||||||
query.Origin.Hash = header.ParentHash
|
|
||||||
number--
|
|
||||||
} else {
|
|
||||||
unknown = true
|
unknown = true
|
||||||
break
|
} else {
|
||||||
|
query.Origin.Hash, query.Origin.Number = pm.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical)
|
||||||
|
unknown = (query.Origin.Hash == common.Hash{})
|
||||||
}
|
}
|
||||||
}
|
case hashMode && !query.Reverse:
|
||||||
case query.Origin.Hash != (common.Hash{}) && !query.Reverse:
|
|
||||||
// Hash based traversal towards the leaf block
|
// Hash based traversal towards the leaf block
|
||||||
var (
|
var (
|
||||||
current = origin.Number.Uint64()
|
current = origin.Number.Uint64()
|
||||||
|
|
@ -387,8 +394,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
unknown = true
|
unknown = true
|
||||||
} else {
|
} else {
|
||||||
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
||||||
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
|
nextHash := header.Hash()
|
||||||
query.Origin.Hash = header.Hash()
|
expOldHash, _ := pm.blockchain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical)
|
||||||
|
if expOldHash == query.Origin.Hash {
|
||||||
|
query.Origin.Hash, query.Origin.Number = nextHash, next
|
||||||
} else {
|
} else {
|
||||||
unknown = true
|
unknown = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -461,13 +461,11 @@ func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Byt
|
||||||
}
|
}
|
||||||
sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1
|
sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1
|
||||||
|
|
||||||
rpk, err := crypto.Ecrecover(signHash(data), sig)
|
rpk, err := crypto.SigToPub(signHash(data), sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
pubKey := crypto.ToECDSAPub(rpk)
|
return crypto.PubkeyToAddress(*rpk), nil
|
||||||
recoveredAddr := crypto.PubkeyToAddress(*pubKey)
|
|
||||||
return recoveredAddr, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignAndSendTransaction was renamed to SendTransaction. This method is deprecated
|
// SignAndSendTransaction was renamed to SendTransaction. This method is deprecated
|
||||||
|
|
@ -1302,14 +1300,19 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen
|
||||||
return &SignTransactionResult{data, tx}, nil
|
return &SignTransactionResult{data, tx}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PendingTransactions returns the transactions that are in the transaction pool and have a from address that is one of
|
// PendingTransactions returns the transactions that are in the transaction pool
|
||||||
// the accounts this node manages.
|
// and have a from address that is one of the accounts this node manages.
|
||||||
func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) {
|
func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) {
|
||||||
pending, err := s.b.GetPoolTransactions()
|
pending, err := s.b.GetPoolTransactions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
accounts := make(map[common.Address]struct{})
|
||||||
|
for _, wallet := range s.b.AccountManager().Wallets() {
|
||||||
|
for _, account := range wallet.Accounts() {
|
||||||
|
accounts[account.Address] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
transactions := make([]*RPCTransaction, 0, len(pending))
|
transactions := make([]*RPCTransaction, 0, len(pending))
|
||||||
for _, tx := range pending {
|
for _, tx := range pending {
|
||||||
var signer types.Signer = types.HomesteadSigner{}
|
var signer types.Signer = types.HomesteadSigner{}
|
||||||
|
|
@ -1317,7 +1320,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
|
||||||
signer = types.NewEIP155Signer(tx.ChainId())
|
signer = types.NewEIP155Signer(tx.ChainId())
|
||||||
}
|
}
|
||||||
from, _ := types.Sender(signer, tx)
|
from, _ := types.Sender(signer, tx)
|
||||||
if _, err := s.b.AccountManager().Find(accounts.Account{Address: from}); err == nil {
|
if _, exists := accounts[from]; exists {
|
||||||
transactions = append(transactions, newRPCPendingTransaction(tx))
|
transactions = append(transactions, newRPCPendingTransaction(tx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay)
|
leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay)
|
||||||
if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, true, ClientProtocolVersions, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, quitSync, &leth.wg); err != nil {
|
if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, true, ClientProtocolVersions, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, leth.serverPool, quitSync, &leth.wg); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
leth.ApiBackend = &LesApiBackend{leth, nil}
|
leth.ApiBackend = &LesApiBackend{leth, nil}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ type BlockChain interface {
|
||||||
InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error)
|
InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error)
|
||||||
Rollback(chain []common.Hash)
|
Rollback(chain []common.Hash)
|
||||||
GetHeaderByNumber(number uint64) *types.Header
|
GetHeaderByNumber(number uint64) *types.Header
|
||||||
GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash
|
GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64)
|
||||||
Genesis() *types.Block
|
Genesis() *types.Block
|
||||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +129,7 @@ type ProtocolManager struct {
|
||||||
|
|
||||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
// with the ethereum network.
|
// with the ethereum network.
|
||||||
func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protocolVersions []uint, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) {
|
func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protocolVersions []uint, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, serverPool *serverPool, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) {
|
||||||
// Create the protocol manager with the base fields
|
// Create the protocol manager with the base fields
|
||||||
manager := &ProtocolManager{
|
manager := &ProtocolManager{
|
||||||
lightSync: lightSync,
|
lightSync: lightSync,
|
||||||
|
|
@ -141,6 +141,7 @@ func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protoco
|
||||||
networkId: networkId,
|
networkId: networkId,
|
||||||
txpool: txpool,
|
txpool: txpool,
|
||||||
txrelay: txrelay,
|
txrelay: txrelay,
|
||||||
|
serverPool: serverPool,
|
||||||
peers: peers,
|
peers: peers,
|
||||||
newPeerCh: make(chan *peer),
|
newPeerCh: make(chan *peer),
|
||||||
quitSync: quitSync,
|
quitSync: quitSync,
|
||||||
|
|
@ -418,6 +419,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
hashMode := query.Origin.Hash != (common.Hash{})
|
hashMode := query.Origin.Hash != (common.Hash{})
|
||||||
|
first := true
|
||||||
|
maxNonCanonical := uint64(100)
|
||||||
|
|
||||||
// Gather headers until the fetch or network limits is reached
|
// Gather headers until the fetch or network limits is reached
|
||||||
var (
|
var (
|
||||||
|
|
@ -429,14 +432,21 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
// Retrieve the next header satisfying the query
|
// Retrieve the next header satisfying the query
|
||||||
var origin *types.Header
|
var origin *types.Header
|
||||||
if hashMode {
|
if hashMode {
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash)
|
origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash)
|
||||||
|
if origin != nil {
|
||||||
|
query.Origin.Number = origin.Number.Uint64()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
origin = pm.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number)
|
origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number)
|
||||||
}
|
}
|
||||||
if origin == nil {
|
if origin == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
number := origin.Number.Uint64()
|
|
||||||
headers = append(headers, origin)
|
headers = append(headers, origin)
|
||||||
bytes += estHeaderRlpSize
|
bytes += estHeaderRlpSize
|
||||||
|
|
||||||
|
|
@ -444,14 +454,12 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
switch {
|
switch {
|
||||||
case hashMode && query.Reverse:
|
case hashMode && query.Reverse:
|
||||||
// Hash based traversal towards the genesis block
|
// Hash based traversal towards the genesis block
|
||||||
for i := 0; i < int(query.Skip)+1; i++ {
|
ancestor := query.Skip + 1
|
||||||
if header := pm.blockchain.GetHeader(query.Origin.Hash, number); header != nil {
|
if ancestor == 0 {
|
||||||
query.Origin.Hash = header.ParentHash
|
|
||||||
number--
|
|
||||||
} else {
|
|
||||||
unknown = true
|
unknown = true
|
||||||
break
|
} else {
|
||||||
}
|
query.Origin.Hash, query.Origin.Number = pm.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical)
|
||||||
|
unknown = (query.Origin.Hash == common.Hash{})
|
||||||
}
|
}
|
||||||
case hashMode && !query.Reverse:
|
case hashMode && !query.Reverse:
|
||||||
// Hash based traversal towards the leaf block
|
// Hash based traversal towards the leaf block
|
||||||
|
|
@ -465,8 +473,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
unknown = true
|
unknown = true
|
||||||
} else {
|
} else {
|
||||||
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
||||||
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
|
nextHash := header.Hash()
|
||||||
query.Origin.Hash = header.Hash()
|
expOldHash, _ := pm.blockchain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical)
|
||||||
|
if expOldHash == query.Origin.Hash {
|
||||||
|
query.Origin.Hash, query.Origin.Number = nextHash, next
|
||||||
} else {
|
} else {
|
||||||
unknown = true
|
unknown = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
|
||||||
} else {
|
} else {
|
||||||
protocolVersions = ServerProtocolVersions
|
protocolVersions = ServerProtocolVersions
|
||||||
}
|
}
|
||||||
pm, err := NewProtocolManager(gspec.Config, lightSync, protocolVersions, NetworkId, evmux, engine, peers, chain, nil, db, odr, nil, make(chan struct{}), new(sync.WaitGroup))
|
pm, err := NewProtocolManager(gspec.Config, lightSync, protocolVersions, NetworkId, evmux, engine, peers, chain, nil, db, odr, nil, nil, make(chan struct{}), new(sync.WaitGroup))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ type sentReq struct {
|
||||||
lock sync.RWMutex // protect access to sentTo map
|
lock sync.RWMutex // protect access to sentTo map
|
||||||
sentTo map[distPeer]sentReqToPeer
|
sentTo map[distPeer]sentReqToPeer
|
||||||
|
|
||||||
reqQueued bool // a request has been queued but not sent
|
lastReqQueued bool // last request has been queued but not sent
|
||||||
reqSent bool // a request has been sent but not timed out
|
lastReqSentTo distPeer // if not nil then last request has been sent to given peer but not timed out
|
||||||
reqSrtoCount int // number of requests that reached soft (but not hard) timeout
|
reqSrtoCount int // number of requests that reached soft (but not hard) timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,7 +180,7 @@ type reqStateFn func() reqStateFn
|
||||||
// retrieveLoop is the retrieval state machine event loop
|
// retrieveLoop is the retrieval state machine event loop
|
||||||
func (r *sentReq) retrieveLoop() {
|
func (r *sentReq) retrieveLoop() {
|
||||||
go r.tryRequest()
|
go r.tryRequest()
|
||||||
r.reqQueued = true
|
r.lastReqQueued = true
|
||||||
state := r.stateRequesting
|
state := r.stateRequesting
|
||||||
|
|
||||||
for state != nil {
|
for state != nil {
|
||||||
|
|
@ -214,7 +214,7 @@ func (r *sentReq) stateRequesting() reqStateFn {
|
||||||
case rpSoftTimeout:
|
case rpSoftTimeout:
|
||||||
// last request timed out, try asking a new peer
|
// last request timed out, try asking a new peer
|
||||||
go r.tryRequest()
|
go r.tryRequest()
|
||||||
r.reqQueued = true
|
r.lastReqQueued = true
|
||||||
return r.stateRequesting
|
return r.stateRequesting
|
||||||
case rpDeliveredValid:
|
case rpDeliveredValid:
|
||||||
r.stop(nil)
|
r.stop(nil)
|
||||||
|
|
@ -233,7 +233,7 @@ func (r *sentReq) stateNoMorePeers() reqStateFn {
|
||||||
select {
|
select {
|
||||||
case <-time.After(retryQueue):
|
case <-time.After(retryQueue):
|
||||||
go r.tryRequest()
|
go r.tryRequest()
|
||||||
r.reqQueued = true
|
r.lastReqQueued = true
|
||||||
return r.stateRequesting
|
return r.stateRequesting
|
||||||
case ev := <-r.eventsCh:
|
case ev := <-r.eventsCh:
|
||||||
r.update(ev)
|
r.update(ev)
|
||||||
|
|
@ -260,22 +260,26 @@ func (r *sentReq) stateStopped() reqStateFn {
|
||||||
func (r *sentReq) update(ev reqPeerEvent) {
|
func (r *sentReq) update(ev reqPeerEvent) {
|
||||||
switch ev.event {
|
switch ev.event {
|
||||||
case rpSent:
|
case rpSent:
|
||||||
r.reqQueued = false
|
r.lastReqQueued = false
|
||||||
if ev.peer != nil {
|
r.lastReqSentTo = ev.peer
|
||||||
r.reqSent = true
|
|
||||||
}
|
|
||||||
case rpSoftTimeout:
|
case rpSoftTimeout:
|
||||||
r.reqSent = false
|
r.lastReqSentTo = nil
|
||||||
r.reqSrtoCount++
|
r.reqSrtoCount++
|
||||||
case rpHardTimeout, rpDeliveredValid, rpDeliveredInvalid:
|
case rpHardTimeout:
|
||||||
r.reqSrtoCount--
|
r.reqSrtoCount--
|
||||||
|
case rpDeliveredValid, rpDeliveredInvalid:
|
||||||
|
if ev.peer == r.lastReqSentTo {
|
||||||
|
r.lastReqSentTo = nil
|
||||||
|
} else {
|
||||||
|
r.reqSrtoCount--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// waiting returns true if the retrieval mechanism is waiting for an answer from
|
// waiting returns true if the retrieval mechanism is waiting for an answer from
|
||||||
// any peer
|
// any peer
|
||||||
func (r *sentReq) waiting() bool {
|
func (r *sentReq) waiting() bool {
|
||||||
return r.reqQueued || r.reqSent || r.reqSrtoCount > 0
|
return r.lastReqQueued || r.lastReqSentTo != nil || r.reqSrtoCount > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// tryRequest tries to send the request to a new peer and waits for it to either
|
// tryRequest tries to send the request to a new peer and waits for it to either
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ type LesServer struct {
|
||||||
|
|
||||||
func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
|
func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
|
||||||
quitSync := make(chan struct{})
|
quitSync := make(chan struct{})
|
||||||
pm, err := NewProtocolManager(eth.BlockChain().Config(), false, ServerProtocolVersions, config.NetworkId, eth.EventMux(), eth.Engine(), newPeerSet(), eth.BlockChain(), eth.TxPool(), eth.ChainDb(), nil, nil, quitSync, new(sync.WaitGroup))
|
pm, err := NewProtocolManager(eth.BlockChain().Config(), false, ServerProtocolVersions, config.NetworkId, eth.EventMux(), eth.Engine(), newPeerSet(), eth.BlockChain(), eth.TxPool(), eth.ChainDb(), nil, nil, nil, quitSync, new(sync.WaitGroup))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -433,6 +433,18 @@ func (self *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []c
|
||||||
return self.hc.GetBlockHashesFromHash(hash, max)
|
return self.hc.GetBlockHashesFromHash(hash, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
|
||||||
|
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
|
||||||
|
// number of blocks to be individually checked before we reach the canonical chain.
|
||||||
|
//
|
||||||
|
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
|
||||||
|
func (bc *LightChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
|
||||||
|
bc.chainmu.Lock()
|
||||||
|
defer bc.chainmu.Unlock()
|
||||||
|
|
||||||
|
return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
|
||||||
|
}
|
||||||
|
|
||||||
// GetHeaderByNumber retrieves a block header from the database by number,
|
// GetHeaderByNumber retrieves a block header from the database by number,
|
||||||
// caching it (associated with its hash) if found.
|
// caching it (associated with its hash) if found.
|
||||||
func (self *LightChain) GetHeaderByNumber(number uint64) *types.Header {
|
func (self *LightChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
|
|
||||||
|
|
@ -528,9 +528,9 @@ func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) {
|
||||||
return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey))
|
return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey))
|
||||||
}
|
}
|
||||||
// TODO: fewer pointless conversions
|
// TODO: fewer pointless conversions
|
||||||
pub := crypto.ToECDSAPub(pubKey65)
|
pub, err := crypto.UnmarshalPubkey(pubKey65)
|
||||||
if pub.X == nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid public key")
|
return nil, err
|
||||||
}
|
}
|
||||||
return ecies.ImportECDSAPublic(pub), nil
|
return ecies.ImportECDSAPublic(pub), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -432,13 +432,11 @@ func (api *SignerAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (c
|
||||||
}
|
}
|
||||||
sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1
|
sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1
|
||||||
hash, _ := SignHash(data)
|
hash, _ := SignHash(data)
|
||||||
rpk, err := crypto.Ecrecover(hash, sig)
|
rpk, err := crypto.SigToPub(hash, sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
pubKey := crypto.ToECDSAPub(rpk)
|
return crypto.PubkeyToAddress(*rpk), nil
|
||||||
recoveredAddr := crypto.PubkeyToAddress(*pubKey)
|
|
||||||
return recoveredAddr, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignHash is a helper function that calculates a hash for the given message that can be
|
// SignHash is a helper function that calculates a hash for the given message that can be
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package swap
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -134,6 +135,11 @@ func NewSwap(local *SwapParams, remote *SwapProfile, backend chequebook.Backend,
|
||||||
out *chequebook.Outbox
|
out *chequebook.Outbox
|
||||||
)
|
)
|
||||||
|
|
||||||
|
remotekey, err := crypto.UnmarshalPubkey(common.FromHex(remote.PublicKey))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("invalid remote public key")
|
||||||
|
}
|
||||||
|
|
||||||
// check if remote chequebook is valid
|
// check if remote chequebook is valid
|
||||||
// insolvent chequebooks suicide so will signal as invalid
|
// insolvent chequebooks suicide so will signal as invalid
|
||||||
// TODO: monitoring a chequebooks events
|
// TODO: monitoring a chequebooks events
|
||||||
|
|
@ -142,7 +148,7 @@ func NewSwap(local *SwapParams, remote *SwapProfile, backend chequebook.Backend,
|
||||||
log.Info(fmt.Sprintf("invalid contract %v for peer %v: %v)", remote.Contract.Hex()[:8], proto, err))
|
log.Info(fmt.Sprintf("invalid contract %v for peer %v: %v)", remote.Contract.Hex()[:8], proto, err))
|
||||||
} else {
|
} else {
|
||||||
// remote contract valid, create inbox
|
// remote contract valid, create inbox
|
||||||
in, err = chequebook.NewInbox(local.privateKey, remote.Contract, local.Beneficiary, crypto.ToECDSAPub(common.FromHex(remote.PublicKey)), backend)
|
in, err = chequebook.NewInbox(local.privateKey, remote.Contract, local.Beneficiary, remotekey, backend)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(fmt.Sprintf("unable to set up inbox for chequebook contract %v for peer %v: %v)", remote.Contract.Hex()[:8], proto, err))
|
log.Warn(fmt.Sprintf("unable to set up inbox for chequebook contract %v for peer %v: %v)", remote.Contract.Hex()[:8], proto, err))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -252,8 +252,7 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er
|
||||||
|
|
||||||
// Set asymmetric key that is used to encrypt the message
|
// Set asymmetric key that is used to encrypt the message
|
||||||
if pubKeyGiven {
|
if pubKeyGiven {
|
||||||
params.Dst = crypto.ToECDSAPub(req.PublicKey)
|
if params.Dst, err = crypto.UnmarshalPubkey(req.PublicKey); err != nil {
|
||||||
if !ValidatePublicKey(params.Dst) {
|
|
||||||
return false, ErrInvalidPublicKey
|
return false, ErrInvalidPublicKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -329,8 +328,7 @@ func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc.
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(crit.Sig) > 0 {
|
if len(crit.Sig) > 0 {
|
||||||
filter.Src = crypto.ToECDSAPub(crit.Sig)
|
if filter.Src, err = crypto.UnmarshalPubkey(crit.Sig); err != nil {
|
||||||
if !ValidatePublicKey(filter.Src) {
|
|
||||||
return nil, ErrInvalidSigningPubKey
|
return nil, ErrInvalidSigningPubKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -513,8 +511,7 @@ func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(req.Sig) > 0 {
|
if len(req.Sig) > 0 {
|
||||||
src = crypto.ToECDSAPub(req.Sig)
|
if src, err = crypto.UnmarshalPubkey(req.Sig); err != nil {
|
||||||
if !ValidatePublicKey(src) {
|
|
||||||
return "", ErrInvalidSigningPubKey
|
return "", ErrInvalidSigningPubKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -272,8 +272,7 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (hexutil.
|
||||||
|
|
||||||
// Set asymmetric key that is used to encrypt the message
|
// Set asymmetric key that is used to encrypt the message
|
||||||
if pubKeyGiven {
|
if pubKeyGiven {
|
||||||
params.Dst = crypto.ToECDSAPub(req.PublicKey)
|
if params.Dst, err = crypto.UnmarshalPubkey(req.PublicKey); err != nil {
|
||||||
if !ValidatePublicKey(params.Dst) {
|
|
||||||
return nil, ErrInvalidPublicKey
|
return nil, ErrInvalidPublicKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -360,8 +359,7 @@ func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc.
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(crit.Sig) > 0 {
|
if len(crit.Sig) > 0 {
|
||||||
filter.Src = crypto.ToECDSAPub(crit.Sig)
|
if filter.Src, err = crypto.UnmarshalPubkey(crit.Sig); err != nil {
|
||||||
if !ValidatePublicKey(filter.Src) {
|
|
||||||
return nil, ErrInvalidSigningPubKey
|
return nil, ErrInvalidSigningPubKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -544,8 +542,7 @@ func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(req.Sig) > 0 {
|
if len(req.Sig) > 0 {
|
||||||
src = crypto.ToECDSAPub(req.Sig)
|
if src, err = crypto.UnmarshalPubkey(req.Sig); err != nil {
|
||||||
if !ValidatePublicKey(src) {
|
|
||||||
return "", ErrInvalidSigningPubKey
|
return "", ErrInvalidSigningPubKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue