mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
les: lespay API
This commit is contained in:
parent
be4fb5757a
commit
db4bc521a3
9 changed files with 146 additions and 15 deletions
|
|
@ -33,6 +33,7 @@ var Modules = map[string]string{
|
|||
"swarmfs": SwarmfsJs,
|
||||
"txpool": TxpoolJs,
|
||||
"les": LESJs,
|
||||
"lespay": LESPAYJs,
|
||||
}
|
||||
|
||||
const ChequebookJs = `
|
||||
|
|
@ -856,3 +857,20 @@ web3._extend({
|
|||
]
|
||||
});
|
||||
`
|
||||
|
||||
const LESPAYJs = `
|
||||
web3._extend({
|
||||
property: 'lespay',
|
||||
methods:
|
||||
[
|
||||
new web3._extend.Method({
|
||||
name: 'connection',
|
||||
call: 'lespay_connection',
|
||||
params: 6
|
||||
}),
|
||||
],
|
||||
properties:
|
||||
[
|
||||
]
|
||||
});
|
||||
`
|
||||
|
|
|
|||
102
les/api.go
102
les/api.go
|
|
@ -17,13 +17,16 @@
|
|||
package les
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/mclock"
|
||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -349,3 +352,102 @@ func (api *PrivateLightAPI) GetCheckpointContractAddress() (string, error) {
|
|||
}
|
||||
return api.backend.oracle.config.Address.Hex(), nil
|
||||
}
|
||||
|
||||
type PrivateLespayAPI struct {
|
||||
peerSet *peerSet
|
||||
clientHandler *clientHandler
|
||||
dht *discv5.Network
|
||||
tokenSale *tokenSale
|
||||
}
|
||||
|
||||
// NewPrivateLespayAPI creates a new LESPAY API.
|
||||
func NewPrivateLespayAPI(peerSet *peerSet, clientHandler *clientHandler, dht *discv5.Network, tokenSale *tokenSale) *PrivateLespayAPI {
|
||||
return &PrivateLespayAPI{
|
||||
peerSet: peerSet,
|
||||
clientHandler: clientHandler,
|
||||
dht: dht,
|
||||
tokenSale: tokenSale,
|
||||
}
|
||||
}
|
||||
|
||||
func (api *PrivateLespayAPI) makeCall(ctx context.Context, remote bool, nodeStr string, cmd []byte) ([]byte, error) {
|
||||
var (
|
||||
id enode.ID
|
||||
freeID string
|
||||
peer *peer
|
||||
node *enode.Node
|
||||
)
|
||||
if nodeStr != "" {
|
||||
if peer = api.peerSet.Peer(nodeStr); peer != nil {
|
||||
id = peer.ID()
|
||||
freeID = peer.freeClientId()
|
||||
} else {
|
||||
var err error
|
||||
if node, err = enode.Parse(enode.ValidSchemes, nodeStr); err == nil {
|
||||
id = node.ID()
|
||||
freeID = node.IP().String()
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if remote {
|
||||
var (
|
||||
reply []byte
|
||||
cancelFn func() bool
|
||||
)
|
||||
delivered := make(chan struct{})
|
||||
if peer != nil {
|
||||
// remote call to a connected peer through LES
|
||||
if api.clientHandler == nil {
|
||||
return nil, errors.New("client handler not available")
|
||||
}
|
||||
cancelFn = api.clientHandler.makeLespayCall(peer, [][]byte{cmd}, func(replies [][]byte) bool {
|
||||
if len(replies) == 1 {
|
||||
reply = replies[0]
|
||||
}
|
||||
close(delivered)
|
||||
return reply != nil
|
||||
})
|
||||
} else {
|
||||
// remote call through UDP TALK
|
||||
if api.dht == nil {
|
||||
return nil, errors.New("UDP DHT not available")
|
||||
}
|
||||
cancelFn = api.dht.SendTalkRequest(node, "lespay", [][]byte{cmd}, func(payload interface{}) bool {
|
||||
if replies, ok := payload.([][]byte); ok && len(replies) == 1 {
|
||||
reply = replies[0]
|
||||
}
|
||||
close(delivered)
|
||||
return reply != nil
|
||||
})
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
cancelFn()
|
||||
return nil, ctx.Err()
|
||||
case <-delivered:
|
||||
return reply, nil
|
||||
}
|
||||
} else {
|
||||
if api.tokenSale == nil {
|
||||
return nil, errors.New("token sale module not available")
|
||||
}
|
||||
// execute call locally
|
||||
return api.tokenSale.runCommand(cmd, id, freeID), nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (api *PrivateLespayAPI) Connection(ctx context.Context, remote bool, node string, requestedCapacity, stayConnected uint64, paymentModule []string, setCap bool) (results tsConnectionResults, err error) {
|
||||
params := tsConnectionParams{requestedCapacity, stayConnected, paymentModule, setCap}
|
||||
enc, _ := rlp.EncodeToBytes(¶ms)
|
||||
var resEnc []byte
|
||||
resEnc, err = api.makeCall(ctx, remote, node, enc)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = rlp.DecodeBytes(resEnc, &results)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import (
|
|||
type LightEthereum struct {
|
||||
lesCommons
|
||||
|
||||
srvr *p2p.Server
|
||||
reqDist *requestDistributor
|
||||
retriever *retrieveManager
|
||||
odr *LesOdr
|
||||
|
|
@ -206,6 +207,12 @@ func (s *LightEthereum) APIs() []rpc.API {
|
|||
Service: NewPrivateLightAPI(&s.lesCommons),
|
||||
Public: false,
|
||||
},
|
||||
{
|
||||
Namespace: "lespay",
|
||||
Version: "1.0",
|
||||
Service: NewPrivateLespayAPI(s.lesCommons.peers, s.handler, s.srvr.DiscV5, nil),
|
||||
Public: false,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
|
|
@ -235,6 +242,7 @@ func (s *LightEthereum) Protocols() []p2p.Protocol {
|
|||
// light ethereum protocol implementation.
|
||||
func (s *LightEthereum) Start(srvr *p2p.Server) error {
|
||||
log.Warn("Light client mode is an experimental feature")
|
||||
s.srvr = srvr
|
||||
|
||||
// Start bloom request workers.
|
||||
s.wg.Add(bloomServiceThreads)
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ func (h *clientHandler) handleMsg(p *peer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (h *clientHandler) sendLespayCommands(p *peer, cmds [][]byte, handler func([][]byte) bool) func() bool {
|
||||
func (h *clientHandler) makeLespayCall(p *peer, cmds [][]byte, handler func([][]byte) bool) func() bool {
|
||||
reqID := genReqID()
|
||||
if p.SendLespay(reqID, cmds) != nil {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -149,6 +149,12 @@ func (s *LesServer) APIs() []rpc.API {
|
|||
Service: NewPrivateDebugAPI(s),
|
||||
Public: false,
|
||||
},
|
||||
{
|
||||
Namespace: "lespay",
|
||||
Version: "1.0",
|
||||
Service: NewPrivateLespayAPI(s.lesCommons.peers, nil, s.srvr.DiscV5, s.tokenSale),
|
||||
Public: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -981,9 +981,9 @@ func (h *serverHandler) broadcastHeaders() {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *serverHandler) talkRequestHandler(id enode.ID, addr *net.UDPAddr, payload []byte) ([]byte, bool) {
|
||||
var cmds [][]byte
|
||||
if err := rlp.DecodeBytes(payload, &cmds); err != nil {
|
||||
func (h *serverHandler) talkRequestHandler(id enode.ID, addr *net.UDPAddr, payload interface{}) (interface{}, bool) {
|
||||
cmds, ok := payload.([][]byte)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
results := h.server.tokenSale.runCommands(cmds, id, addr.IP.String())
|
||||
|
|
|
|||
|
|
@ -319,11 +319,6 @@ const (
|
|||
tsConnection
|
||||
)
|
||||
|
||||
/*func (t *tokenSale) connection(id enode.ID, freeID string, requestedCapacity uint64, stayConnected time.Duration, paymentModule []string, setCap bool) (availableCapacity, tokenBalance, tokensMissing, pcBalance, pcMissing uint64, paymentRequired []uint64, err error) {
|
||||
func (t *tokenSale) deposit(id enode.ID, paymentModule string, proofOfPayment []byte) (pcValue, pcBalance uint64, err error) {
|
||||
func (t *tokenSale) buyTokens(id enode.ID, maxSpend, minReceive uint64, spendAll bool) (pcBalance, tokenBalance, spend, receive uint64, success bool) {
|
||||
func (t *tokenSale) paymentInfo(paymentModule []string) map[string][]byte {*/
|
||||
|
||||
type (
|
||||
tsDepositParams struct {
|
||||
PaymentModule string
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ type Network struct {
|
|||
}
|
||||
|
||||
type (
|
||||
TalkRequestHandler func(enode.ID, *net.UDPAddr, []byte) ([]byte, bool)
|
||||
TalkResponseHandler func([]byte) bool
|
||||
TalkRequestHandler func(enode.ID, *net.UDPAddr, interface{}) (interface{}, bool)
|
||||
TalkResponseHandler func(interface{}) bool
|
||||
)
|
||||
|
||||
// transport is implemented by the UDP transport.
|
||||
|
|
@ -116,7 +116,7 @@ type findnodeQuery struct {
|
|||
type talkQuery struct {
|
||||
remote *Node
|
||||
talkID string
|
||||
payload rlp.RawValue
|
||||
payload interface{}
|
||||
key string
|
||||
handler TalkResponseHandler
|
||||
}
|
||||
|
|
@ -1387,7 +1387,7 @@ func (q *talkQuery) deferQuery() {
|
|||
q.remote.deferQuery(q)
|
||||
}
|
||||
|
||||
func (net *Network) SendTalkRequest(to *enode.Node, talkID string, payload []byte, handler TalkResponseHandler) func() bool {
|
||||
func (net *Network) SendTalkRequest(to *enode.Node, talkID string, payload interface{}, handler TalkResponseHandler) func() bool {
|
||||
var nodeID NodeID
|
||||
copy(nodeID[:], crypto.FromECDSAPub(to.Pubkey())[1:])
|
||||
node := net.nodes[nodeID]
|
||||
|
|
|
|||
|
|
@ -120,11 +120,13 @@ type (
|
|||
}
|
||||
|
||||
talkRequest struct {
|
||||
TalkID, Payload []byte
|
||||
TalkID []byte
|
||||
Payload interface{}
|
||||
}
|
||||
|
||||
talkResponse struct {
|
||||
ReplyTok, Payload []byte
|
||||
ReplyTok []byte
|
||||
Payload interface{}
|
||||
}
|
||||
|
||||
rpcNode struct {
|
||||
|
|
|
|||
Loading…
Reference in a new issue