-
Notifications
You must be signed in to change notification settings - Fork 0
/
inmemory.go
119 lines (107 loc) · 3.35 KB
/
inmemory.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package simplepath
import (
"context"
"github.com/go-errors/errors"
"github.com/sanjayhashcash/go/exp/orderbook"
"github.com/sanjayhashcash/go/services/aurora/internal/paths"
"github.com/sanjayhashcash/go/xdr"
)
const (
maxAssetsPerPath = 5
// MaxInMemoryPathLength is the maximum path length which can be queried by the InMemoryFinder
MaxInMemoryPathLength = 5
)
var (
// ErrEmptyInMemoryOrderBook indicates that the in memory order book is not yet populated
ErrEmptyInMemoryOrderBook = errors.New("Empty orderbook")
)
// InMemoryFinder is an implementation of the path finding interface
// using the in memory orderbook
type InMemoryFinder struct {
graph *orderbook.OrderBookGraph
includePools bool
}
// NewInMemoryFinder constructs a new InMemoryFinder instance
func NewInMemoryFinder(graph *orderbook.OrderBookGraph, includePools bool) InMemoryFinder {
return InMemoryFinder{
graph: graph,
includePools: includePools,
}
}
// Find implements the path payments finder interface
func (finder InMemoryFinder) Find(ctx context.Context, q paths.Query, maxLength uint) ([]paths.Path, uint32, error) {
if finder.graph.IsEmpty() {
return nil, 0, ErrEmptyInMemoryOrderBook
}
if maxLength == 0 {
maxLength = MaxInMemoryPathLength
}
if maxLength > MaxInMemoryPathLength {
return nil, 0, errors.New("invalid value of maxLength")
}
orderbookPaths, lastLedger, err := finder.graph.FindPaths(
ctx,
int(maxLength),
q.DestinationAsset,
q.DestinationAmount,
q.SourceAccount,
q.SourceAssets,
q.SourceAssetBalances,
q.ValidateSourceBalance,
maxAssetsPerPath,
finder.includePools,
)
results := make([]paths.Path, len(orderbookPaths))
for i, path := range orderbookPaths {
results[i] = paths.Path{
Path: path.InteriorNodes,
Source: path.SourceAsset,
SourceAmount: path.SourceAmount,
Destination: path.DestinationAsset,
DestinationAmount: path.DestinationAmount,
}
}
return results, lastLedger, err
}
// FindFixedPaths returns a list of payment paths where the source and destination
// assets are fixed. All returned payment paths will start by spending `amountToSpend`
// of `sourceAsset` and will end with some positive balance of `destinationAsset`.
// `sourceAccountID` is optional. if `sourceAccountID` is provided then no offers
// created by `sourceAccountID` will be considered when evaluating payment paths
func (finder InMemoryFinder) FindFixedPaths(
ctx context.Context,
sourceAsset xdr.Asset,
amountToSpend xdr.Int64,
destinationAssets []xdr.Asset,
maxLength uint,
) ([]paths.Path, uint32, error) {
if finder.graph.IsEmpty() {
return nil, 0, ErrEmptyInMemoryOrderBook
}
if maxLength == 0 {
maxLength = MaxInMemoryPathLength
}
if maxLength > MaxInMemoryPathLength {
return nil, 0, errors.New("invalid value of maxLength")
}
orderbookPaths, lastLedger, err := finder.graph.FindFixedPaths(
ctx,
int(maxLength),
sourceAsset,
amountToSpend,
destinationAssets,
maxAssetsPerPath,
finder.includePools,
)
results := make([]paths.Path, len(orderbookPaths))
for i, path := range orderbookPaths {
results[i] = paths.Path{
Path: path.InteriorNodes,
Source: path.SourceAsset,
SourceAmount: path.SourceAmount,
Destination: path.DestinationAsset,
DestinationAmount: path.DestinationAmount,
}
}
return results, lastLedger, err
}