mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
swarm/swap: swap implemented as protocols/protocol.Peer extension
This commit is contained in:
parent
fac86b399f
commit
251e53e418
5 changed files with 113 additions and 88 deletions
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/swarm/network"
|
"github.com/ethereum/go-ethereum/swarm/network"
|
||||||
"github.com/ethereum/go-ethereum/swarm/spancontext"
|
"github.com/ethereum/go-ethereum/swarm/spancontext"
|
||||||
"github.com/ethereum/go-ethereum/swarm/storage"
|
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||||
"github.com/ethereum/go-ethereum/swarm/swap"
|
|
||||||
opentracing "github.com/opentracing/opentracing-go"
|
opentracing "github.com/opentracing/opentracing-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -140,8 +139,8 @@ type RetrieveRequestMsg struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: what is the correct price
|
//TODO: what is the correct price
|
||||||
func (rrm *RetrieveRequestMsg) GetMsgPrice() (*big.Int, swap.EntryDirection) {
|
func (rrm *RetrieveRequestMsg) GetMsgPrice() *big.Int {
|
||||||
return big.NewInt(int64(4096)), swap.CreditEntry
|
return big.NewInt(int64(4096))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Delivery) handleRetrieveRequestMsg(ctx context.Context, sp *Peer, req *RetrieveRequestMsg) error {
|
func (d *Delivery) handleRetrieveRequestMsg(ctx context.Context, sp *Peer, req *RetrieveRequestMsg) error {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/swarm/spancontext"
|
"github.com/ethereum/go-ethereum/swarm/spancontext"
|
||||||
"github.com/ethereum/go-ethereum/swarm/state"
|
"github.com/ethereum/go-ethereum/swarm/state"
|
||||||
"github.com/ethereum/go-ethereum/swarm/storage"
|
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||||
|
"github.com/ethereum/go-ethereum/swarm/swap"
|
||||||
opentracing "github.com/opentracing/opentracing-go"
|
opentracing "github.com/opentracing/opentracing-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -53,7 +54,8 @@ var ErrMaxPeerServers = errors.New("max peer servers")
|
||||||
|
|
||||||
// Peer is the Peer extension for the streaming protocol
|
// Peer is the Peer extension for the streaming protocol
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
*protocols.Peer
|
//*protocols.Peer
|
||||||
|
*swap.SwapPeer
|
||||||
streamer *Registry
|
streamer *Registry
|
||||||
pq *pq.PriorityQueue
|
pq *pq.PriorityQueue
|
||||||
serverMu sync.RWMutex
|
serverMu sync.RWMutex
|
||||||
|
|
@ -75,7 +77,7 @@ type WrappedPriorityMsg struct {
|
||||||
// NewPeer is the constructor for Peer
|
// NewPeer is the constructor for Peer
|
||||||
func NewPeer(peer *protocols.Peer, streamer *Registry) *Peer {
|
func NewPeer(peer *protocols.Peer, streamer *Registry) *Peer {
|
||||||
p := &Peer{
|
p := &Peer{
|
||||||
Peer: peer,
|
SwapPeer: swap.NewSwapPeer(peer, streamer.swap),
|
||||||
pq: pq.New(int(PriorityQueue), PriorityQueueCap),
|
pq: pq.New(int(PriorityQueue), PriorityQueueCap),
|
||||||
streamer: streamer,
|
streamer: streamer,
|
||||||
servers: make(map[Stream]*server),
|
servers: make(map[Stream]*server),
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ func (r *Registry) Run(p *network.BzzPeer) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sp.Run(sp.HandleAccountedMsg)
|
return sp.RunAccountedProtocol(sp.HandleMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSyncing subscribes to SYNC streams by iterating over the
|
// updateSyncing subscribes to SYNC streams by iterating over the
|
||||||
|
|
@ -460,16 +460,8 @@ func (r *Registry) runProtocol(p *p2p.Peer, rw p2p.MsgReadWriter) error {
|
||||||
return r.Run(bp)
|
return r.Run(bp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Peer) HandleAccountedMsg(ctx context.Context, msg interface{}) error {
|
|
||||||
err := p.handleMsg(ctx, msg)
|
|
||||||
if _, ok := msg.(swap.SwapAccountedMsgType); ok && err == nil {
|
|
||||||
p.streamer.swap.AccountForMsg(ctx, msg, p.ID())
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleMsg is the message handler that delegates incoming messages
|
// HandleMsg is the message handler that delegates incoming messages
|
||||||
func (p *Peer) handleMsg(ctx context.Context, msg interface{}) error {
|
func (p *Peer) HandleMsg(ctx context.Context, msg interface{}) error {
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
|
|
||||||
case *SubscribeMsg:
|
case *SubscribeMsg:
|
||||||
|
|
|
||||||
|
|
@ -35,25 +35,25 @@ const (
|
||||||
|
|
||||||
type SwapProtocol struct {
|
type SwapProtocol struct {
|
||||||
peersMu sync.RWMutex
|
peersMu sync.RWMutex
|
||||||
peers map[discover.NodeID]*SwapPeer
|
peers map[discover.NodeID]*SwapProtocolPeer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peer is the Peer extension for the streaming protocol
|
// Peer is the Peer extension for the streaming protocol
|
||||||
type SwapPeer struct {
|
type SwapProtocolPeer struct {
|
||||||
*protocols.Peer
|
*protocols.Peer
|
||||||
swapProtocol *SwapProtocol
|
swapProtocol *SwapProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSwapProtocol() *SwapProtocol {
|
func NewSwapProtocol() *SwapProtocol {
|
||||||
proto := &SwapProtocol{
|
proto := &SwapProtocol{
|
||||||
peers: make(map[discover.NodeID]*SwapPeer),
|
peers: make(map[discover.NodeID]*SwapProtocolPeer),
|
||||||
}
|
}
|
||||||
return proto
|
return proto
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPeer is the constructor for Peer
|
// NewPeer is the constructor for Peer
|
||||||
func NewPeer(peer *protocols.Peer, swap *SwapProtocol) *SwapPeer {
|
func NewPeer(peer *protocols.Peer, swap *SwapProtocol) *SwapProtocolPeer {
|
||||||
p := &SwapPeer{
|
p := &SwapProtocolPeer{
|
||||||
Peer: peer,
|
Peer: peer,
|
||||||
swapProtocol: swap,
|
swapProtocol: swap,
|
||||||
}
|
}
|
||||||
|
|
@ -100,19 +100,6 @@ func (p *SwapProtocol) Protocols() []p2p.Protocol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (swap *SwapProtocol) DebitByteCount(peer *SwapPeer, numberOfBytes int) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (swap *SwapProtocol) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
|
|
||||||
p := protocols.NewPeer(peer, rw, swapSpec)
|
|
||||||
sp := NewPeer(p, swap)
|
|
||||||
swap.setPeer(sp)
|
|
||||||
defer swap.deletePeer(sp)
|
|
||||||
defer swap.Close()
|
|
||||||
return sp.Run(sp.handleSwapMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *SwapProtocol) APIs() []rpc.API {
|
func (p *SwapProtocol) APIs() []rpc.API {
|
||||||
apis := []rpc.API{
|
apis := []rpc.API{
|
||||||
{
|
{
|
||||||
|
|
@ -125,7 +112,17 @@ func (p *SwapProtocol) APIs() []rpc.API {
|
||||||
return apis
|
return apis
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// SECTION: p2p.protocol interface
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
func (swap *SwapProtocol) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
|
||||||
|
p := protocols.NewPeer(peer, rw, swapSpec)
|
||||||
|
sp := NewPeer(p, swap)
|
||||||
|
swap.setPeer(sp)
|
||||||
|
defer swap.deletePeer(sp)
|
||||||
|
defer swap.Close()
|
||||||
|
return sp.Run(sp.handleSwapMsg)
|
||||||
|
}
|
||||||
|
|
||||||
func (swap *SwapProtocol) NodeInfo() interface{} {
|
func (swap *SwapProtocol) NodeInfo() interface{} {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -135,18 +132,23 @@ func (swap *SwapProtocol) PeerInfo(id discover.NodeID) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (swap *SwapProtocol) Close() error {
|
//------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func (swap *SwapProtocol) DebitByteCount(peer *SwapProtocolPeer, numberOfBytes int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (swap *SwapProtocol) getPeer(peerId discover.NodeID) *SwapPeer {
|
func (swap *SwapProtocol) Close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (swap *SwapProtocol) getPeer(peerId discover.NodeID) *SwapProtocolPeer {
|
||||||
swap.peersMu.RLock()
|
swap.peersMu.RLock()
|
||||||
defer swap.peersMu.RUnlock()
|
defer swap.peersMu.RUnlock()
|
||||||
|
|
||||||
return swap.peers[peerId]
|
return swap.peers[peerId]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (swap *SwapProtocol) setPeer(peer *SwapPeer) {
|
func (swap *SwapProtocol) setPeer(peer *SwapProtocolPeer) {
|
||||||
swap.peersMu.Lock()
|
swap.peersMu.Lock()
|
||||||
defer swap.peersMu.Unlock()
|
defer swap.peersMu.Unlock()
|
||||||
|
|
||||||
|
|
@ -154,7 +156,7 @@ func (swap *SwapProtocol) setPeer(peer *SwapPeer) {
|
||||||
metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(swap.peers)))
|
metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(swap.peers)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (swap *SwapProtocol) deletePeer(peer *SwapPeer) {
|
func (swap *SwapProtocol) deletePeer(peer *SwapProtocolPeer) {
|
||||||
swap.peersMu.Lock()
|
swap.peersMu.Lock()
|
||||||
defer swap.peersMu.Unlock()
|
defer swap.peersMu.Unlock()
|
||||||
|
|
||||||
|
|
@ -170,7 +172,7 @@ func (swap *SwapProtocol) peersCount() (c int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SwapPeer) handleSwapMsg(ctx context.Context, msg interface{}) error {
|
func (p *SwapProtocolPeer) handleSwapMsg(ctx context.Context, msg interface{}) error {
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
|
|
||||||
case *IssueChequeMsg:
|
case *IssueChequeMsg:
|
||||||
|
|
@ -190,10 +192,10 @@ func (p *SwapPeer) handleSwapMsg(ctx context.Context, msg interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *SwapPeer) handleIssueChequeMsg(ctx context.Context, msg interface{}) (err error) {
|
func (sp *SwapProtocolPeer) handleIssueChequeMsg(ctx context.Context, msg interface{}) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *SwapPeer) handleRedeemChequeMsg(ctx context.Context, msg interface{}) (err error) {
|
func (sp *SwapProtocolPeer) handleRedeemChequeMsg(ctx context.Context, msg interface{}) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/protocols"
|
||||||
"github.com/ethereum/go-ethereum/swarm/log"
|
"github.com/ethereum/go-ethereum/swarm/log"
|
||||||
"github.com/ethereum/go-ethereum/swarm/state"
|
"github.com/ethereum/go-ethereum/swarm/state"
|
||||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||||
|
|
@ -67,10 +68,19 @@ const (
|
||||||
type Swap struct {
|
type Swap struct {
|
||||||
stateStore state.Store
|
stateStore state.Store
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
peers map[discover.NodeID]*swapPeer
|
peers map[discover.NodeID]*SwapPeer
|
||||||
local *Params // local peer's swap parameters
|
local *Params // local peer's swap parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SwapPeer struct {
|
||||||
|
*protocols.Peer
|
||||||
|
lock sync.RWMutex
|
||||||
|
swapAccount *Swap
|
||||||
|
handlerFunc func(context.Context, interface{}) error
|
||||||
|
balance *big.Int
|
||||||
|
storeID string
|
||||||
|
}
|
||||||
|
|
||||||
type EntryDirection bool
|
type EntryDirection bool
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -79,26 +89,20 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type SwapAccountedMsgType interface {
|
type SwapAccountedMsgType interface {
|
||||||
GetMsgPrice() (*big.Int, EntryDirection)
|
GetMsgPrice() *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (swap *Swap) AccountForMsg(ctx context.Context, msg interface{}, peer discover.NodeID) error {
|
func (sp *SwapPeer) RunAccountedProtocol(protocolHandler func(ctx context.Context, msg interface{}) error) error {
|
||||||
|
sp.handlerFunc = protocolHandler
|
||||||
|
|
||||||
|
return sp.Run(sp.handleAccountedMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sp *SwapPeer) doAccountMsg(ctx context.Context, msg interface{}, direction EntryDirection) error {
|
||||||
if accounted, ok := msg.(SwapAccountedMsgType); ok {
|
if accounted, ok := msg.(SwapAccountedMsgType); ok {
|
||||||
if _, exists := swap.peers[peer]; !exists {
|
price := accounted.GetMsgPrice()
|
||||||
balance := big.NewInt(0)
|
|
||||||
swap.stateStore.Get(peer.String()[:24]+"-swap", &balance)
|
|
||||||
swap.lock.Lock()
|
|
||||||
swap.peers[peer] = &swapPeer{
|
|
||||||
peer: peer,
|
|
||||||
swapAccount: swap,
|
|
||||||
balance: balance,
|
|
||||||
storeID: peer.String()[:24] + "-swap",
|
|
||||||
}
|
|
||||||
swap.lock.Unlock()
|
|
||||||
}
|
|
||||||
price, direction := accounted.GetMsgPrice()
|
|
||||||
//TODO: Calculate total price and account
|
//TODO: Calculate total price and account
|
||||||
swap.peers[peer].AccountMsgForPeer(price, direction)
|
sp.AccountMsgForPeer(price, direction)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -110,6 +114,61 @@ func (swap *Swap) GetPeerBalance(peer discover.NodeID) *big.Int {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sp *SwapPeer) handleAccountedMsg(ctx context.Context, msg interface{}) error {
|
||||||
|
err := sp.handlerFunc(ctx, msg)
|
||||||
|
if _, ok := msg.(SwapAccountedMsgType); ok && err == nil {
|
||||||
|
sp.doAccountMsg(ctx, msg, CreditEntry)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sp *SwapPeer) Send(ctx context.Context, msg interface{}) error {
|
||||||
|
err := sp.Peer.Send(ctx, msg)
|
||||||
|
if _, ok := msg.(SwapAccountedMsgType); ok && err == nil {
|
||||||
|
sp.doAccountMsg(ctx, msg, DebitEntry)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//The balance is accounted from the point of view of the local node
|
||||||
|
//Thus, we credit the balance and increase it when the amount is in favor of the local node
|
||||||
|
//We debit the balance and decrease it when the amount is in favor of the remote peer
|
||||||
|
func (sp *SwapPeer) AccountMsgForPeer(price *big.Int, direction EntryDirection) {
|
||||||
|
sp.lock.Lock()
|
||||||
|
defer sp.lock.Unlock()
|
||||||
|
//local node is being credited (in its favor), so its balance increases
|
||||||
|
if direction == CreditEntry {
|
||||||
|
sp.balance = sp.balance.Add(sp.balance, price)
|
||||||
|
//local node is being debited (in favor of remote peer), so its balance decreases
|
||||||
|
} else if direction == DebitEntry {
|
||||||
|
sp.balance = sp.balance.Sub(sp.balance, price)
|
||||||
|
}
|
||||||
|
//TODO: save to store here? init store?
|
||||||
|
sp.swapAccount.stateStore.Put(sp.storeID, sp.balance)
|
||||||
|
if sp.balance.Cmp(payAt) > -1 {
|
||||||
|
//TODO: Issue Cheque
|
||||||
|
}
|
||||||
|
if sp.balance.Cmp(dropAt) < 0 {
|
||||||
|
//TODO: Drop peer
|
||||||
|
}
|
||||||
|
log.Debug(fmt.Sprintf("balance for peer %s: %s", sp.ID(), sp.balance.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSwapPeer(peer *protocols.Peer, swap *Swap) *SwapPeer {
|
||||||
|
balance := big.NewInt(0)
|
||||||
|
swap.stateStore.Get(peer.String()[:24]+"-swap", &balance)
|
||||||
|
sp := &SwapPeer{
|
||||||
|
Peer: peer,
|
||||||
|
swapAccount: swap,
|
||||||
|
balance: balance,
|
||||||
|
storeID: peer.String()[:24] + "-swap",
|
||||||
|
}
|
||||||
|
swap.lock.Lock()
|
||||||
|
defer swap.lock.Unlock()
|
||||||
|
swap.peers[peer.ID()] = sp
|
||||||
|
return sp
|
||||||
|
}
|
||||||
|
|
||||||
// Profile - public swap profile
|
// Profile - public swap profile
|
||||||
// public parameters for SWAP, serializable config struct passed in handshake
|
// public parameters for SWAP, serializable config struct passed in handshake
|
||||||
type Profile struct {
|
type Profile struct {
|
||||||
|
|
@ -168,42 +227,13 @@ type PayProfile struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type swapPeer struct {
|
|
||||||
lock sync.RWMutex
|
|
||||||
peer discover.NodeID
|
|
||||||
swapAccount *Swap
|
|
||||||
balance *big.Int
|
|
||||||
storeID string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *swapPeer) AccountMsgForPeer(price *big.Int, direction EntryDirection) {
|
|
||||||
sp.lock.Lock()
|
|
||||||
defer sp.lock.Unlock()
|
|
||||||
//the peer is being credited (in its favor), so its balance increases
|
|
||||||
if direction == CreditEntry {
|
|
||||||
sp.balance = sp.balance.Add(sp.balance, price)
|
|
||||||
//the peer is being debited (in local favor), so its balance decreases
|
|
||||||
} else if direction == DebitEntry {
|
|
||||||
sp.balance = sp.balance.Sub(sp.balance, price)
|
|
||||||
}
|
|
||||||
//TODO: save to store here? init store?
|
|
||||||
sp.swapAccount.stateStore.Put(sp.storeID, sp.balance)
|
|
||||||
if sp.balance.Cmp(payAt) > -1 {
|
|
||||||
//TODO: Issue Cheque
|
|
||||||
}
|
|
||||||
if sp.balance.Cmp(dropAt) < 0 {
|
|
||||||
//TODO: Drop peer
|
|
||||||
}
|
|
||||||
log.Debug(fmt.Sprintf("balance for peer %s: %s", sp.peer, sp.balance.String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// New - swap constructor
|
// New - swap constructor
|
||||||
func NewSwap(local *Params, stateStore state.Store) (swap *Swap, err error) {
|
func NewSwap(local *Params, stateStore state.Store) (swap *Swap, err error) {
|
||||||
|
|
||||||
swap = &Swap{
|
swap = &Swap{
|
||||||
local: local,
|
local: local,
|
||||||
stateStore: stateStore,
|
stateStore: stateStore,
|
||||||
peers: make(map[discover.NodeID]*swapPeer),
|
peers: make(map[discover.NodeID]*SwapPeer),
|
||||||
}
|
}
|
||||||
|
|
||||||
//swap.SetParams(local)
|
//swap.SetParams(local)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue