terra/route_service.go

76 lines
1.9 KiB
Go

package terra
type RouteService interface {
RegisterPairs(pairs ...Pair)
FindRoutes(offer Token, ask Token, maxDepth int) []Route
FindArbitrages(token Token, maxDepth int) []Route
GetAllArbitrages(maxDepth int) []Route
}
type routeService struct {
pairs []Pair
}
func NewRouteService() RouteService {
return &routeService{}
}
func (s *routeService) RegisterPairs(pairs ...Pair) {
s.pairs = append(s.pairs, pairs...)
}
func (s *routeService) walkRoute(route Route, ask Token, depth, maxdepth int) []Route {
var res []Route
depth++
if depth > maxdepth {
return res
}
if route.AskToken().Equals(ask) {
res = append(res, route)
return res
}
for _, pair := range s.pairs {
if route.Contains(pair) {
continue
}
var newroute Route
if route.Last().SecondToken().Equals(pair.Token1()) {
newroute = route.CopyAndAdd(NewRoutePair(pair, true))
}
if route.Last().SecondToken().Equals(pair.Token2()) {
newroute = route.CopyAndAdd(NewRoutePair(pair, false))
}
if newroute == nil {
continue
}
res = append(res, s.walkRoute(newroute, ask, depth, maxdepth)...)
}
return res
}
func (s *routeService) FindRoutes(offer Token, ask Token, maxDepth int) []Route {
var res []Route
for _, pair := range s.pairs {
if pair.Token1().Equals(offer) {
res = append(res, s.walkRoute(NewRoute(NewRoutePair(pair, true)), ask, 0, maxDepth)...)
}
if pair.Token2().Equals(offer) {
res = append(res, s.walkRoute(NewRoute(NewRoutePair(pair, false)), ask, 0, maxDepth)...)
}
}
return res
}
func (s *routeService) FindArbitrages(token Token, maxDepth int) []Route {
return s.FindRoutes(token, token, maxDepth)
}
func (s *routeService) GetAllArbitrages(maxDepth int) []Route {
var res []Route
for _, pair := range s.pairs {
res = append(res, s.walkRoute(NewRoute(NewRoutePair(pair, true)), pair.Token1(), 0, maxDepth)...)
res = append(res, s.walkRoute(NewRoute(NewRoutePair(pair, false)), pair.Token2(), 0, maxDepth)...)
}
return res
}