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
db4bc521a3
commit
94bf8de547
7 changed files with 88 additions and 29 deletions
24
les/api.go
24
les/api.go
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
@ -376,10 +377,13 @@ func (api *PrivateLespayAPI) makeCall(ctx context.Context, remote bool, nodeStr
|
||||||
freeID string
|
freeID string
|
||||||
peer *peer
|
peer *peer
|
||||||
node *enode.Node
|
node *enode.Node
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
if nodeStr != "" {
|
if nodeStr != "" {
|
||||||
if peer = api.peerSet.Peer(nodeStr); peer != nil {
|
if id, err = enode.ParseID(nodeStr); err == nil {
|
||||||
id = peer.ID()
|
if peer = api.peerSet.Peer(peerIdToString(id)); peer == nil {
|
||||||
|
return nil, errors.New("peer not connected")
|
||||||
|
}
|
||||||
freeID = peer.freeClientId()
|
freeID = peer.freeClientId()
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -416,18 +420,25 @@ func (api *PrivateLespayAPI) makeCall(ctx context.Context, remote bool, nodeStr
|
||||||
return nil, errors.New("UDP DHT not available")
|
return nil, errors.New("UDP DHT not available")
|
||||||
}
|
}
|
||||||
cancelFn = api.dht.SendTalkRequest(node, "lespay", [][]byte{cmd}, func(payload interface{}) bool {
|
cancelFn = api.dht.SendTalkRequest(node, "lespay", [][]byte{cmd}, func(payload interface{}) bool {
|
||||||
if replies, ok := payload.([][]byte); ok && len(replies) == 1 {
|
fmt.Println("dht delivered", payload, reflect.TypeOf(payload))
|
||||||
reply = replies[0]
|
if replies, ok := payload.([]interface{}); ok && len(replies) == 1 {
|
||||||
|
reply, ok = replies[0].([]byte)
|
||||||
}
|
}
|
||||||
close(delivered)
|
close(delivered)
|
||||||
return reply != nil
|
return reply != nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
|
case <-time.After(time.Second * 5):
|
||||||
|
cancelFn()
|
||||||
|
return nil, errors.New("timeout")
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
cancelFn()
|
cancelFn()
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
case <-delivered:
|
case <-delivered:
|
||||||
|
if len(reply) == 0 {
|
||||||
|
return nil, errors.New("unknown command")
|
||||||
|
}
|
||||||
return reply, nil
|
return reply, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -444,10 +455,13 @@ func (api *PrivateLespayAPI) Connection(ctx context.Context, remote bool, node s
|
||||||
params := tsConnectionParams{requestedCapacity, stayConnected, paymentModule, setCap}
|
params := tsConnectionParams{requestedCapacity, stayConnected, paymentModule, setCap}
|
||||||
enc, _ := rlp.EncodeToBytes(¶ms)
|
enc, _ := rlp.EncodeToBytes(¶ms)
|
||||||
var resEnc []byte
|
var resEnc []byte
|
||||||
resEnc, err = api.makeCall(ctx, remote, node, enc)
|
fmt.Println("makeCall", remote, node, enc)
|
||||||
|
resEnc, err = api.makeCall(ctx, remote, node, append([]byte{tsConnection}, enc...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("makeCall err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = rlp.DecodeBytes(resEnc, &results)
|
err = rlp.DecodeBytes(resEnc, &results)
|
||||||
|
fmt.Println("decode err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package les
|
package les
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -316,19 +317,24 @@ func (h *clientHandler) handleMsg(p *peer) error {
|
||||||
p.freezeServer(false)
|
p.freezeServer(false)
|
||||||
p.Log().Debug("Service resumed")
|
p.Log().Debug("Service resumed")
|
||||||
case LespayReplyMsg:
|
case LespayReplyMsg:
|
||||||
|
fmt.Println("LespayReply received")
|
||||||
p.Log().Trace("Received tx status response")
|
p.Log().Trace("Received tx status response")
|
||||||
var resp struct {
|
var resp struct {
|
||||||
ReqID uint64
|
ReqID uint64
|
||||||
Replies [][]byte
|
Replies [][]byte
|
||||||
}
|
}
|
||||||
if err := msg.Decode(&resp); err != nil {
|
if err := msg.Decode(&resp); err != nil {
|
||||||
|
fmt.Println("LespayReply decode err", err)
|
||||||
return errResp(ErrDecode, "msg %v: %v", msg, err)
|
return errResp(ErrDecode, "msg %v: %v", msg, err)
|
||||||
}
|
}
|
||||||
|
fmt.Println("LespayReply decoded", resp)
|
||||||
h.lespayReplyLock.Lock()
|
h.lespayReplyLock.Lock()
|
||||||
if handler := h.lespayReplyHandlers[resp.ReqID]; handler != nil {
|
if handler := h.lespayReplyHandlers[resp.ReqID]; handler != nil {
|
||||||
|
fmt.Println("handler found")
|
||||||
delete(h.lespayReplyHandlers, resp.ReqID)
|
delete(h.lespayReplyHandlers, resp.ReqID)
|
||||||
responseError = !handler(resp.Replies)
|
responseError = !handler(resp.Replies)
|
||||||
} else {
|
} else {
|
||||||
|
fmt.Println("handler not found")
|
||||||
responseError = true
|
responseError = true
|
||||||
}
|
}
|
||||||
h.lespayReplyLock.Unlock()
|
h.lespayReplyLock.Unlock()
|
||||||
|
|
@ -354,9 +360,16 @@ func (h *clientHandler) handleMsg(p *peer) error {
|
||||||
|
|
||||||
func (h *clientHandler) makeLespayCall(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()
|
reqID := genReqID()
|
||||||
|
h.lespayReplyLock.Lock()
|
||||||
|
h.lespayReplyHandlers[reqID] = handler
|
||||||
|
h.lespayReplyLock.Unlock()
|
||||||
if p.SendLespay(reqID, cmds) != nil {
|
if p.SendLespay(reqID, cmds) != nil {
|
||||||
|
h.lespayReplyLock.Lock()
|
||||||
|
delete(h.lespayReplyHandlers, reqID)
|
||||||
|
h.lespayReplyLock.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
fmt.Println("Lespay sent")
|
||||||
return func() bool {
|
return func() bool {
|
||||||
h.lespayReplyLock.Lock()
|
h.lespayReplyLock.Lock()
|
||||||
cancel := h.lespayReplyHandlers[reqID] != nil
|
cancel := h.lespayReplyHandlers[reqID] != nil
|
||||||
|
|
|
||||||
|
|
@ -594,10 +594,11 @@ func (f *clientPool) setCapacity(id enode.ID, freeID string, capacity uint64, mi
|
||||||
if missing != 0 {
|
if missing != 0 {
|
||||||
return missing, capacity, errNoPriority
|
return missing, capacity, errNoPriority
|
||||||
}
|
}
|
||||||
if setCap && c == nil {
|
|
||||||
return missing, capacity, fmt.Errorf("client %064x is not connected", c.id[:])
|
|
||||||
}
|
|
||||||
// capacity update is possible
|
// capacity update is possible
|
||||||
|
if setCap {
|
||||||
|
if c == nil {
|
||||||
|
return 0, capacity, fmt.Errorf("client %064x is not connected", c.id[:])
|
||||||
|
}
|
||||||
f.connectedCap += capacity - c.capacity
|
f.connectedCap += capacity - c.capacity
|
||||||
f.updateFullRatio()
|
f.updateFullRatio()
|
||||||
f.priorityConnected += capacity - c.capacity
|
f.priorityConnected += capacity - c.capacity
|
||||||
|
|
@ -607,6 +608,7 @@ func (f *clientPool) setCapacity(id enode.ID, freeID string, capacity uint64, mi
|
||||||
totalConnectedGauge.Update(int64(f.connectedCap))
|
totalConnectedGauge.Update(int64(f.connectedCap))
|
||||||
updatePriceFactors(&c.balanceTracker, c.posFactors, c.negFactors, c.capacity)
|
updatePriceFactors(&c.balanceTracker, c.posFactors, c.negFactors, c.capacity)
|
||||||
c.peer.updateCapacity(c.capacity)
|
c.peer.updateCapacity(c.capacity)
|
||||||
|
}
|
||||||
return 0, capacity, nil
|
return 0, capacity, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -130,7 +132,7 @@ func (h *serverHandler) handle(p *peer) error {
|
||||||
}
|
}
|
||||||
// Reject light clients if server is not synced.
|
// Reject light clients if server is not synced.
|
||||||
if !h.synced() {
|
if !h.synced() {
|
||||||
return p2p.DiscRequested
|
//return p2p.DiscRequested
|
||||||
}
|
}
|
||||||
defer p.fcClient.Disconnect()
|
defer p.fcClient.Disconnect()
|
||||||
|
|
||||||
|
|
@ -982,11 +984,21 @@ func (h *serverHandler) broadcastHeaders() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *serverHandler) talkRequestHandler(id enode.ID, addr *net.UDPAddr, payload interface{}) (interface{}, bool) {
|
func (h *serverHandler) talkRequestHandler(id enode.ID, addr *net.UDPAddr, payload interface{}) (interface{}, bool) {
|
||||||
cmds, ok := payload.([][]byte)
|
fmt.Println("talkRequestHandler", id, addr, payload, reflect.TypeOf(payload))
|
||||||
|
c, ok := payload.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
cmds := make([][]byte, len(c))
|
||||||
|
for i, c := range c {
|
||||||
|
cmds[i], ok = c.([]byte)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("type err", reflect.TypeOf(c))
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("ok", ok)
|
||||||
results := h.server.tokenSale.runCommands(cmds, id, addr.IP.String())
|
results := h.server.tokenSale.runCommands(cmds, id, addr.IP.String())
|
||||||
res, _ := rlp.EncodeToBytes(&results)
|
fmt.Println("results", results)
|
||||||
return res, true
|
return results, true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,9 @@ func (t *tokenSale) runCommand(cmd []byte, id enode.ID, freeID string) []byte {
|
||||||
)
|
)
|
||||||
if err := rlp.DecodeBytes(cmd[1:], ¶ms); err == nil {
|
if err := rlp.DecodeBytes(cmd[1:], ¶ms); err == nil {
|
||||||
results.PcValue, results.PcBalance, err = t.deposit(id, params.PaymentModule, params.ProofOfPayment)
|
results.PcValue, results.PcBalance, err = t.deposit(id, params.PaymentModule, params.ProofOfPayment)
|
||||||
|
if err != nil {
|
||||||
results.Err = err.Error()
|
results.Err = err.Error()
|
||||||
|
}
|
||||||
res, _ = rlp.EncodeToBytes(&results)
|
res, _ = rlp.EncodeToBytes(&results)
|
||||||
}
|
}
|
||||||
case tsBuyTokens:
|
case tsBuyTokens:
|
||||||
|
|
@ -388,7 +390,9 @@ func (t *tokenSale) runCommand(cmd []byte, id enode.ID, freeID string) []byte {
|
||||||
if err := rlp.DecodeBytes(cmd[1:], ¶ms); err == nil {
|
if err := rlp.DecodeBytes(cmd[1:], ¶ms); err == nil {
|
||||||
results.AvailableCapacity, results.TokenBalance, results.TokensMissing, results.PcBalance, results.PcMissing, results.PaymentRequired, err =
|
results.AvailableCapacity, results.TokenBalance, results.TokensMissing, results.PcBalance, results.PcMissing, results.PaymentRequired, err =
|
||||||
t.connection(id, freeID, params.RequestedCapacity, time.Duration(params.StayConnected)*time.Second, params.PaymentModule, params.SetCap)
|
t.connection(id, freeID, params.RequestedCapacity, time.Duration(params.StayConnected)*time.Second, params.PaymentModule, params.SetCap)
|
||||||
|
if err != nil {
|
||||||
results.Err = err.Error()
|
results.Err = err.Error()
|
||||||
|
}
|
||||||
res, _ = rlp.EncodeToBytes(&results)
|
res, _ = rlp.EncodeToBytes(&results)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -432,9 +432,11 @@ loop:
|
||||||
|
|
||||||
// Ingress packet handling.
|
// Ingress packet handling.
|
||||||
case pkt := <-net.read:
|
case pkt := <-net.read:
|
||||||
//fmt.Println("read", pkt.ev)
|
|
||||||
log.Trace("<-net.read")
|
log.Trace("<-net.read")
|
||||||
n := net.internNode(&pkt)
|
n := net.internNode(&pkt)
|
||||||
|
if pkt.ev == talkRequestPacket {
|
||||||
|
fmt.Println("read trp", n.state, pkt)
|
||||||
|
}
|
||||||
prestate := n.state
|
prestate := n.state
|
||||||
status := "ok"
|
status := "ok"
|
||||||
if err := net.handle(n, pkt.ev, &pkt); err != nil {
|
if err := net.handle(n, pkt.ev, &pkt); err != nil {
|
||||||
|
|
@ -722,11 +724,17 @@ func (net *Network) refresh(done chan<- struct{}) {
|
||||||
|
|
||||||
func (net *Network) internNode(pkt *ingressPacket) *Node {
|
func (net *Network) internNode(pkt *ingressPacket) *Node {
|
||||||
if n := net.nodes[pkt.remoteID]; n != nil {
|
if n := net.nodes[pkt.remoteID]; n != nil {
|
||||||
|
if pkt.ev == talkRequestPacket {
|
||||||
|
fmt.Println("node exists")
|
||||||
|
}
|
||||||
n.IP = pkt.remoteAddr.IP
|
n.IP = pkt.remoteAddr.IP
|
||||||
n.UDP = uint16(pkt.remoteAddr.Port)
|
n.UDP = uint16(pkt.remoteAddr.Port)
|
||||||
n.TCP = uint16(pkt.remoteAddr.Port)
|
n.TCP = uint16(pkt.remoteAddr.Port)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
if pkt.ev == talkRequestPacket {
|
||||||
|
fmt.Println("node created")
|
||||||
|
}
|
||||||
n := NewNode(pkt.remoteID, pkt.remoteAddr.IP, uint16(pkt.remoteAddr.Port), uint16(pkt.remoteAddr.Port))
|
n := NewNode(pkt.remoteID, pkt.remoteAddr.IP, uint16(pkt.remoteAddr.Port), uint16(pkt.remoteAddr.Port))
|
||||||
n.state = unknown
|
n.state = unknown
|
||||||
net.nodes[pkt.remoteID] = n
|
net.nodes[pkt.remoteID] = n
|
||||||
|
|
@ -1061,7 +1069,7 @@ func (net *Network) handle(n *Node, ev nodeEvent, pkt *ingressPacket) error {
|
||||||
//fmt.Println("handle", n.addr().String(), n.state, ev)
|
//fmt.Println("handle", n.addr().String(), n.state, ev)
|
||||||
if pkt != nil {
|
if pkt != nil {
|
||||||
if err := net.checkPacket(n, ev, pkt); err != nil {
|
if err := net.checkPacket(n, ev, pkt); err != nil {
|
||||||
//fmt.Println("check err:", err)
|
//fmt.Println("check err:", err, pkt)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Start the background expiration goroutine after the first
|
// Start the background expiration goroutine after the first
|
||||||
|
|
@ -1076,6 +1084,7 @@ func (net *Network) handle(n *Node, ev nodeEvent, pkt *ingressPacket) error {
|
||||||
if n.state == nil {
|
if n.state == nil {
|
||||||
n.state = unknown //???
|
n.state = unknown //???
|
||||||
}
|
}
|
||||||
|
//fmt.Println("old state:", n.state)
|
||||||
next, err := n.state.handle(net, n, ev, pkt)
|
next, err := n.state.handle(net, n, ev, pkt)
|
||||||
net.transition(n, next)
|
net.transition(n, next)
|
||||||
//fmt.Println("new state:", n.state)
|
//fmt.Println("new state:", n.state)
|
||||||
|
|
@ -1241,8 +1250,10 @@ func (net *Network) handleQueryEvent(n *Node, ev nodeEvent, pkt *ingressPacket)
|
||||||
net.talkRequestSubLock.RLock()
|
net.talkRequestSubLock.RLock()
|
||||||
subFn := net.talkRequestSubs[string(p.TalkID)]
|
subFn := net.talkRequestSubs[string(p.TalkID)]
|
||||||
net.talkRequestSubLock.RUnlock()
|
net.talkRequestSubLock.RUnlock()
|
||||||
|
fmt.Println("trp", p)
|
||||||
if subFn != nil {
|
if subFn != nil {
|
||||||
resp, ok := subFn(enode.ID(n.sha), n.addr(), p.Payload)
|
resp, ok := subFn(enode.ID(n.sha), n.addr(), p.Payload)
|
||||||
|
fmt.Println("subFn", ok)
|
||||||
if ok {
|
if ok {
|
||||||
net.conn.send(n, talkResponsePacket, talkResponse{ReplyTok: pkt.hash, Payload: resp})
|
net.conn.send(n, talkResponsePacket, talkResponse{ReplyTok: pkt.hash, Payload: resp})
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1367,7 +1378,7 @@ func (q *talkQuery) start(net *Network) bool {
|
||||||
q.key = string(q.remote.sha[:]) + string(hash[:])
|
q.key = string(q.remote.sha[:]) + string(hash[:])
|
||||||
net.talkResponseSubs[q.key] = q.handler
|
net.talkResponseSubs[q.key] = q.handler
|
||||||
net.talkResponseSubLock.Unlock()
|
net.talkResponseSubLock.Unlock()
|
||||||
fmt.Println("sent")
|
fmt.Println("sent", q.remote.state)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// If the node is not known yet, it won't accept queries.
|
// If the node is not known yet, it won't accept queries.
|
||||||
|
|
@ -1397,6 +1408,9 @@ func (net *Network) SendTalkRequest(to *enode.Node, talkID string, payload inter
|
||||||
net.nodes[nodeID] = node
|
net.nodes[nodeID] = node
|
||||||
}
|
}
|
||||||
q := &talkQuery{remote: node, talkID: talkID, payload: payload, handler: handler}
|
q := &talkQuery{remote: node, talkID: talkID, payload: payload, handler: handler}
|
||||||
|
if node.state == nil || !node.state.canQuery {
|
||||||
|
net.ping(node, node.addr())
|
||||||
|
}
|
||||||
select {
|
select {
|
||||||
case net.queryReq <- q:
|
case net.queryReq <- q:
|
||||||
case <-net.closed:
|
case <-net.closed:
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ func (n ID) MarshalText() ([]byte, error) {
|
||||||
|
|
||||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||||
func (n *ID) UnmarshalText(text []byte) error {
|
func (n *ID) UnmarshalText(text []byte) error {
|
||||||
id, err := parseID(string(text))
|
id, err := ParseID(string(text))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -229,14 +229,14 @@ func (n *ID) UnmarshalText(text []byte) error {
|
||||||
// The string may be prefixed with 0x.
|
// The string may be prefixed with 0x.
|
||||||
// It panics if the string is not a valid ID.
|
// It panics if the string is not a valid ID.
|
||||||
func HexID(in string) ID {
|
func HexID(in string) ID {
|
||||||
id, err := parseID(in)
|
id, err := ParseID(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseID(in string) (ID, error) {
|
func ParseID(in string) (ID, error) {
|
||||||
var id ID
|
var id ID
|
||||||
b, err := hex.DecodeString(strings.TrimPrefix(in, "0x"))
|
b, err := hex.DecodeString(strings.TrimPrefix(in, "0x"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue