mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
swarm/swap: rebased on latest master
This commit is contained in:
parent
12d825e379
commit
3d234cdbbb
7 changed files with 55 additions and 64 deletions
|
|
@ -21,7 +21,7 @@ import (
|
|||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -44,7 +44,7 @@ func NewAPI(swap *Swap) *API {
|
|||
}
|
||||
|
||||
//Get the balance for this node with a specific peer
|
||||
func (swapapi *API) BalanceWithPeer(ctx context.Context, peer discover.NodeID) (balance *big.Int, err error) {
|
||||
func (swapapi *API) BalanceWithPeer(ctx context.Context, peer enode.ID) (balance *big.Int, err error) {
|
||||
balance = swapapi.swap.peers[peer]
|
||||
if balance == nil {
|
||||
err = ErrNoSuchPeerAccounting
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ package swap
|
|||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/swarm/state"
|
||||
)
|
||||
|
||||
type ChequeManager struct {
|
||||
stateStore state.Store
|
||||
serialPerNode map[discover.NodeID]uint64
|
||||
openDebitCheques map[discover.NodeID][]*Cheque
|
||||
openCreditCheques map[discover.NodeID][]*Cheque
|
||||
serialPerNode map[enode.ID]uint64
|
||||
openDebitCheques map[enode.ID][]*Cheque
|
||||
openCreditCheques map[enode.ID][]*Cheque
|
||||
}
|
||||
|
||||
type Cheque struct {
|
||||
|
|
@ -35,20 +35,20 @@ type Cheque struct {
|
|||
timeout uint64
|
||||
amount *big.Int
|
||||
sumCumulated *big.Int
|
||||
beneficiary discover.NodeID //this should probably be common.Address?
|
||||
beneficiary enode.ID //this should probably be common.Address?
|
||||
}
|
||||
|
||||
func NewChequeManager(stateStore state.Store) *ChequeManager {
|
||||
return &ChequeManager{
|
||||
stateStore: stateStore,
|
||||
//TODO: restore from state store
|
||||
serialPerNode: make(map[discover.NodeID]uint64),
|
||||
openDebitCheques: make(map[discover.NodeID][]*Cheque),
|
||||
openCreditCheques: make(map[discover.NodeID][]*Cheque),
|
||||
serialPerNode: make(map[enode.ID]uint64),
|
||||
openDebitCheques: make(map[enode.ID][]*Cheque),
|
||||
openCreditCheques: make(map[enode.ID][]*Cheque),
|
||||
}
|
||||
}
|
||||
|
||||
func (mgr *ChequeManager) CreateCheque(beneficiary discover.NodeID, amount *big.Int) *Cheque {
|
||||
func (mgr *ChequeManager) CreateCheque(beneficiary enode.ID, amount *big.Int) *Cheque {
|
||||
mgr.serialPerNode[beneficiary]++
|
||||
cheque := &Cheque{
|
||||
serial: mgr.serialPerNode[beneficiary],
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"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/p2p/protocols"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/ethereum/go-ethereum/swarm/log"
|
||||
|
|
@ -40,7 +40,7 @@ const (
|
|||
//For a better understanding, please read the Swap network paper "Generalized Swap swear and swindle games"
|
||||
type Protocol struct {
|
||||
peersMu sync.RWMutex
|
||||
peers map[discover.NodeID]*Peer
|
||||
peers map[enode.ID]*Peer
|
||||
}
|
||||
|
||||
//This is the peer representing a participant in this protocol
|
||||
|
|
@ -51,7 +51,7 @@ type Peer struct {
|
|||
//Create a new protocol instance
|
||||
func NewProtocol() *Protocol {
|
||||
proto := &Protocol{
|
||||
peers: make(map[discover.NodeID]*Peer),
|
||||
peers: make(map[enode.ID]*Peer),
|
||||
}
|
||||
return proto
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ func (s *Swap) NodeInfo() interface{} {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Swap) PeerInfo(id discover.NodeID) interface{} {
|
||||
func (s *Swap) PeerInfo(id enode.ID) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ func (s *Swap) PeerInfo(id discover.NodeID) interface{} {
|
|||
func (proto *Protocol) Close() {
|
||||
}
|
||||
|
||||
func (proto *Protocol) getPeer(peerId discover.NodeID) *Peer {
|
||||
func (proto *Protocol) getPeer(peerId enode.ID) *Peer {
|
||||
proto.peersMu.RLock()
|
||||
defer proto.peersMu.RUnlock()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,10 +22,9 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"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/swarm/log"
|
||||
"github.com/ethereum/go-ethereum/swarm/network/stream"
|
||||
"github.com/ethereum/go-ethereum/swarm/state"
|
||||
|
|
@ -45,23 +44,17 @@ var (
|
|||
ErrInsufficientFunds = errors.New("Insufficient funds")
|
||||
)
|
||||
|
||||
const (
|
||||
chequebookDeployRetries = 5
|
||||
chequebookDeployDelay = 1 * time.Second // delay between retries
|
||||
)
|
||||
|
||||
// SwAP Swarm Accounting Protocol
|
||||
// a peer to peer micropayment system
|
||||
// A node maintains an individual balance with every peer
|
||||
// Only messages which have a price will be accounted for
|
||||
type Swap struct {
|
||||
priceOracle PriceOracle
|
||||
chequeManager *ChequeManager
|
||||
stateStore state.Store
|
||||
lock sync.RWMutex
|
||||
peers map[discover.NodeID]*big.Int
|
||||
p2pServer *p2p.Server
|
||||
protocol *Protocol
|
||||
priceOracle PriceOracle //the price oracle facilitates message pricing to the swap instance
|
||||
chequeManager *ChequeManager //cheque manager keeps track of issued cheques
|
||||
stateStore state.Store //stateStore is needed in order to keep balances across sessions
|
||||
lock sync.RWMutex //lock the balances
|
||||
peers map[enode.ID]*big.Int //map of balances for each peer
|
||||
protocol *Protocol //reference to the cheque exchange protocol
|
||||
}
|
||||
|
||||
//PriceOracle is responsible to maintain the price matrix for accounted messages,
|
||||
|
|
@ -197,35 +190,25 @@ func (s *Swap) handleMsgEvent(event *p2p.PeerEvent) {
|
|||
if !s.priceOracle.IsAccountedMsg(event) {
|
||||
return
|
||||
}
|
||||
s.AccountMsgForPeer(event)
|
||||
s.accountMsgForPeer(event)
|
||||
}
|
||||
|
||||
//Do the accounting
|
||||
//Depending on the charging type of the message (set in the PriceTag),
|
||||
//it will charge the sender or receiver
|
||||
func (s *Swap) AccountMsgForPeer(event *p2p.PeerEvent) {
|
||||
func (s *Swap) accountMsgForPeer(event *p2p.PeerEvent) {
|
||||
price, direction := s.priceOracle.GetPriceForMsg(event)
|
||||
if price == nil {
|
||||
//TODO what to do in this case? Should not happen
|
||||
log.Crit("Price is nil; this should have been accounted for but somehow it failed")
|
||||
panic("Price is nil; this should have been accounted for but somehow it failed")
|
||||
}
|
||||
|
||||
if direction == ChargeSender {
|
||||
//we are sending a ChargeSender message, thus debit us and credit remote
|
||||
if event.Type == p2p.PeerEventTypeMsgSend {
|
||||
s.chargeLocal(event, price)
|
||||
//we are receiving a ChargeSender message, so credit us and debit remote
|
||||
} else if event.Type == p2p.PeerEventTypeMsgRecv {
|
||||
s.chargeRemote(event, price)
|
||||
}
|
||||
if chargeLocal := (direction == ChargeSender) == (event.Type == p2p.PeerEventTypeMsgSend); chargeLocal {
|
||||
//debit local node and credit remote
|
||||
s.chargeLocal(event, price)
|
||||
} else {
|
||||
//we are receiving a ChargeReceiver message, thus debit us and credit remote
|
||||
if event.Type == p2p.PeerEventTypeMsgRecv {
|
||||
s.chargeLocal(event, price)
|
||||
//we are sending a ChargeReceiver message, thus credit us and debit remote
|
||||
} else if event.Type == p2p.PeerEventTypeMsgSend {
|
||||
s.chargeRemote(event, price)
|
||||
}
|
||||
//credit local node and debit remote
|
||||
s.chargeRemote(event, price)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +287,7 @@ func (s *Swap) chargeRemote(event *p2p.PeerEvent, amount *big.Int) {
|
|||
}
|
||||
|
||||
//get a peer's balance
|
||||
func (swap *Swap) GetPeerBalance(peer discover.NodeID) *big.Int {
|
||||
func (swap *Swap) GetPeerBalance(peer enode.ID) *big.Int {
|
||||
swap.lock.RLock()
|
||||
defer swap.lock.RUnlock()
|
||||
if p, ok := swap.peers[peer]; ok {
|
||||
|
|
@ -315,7 +298,7 @@ func (swap *Swap) GetPeerBalance(peer discover.NodeID) *big.Int {
|
|||
|
||||
//Issue a cheque for the remote peer. Happens if we are indebted with the peer
|
||||
//and crossed the payment threshold
|
||||
func (s *Swap) issueCheque(ctx context.Context, id discover.NodeID) error {
|
||||
func (s *Swap) issueCheque(ctx context.Context, id enode.ID) error {
|
||||
amount := &big.Int{}
|
||||
cheque := s.chequeManager.CreateCheque(id, amount.Abs(payAt))
|
||||
msg := IssueChequeMsg{
|
||||
|
|
@ -337,7 +320,7 @@ func New(stateStore state.Store) (swap *Swap) {
|
|||
swap = &Swap{
|
||||
chequeManager: NewChequeManager(stateStore),
|
||||
stateStore: stateStore,
|
||||
peers: make(map[discover.NodeID]*big.Int),
|
||||
peers: make(map[enode.ID]*big.Int),
|
||||
priceOracle: priceOracle,
|
||||
protocol: NewProtocol(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import (
|
|||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -42,7 +41,6 @@ var (
|
|||
p2pPort = 30100
|
||||
ipcpath = ".swarm.ipc"
|
||||
datadirPrefix = ".data_"
|
||||
stackW = &sync.WaitGroup{}
|
||||
loglevel = flag.Int("loglevel", 2, "verbosity of logs")
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
// Copyright 2018 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package swarm
|
||||
|
||||
import (
|
||||
|
|
@ -14,7 +30,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"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/p2p/simulations/adapters"
|
||||
"github.com/ethereum/go-ethereum/swarm/api"
|
||||
"github.com/ethereum/go-ethereum/swarm/log"
|
||||
|
|
@ -121,7 +137,7 @@ func TestSwapNetworkSymmetricFileUpload(t *testing.T) {
|
|||
|
||||
//every node has a map to all nodes it had interactions
|
||||
//each entry in the map is a map of the other node with all the balances
|
||||
balancesMap := make(map[discover.NodeID]map[discover.NodeID]*big.Int)
|
||||
balancesMap := make(map[enode.ID]map[enode.ID]*big.Int)
|
||||
|
||||
//iterate all nodes
|
||||
for _, node := range sim.NodeIDs() {
|
||||
|
|
@ -133,7 +149,7 @@ func TestSwapNetworkSymmetricFileUpload(t *testing.T) {
|
|||
swarm := item.(*Swarm)
|
||||
|
||||
//submap for each node is a map of all nodes with the balance for that node
|
||||
subBalances := make(map[discover.NodeID]*big.Int)
|
||||
subBalances := make(map[enode.ID]*big.Int)
|
||||
|
||||
//iterate all nodes again...
|
||||
//get all balances with other peers for every node
|
||||
|
|
@ -295,7 +311,7 @@ func TestSwapNetworkAsymmetricFileUpload(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
balancesMap := make(map[discover.NodeID]map[discover.NodeID]*big.Int)
|
||||
balancesMap := make(map[enode.ID]map[enode.ID]*big.Int)
|
||||
|
||||
for _, node := range sim.NodeIDs() {
|
||||
item, ok := sim.NodeItem(node, bucketKeySwarm)
|
||||
|
|
@ -305,7 +321,7 @@ func TestSwapNetworkAsymmetricFileUpload(t *testing.T) {
|
|||
}
|
||||
swarm := item.(*Swarm)
|
||||
|
||||
subBalances := make(map[discover.NodeID]*big.Int)
|
||||
subBalances := make(map[enode.ID]*big.Int)
|
||||
|
||||
for _, n := range sim.NodeIDs() {
|
||||
if node == n {
|
||||
|
|
|
|||
|
|
@ -178,12 +178,6 @@ func NewSwarm(config *api.Config, mockStore *mock.NodeStore) (self *Swarm, err e
|
|||
if err := nodeID.UnmarshalText([]byte(config.NodeID)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if config.SwapEnabled {
|
||||
self.swap, err = swap.New(stateStore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
self.streamer = stream.NewRegistry(nodeID, delivery, self.netStore, stateStore, &stream.RegistryOptions{
|
||||
SkipCheck: config.DeliverySkipCheck,
|
||||
DoSync: config.SyncEnabled,
|
||||
|
|
|
|||
Loading…
Reference in a new issue