chore_: router response moved to wallet responses location
Following the approach we did for keeping requests at the same location, these changes introduce new location for responses. `SuggestedRoutesResponse` is moved there and renamed to `RouterSuggestedRoutes` and code is updated accordingly. New type `Route` defined (since a single route is composed of zero or more paths). Types `Route`, `Path`, `Graph` and `Node` belong to a new `routs` package now.
This commit is contained in:
parent
00559692bc
commit
1bb9cbc573
|
@ -0,0 +1,15 @@
|
||||||
|
package responses
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/status-im/status-go/errors"
|
||||||
|
"github.com/status-im/status-go/services/wallet/router/routes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RouterSuggestedRoutes struct {
|
||||||
|
Uuid string `json:"Uuid"`
|
||||||
|
Best routes.Route `json:"Best,omitempty"`
|
||||||
|
Candidates routes.Route `json:"Candidates,omitempty"`
|
||||||
|
TokenPrice *float64 `json:"TokenPrice,omitempty"`
|
||||||
|
NativeChainTokenPrice *float64 `json:"NativeChainTokenPrice,omitempty"`
|
||||||
|
ErrorResponse *errors.ErrorResponse `json:"ErrorResponse,omitempty"`
|
||||||
|
}
|
|
@ -2,9 +2,10 @@ package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/status-im/status-go/services/wallet/common"
|
"github.com/status-im/status-go/services/wallet/common"
|
||||||
|
"github.com/status-im/status-go/services/wallet/router/routes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func removeBestRouteFromAllRouters(allRoutes [][]*Path, best []*Path) [][]*Path {
|
func removeBestRouteFromAllRouters(allRoutes []routes.Route, best routes.Route) []routes.Route {
|
||||||
for i := len(allRoutes) - 1; i >= 0; i-- {
|
for i := len(allRoutes) - 1; i >= 0; i-- {
|
||||||
route := allRoutes[i]
|
route := allRoutes[i]
|
||||||
routeFound := true
|
routeFound := true
|
||||||
|
@ -45,7 +46,7 @@ func getChainPriority(chainID uint64) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRoutePriority(route []*Path) int {
|
func getRoutePriority(route routes.Route) int {
|
||||||
priority := 0
|
priority := 0
|
||||||
for _, path := range route {
|
for _, path := range route {
|
||||||
priority += getChainPriority(path.FromChain.ChainID)
|
priority += getChainPriority(path.FromChain.ChainID)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/status-im/status-go/services/wallet/common"
|
"github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||||
|
"github.com/status-im/status-go/services/wallet/router/routes"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -20,7 +21,7 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterRoutes(routes [][]*Path, amountIn *big.Int, fromLockedAmount map[uint64]*hexutil.Big) [][]*Path {
|
func filterRoutes(routes []routes.Route, amountIn *big.Int, fromLockedAmount map[uint64]*hexutil.Big) []routes.Route {
|
||||||
for i := len(routes) - 1; i >= 0; i-- {
|
for i := len(routes) - 1; i >= 0; i-- {
|
||||||
routeAmount := big.NewInt(0)
|
routeAmount := big.NewInt(0)
|
||||||
for _, p := range routes[i] {
|
for _, p := range routes[i] {
|
||||||
|
@ -43,15 +44,15 @@ func filterRoutes(routes [][]*Path, amountIn *big.Int, fromLockedAmount map[uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterNetworkCompliance performs the first level of filtering based on network inclusion/exclusion criteria.
|
// filterNetworkCompliance performs the first level of filtering based on network inclusion/exclusion criteria.
|
||||||
func filterNetworkCompliance(routes [][]*Path, fromLockedAmount map[uint64]*hexutil.Big) [][]*Path {
|
func filterNetworkCompliance(allRoutes []routes.Route, fromLockedAmount map[uint64]*hexutil.Big) []routes.Route {
|
||||||
filteredRoutes := make([][]*Path, 0)
|
filteredRoutes := make([]routes.Route, 0)
|
||||||
if routes == nil || fromLockedAmount == nil {
|
if allRoutes == nil || fromLockedAmount == nil {
|
||||||
return filteredRoutes
|
return filteredRoutes
|
||||||
}
|
}
|
||||||
|
|
||||||
fromIncluded, fromExcluded := setupRouteValidationMaps(fromLockedAmount)
|
fromIncluded, fromExcluded := setupRouteValidationMaps(fromLockedAmount)
|
||||||
|
|
||||||
for _, route := range routes {
|
for _, route := range allRoutes {
|
||||||
if route == nil {
|
if route == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -65,7 +66,7 @@ func filterNetworkCompliance(routes [][]*Path, fromLockedAmount map[uint64]*hexu
|
||||||
}
|
}
|
||||||
|
|
||||||
// isValidForNetworkCompliance checks if a route complies with network inclusion/exclusion criteria.
|
// isValidForNetworkCompliance checks if a route complies with network inclusion/exclusion criteria.
|
||||||
func isValidForNetworkCompliance(route []*Path, fromIncluded, fromExcluded map[uint64]bool) bool {
|
func isValidForNetworkCompliance(route routes.Route, fromIncluded, fromExcluded map[uint64]bool) bool {
|
||||||
logger.Debug("Initial inclusion/exclusion maps",
|
logger.Debug("Initial inclusion/exclusion maps",
|
||||||
zap.Any("fromIncluded", fromIncluded),
|
zap.Any("fromIncluded", fromIncluded),
|
||||||
zap.Any("fromExcluded", fromExcluded),
|
zap.Any("fromExcluded", fromExcluded),
|
||||||
|
@ -117,10 +118,10 @@ func setupRouteValidationMaps(fromLockedAmount map[uint64]*hexutil.Big) (map[uin
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterCapacityValidation performs the second level of filtering based on amount and capacity validation.
|
// filterCapacityValidation performs the second level of filtering based on amount and capacity validation.
|
||||||
func filterCapacityValidation(routes [][]*Path, amountIn *big.Int, fromLockedAmount map[uint64]*hexutil.Big) [][]*Path {
|
func filterCapacityValidation(allRoutes []routes.Route, amountIn *big.Int, fromLockedAmount map[uint64]*hexutil.Big) []routes.Route {
|
||||||
filteredRoutes := make([][]*Path, 0)
|
filteredRoutes := make([]routes.Route, 0)
|
||||||
|
|
||||||
for _, route := range routes {
|
for _, route := range allRoutes {
|
||||||
if hasSufficientCapacity(route, amountIn, fromLockedAmount) {
|
if hasSufficientCapacity(route, amountIn, fromLockedAmount) {
|
||||||
filteredRoutes = append(filteredRoutes, route)
|
filteredRoutes = append(filteredRoutes, route)
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,7 @@ func filterCapacityValidation(routes [][]*Path, amountIn *big.Int, fromLockedAmo
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasSufficientCapacity checks if a route has sufficient capacity to handle the required amount.
|
// hasSufficientCapacity checks if a route has sufficient capacity to handle the required amount.
|
||||||
func hasSufficientCapacity(route []*Path, amountIn *big.Int, fromLockedAmount map[uint64]*hexutil.Big) bool {
|
func hasSufficientCapacity(route routes.Route, amountIn *big.Int, fromLockedAmount map[uint64]*hexutil.Big) bool {
|
||||||
for _, path := range route {
|
for _, path := range route {
|
||||||
if amount, ok := fromLockedAmount[path.FromChain.ChainID]; ok {
|
if amount, ok := fromLockedAmount[path.FromChain.ChainID]; ok {
|
||||||
if path.AmountIn.ToInt().Cmp(amount.ToInt()) != 0 {
|
if path.AmountIn.ToInt().Cmp(amount.ToInt()) != 0 {
|
||||||
|
@ -153,7 +154,7 @@ func hasSufficientCapacity(route []*Path, amountIn *big.Int, fromLockedAmount ma
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculateRestAmountIn calculates the remaining amount in for the route excluding the specified path
|
// calculateRestAmountIn calculates the remaining amount in for the route excluding the specified path
|
||||||
func calculateRestAmountIn(route []*Path, excludePath *Path) *big.Int {
|
func calculateRestAmountIn(route routes.Route, excludePath *routes.Path) *big.Int {
|
||||||
restAmountIn := big.NewInt(0)
|
restAmountIn := big.NewInt(0)
|
||||||
for _, path := range route {
|
for _, path := range route {
|
||||||
if path != excludePath {
|
if path != excludePath {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||||
|
"github.com/status-im/status-go/services/wallet/router/routes"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -26,24 +27,24 @@ var (
|
||||||
amount4 = hexutil.Big(*big.NewInt(400))
|
amount4 = hexutil.Big(*big.NewInt(400))
|
||||||
amount5 = hexutil.Big(*big.NewInt(500))
|
amount5 = hexutil.Big(*big.NewInt(500))
|
||||||
|
|
||||||
path0 = &Path{FromChain: network4, AmountIn: &amount0}
|
path0 = &routes.Path{FromChain: network4, AmountIn: &amount0}
|
||||||
|
|
||||||
pathC1A1 = &Path{FromChain: network1, AmountIn: &amount1}
|
pathC1A1 = &routes.Path{FromChain: network1, AmountIn: &amount1}
|
||||||
|
|
||||||
pathC2A1 = &Path{FromChain: network2, AmountIn: &amount1}
|
pathC2A1 = &routes.Path{FromChain: network2, AmountIn: &amount1}
|
||||||
pathC2A2 = &Path{FromChain: network2, AmountIn: &amount2}
|
pathC2A2 = &routes.Path{FromChain: network2, AmountIn: &amount2}
|
||||||
|
|
||||||
pathC3A1 = &Path{FromChain: network3, AmountIn: &amount1}
|
pathC3A1 = &routes.Path{FromChain: network3, AmountIn: &amount1}
|
||||||
pathC3A2 = &Path{FromChain: network3, AmountIn: &amount2}
|
pathC3A2 = &routes.Path{FromChain: network3, AmountIn: &amount2}
|
||||||
pathC3A3 = &Path{FromChain: network3, AmountIn: &amount3}
|
pathC3A3 = &routes.Path{FromChain: network3, AmountIn: &amount3}
|
||||||
|
|
||||||
pathC4A1 = &Path{FromChain: network4, AmountIn: &amount1}
|
pathC4A1 = &routes.Path{FromChain: network4, AmountIn: &amount1}
|
||||||
pathC4A4 = &Path{FromChain: network4, AmountIn: &amount4}
|
pathC4A4 = &routes.Path{FromChain: network4, AmountIn: &amount4}
|
||||||
|
|
||||||
pathC5A5 = &Path{FromChain: network5, AmountIn: &amount5}
|
pathC5A5 = &routes.Path{FromChain: network5, AmountIn: &amount5}
|
||||||
)
|
)
|
||||||
|
|
||||||
func routesEqual(t *testing.T, expected, actual [][]*Path) bool {
|
func routesEqual(t *testing.T, expected, actual []routes.Route) bool {
|
||||||
if len(expected) != len(actual) {
|
if len(expected) != len(actual) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -55,7 +56,7 @@ func routesEqual(t *testing.T, expected, actual [][]*Path) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func pathsEqual(t *testing.T, expected, actual []*Path) bool {
|
func pathsEqual(t *testing.T, expected, actual routes.Route) bool {
|
||||||
if len(expected) != len(actual) {
|
if len(expected) != len(actual) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -67,7 +68,7 @@ func pathsEqual(t *testing.T, expected, actual []*Path) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func pathEqual(t *testing.T, expected, actual *Path) bool {
|
func pathEqual(t *testing.T, expected, actual *routes.Path) bool {
|
||||||
if expected.FromChain.ChainID != actual.FromChain.ChainID {
|
if expected.FromChain.ChainID != actual.FromChain.ChainID {
|
||||||
t.Logf("expected chain ID '%d' , actual chain ID '%d'", expected.FromChain.ChainID, actual.FromChain.ChainID)
|
t.Logf("expected chain ID '%d' , actual chain ID '%d'", expected.FromChain.ChainID, actual.FromChain.ChainID)
|
||||||
return false
|
return false
|
||||||
|
@ -171,43 +172,43 @@ func TestSetupRouteValidationMaps(t *testing.T) {
|
||||||
func TestCalculateRestAmountIn(t *testing.T) {
|
func TestCalculateRestAmountIn(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
route []*Path
|
route routes.Route
|
||||||
excludePath *Path
|
excludePath *routes.Path
|
||||||
expected *big.Int
|
expected *big.Int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Exclude pathC1A1",
|
name: "Exclude pathC1A1",
|
||||||
route: []*Path{pathC1A1, pathC2A2, pathC3A3},
|
route: routes.Route{pathC1A1, pathC2A2, pathC3A3},
|
||||||
excludePath: pathC1A1,
|
excludePath: pathC1A1,
|
||||||
expected: big.NewInt(500), // 200 + 300
|
expected: big.NewInt(500), // 200 + 300
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Exclude pathC2A2",
|
name: "Exclude pathC2A2",
|
||||||
route: []*Path{pathC1A1, pathC2A2, pathC3A3},
|
route: routes.Route{pathC1A1, pathC2A2, pathC3A3},
|
||||||
excludePath: pathC2A2,
|
excludePath: pathC2A2,
|
||||||
expected: big.NewInt(400), // 100 + 300
|
expected: big.NewInt(400), // 100 + 300
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Exclude pathC3A3",
|
name: "Exclude pathC3A3",
|
||||||
route: []*Path{pathC1A1, pathC2A2, pathC3A3},
|
route: routes.Route{pathC1A1, pathC2A2, pathC3A3},
|
||||||
excludePath: pathC3A3,
|
excludePath: pathC3A3,
|
||||||
expected: big.NewInt(300), // 100 + 200
|
expected: big.NewInt(300), // 100 + 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single path, exclude that path",
|
name: "Single path, exclude that path",
|
||||||
route: []*Path{pathC1A1},
|
route: routes.Route{pathC1A1},
|
||||||
excludePath: pathC1A1,
|
excludePath: pathC1A1,
|
||||||
expected: big.NewInt(0), // No other paths
|
expected: big.NewInt(0), // No other paths
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty route",
|
name: "Empty route",
|
||||||
route: []*Path{},
|
route: routes.Route{},
|
||||||
excludePath: pathC1A1,
|
excludePath: pathC1A1,
|
||||||
expected: big.NewInt(0), // No paths
|
expected: big.NewInt(0), // No paths
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty route, with nil exclude",
|
name: "Empty route, with nil exclude",
|
||||||
route: []*Path{},
|
route: routes.Route{},
|
||||||
excludePath: nil,
|
excludePath: nil,
|
||||||
expected: big.NewInt(0), // No paths
|
expected: big.NewInt(0), // No paths
|
||||||
},
|
},
|
||||||
|
@ -224,56 +225,56 @@ func TestCalculateRestAmountIn(t *testing.T) {
|
||||||
func TestIsValidForNetworkCompliance(t *testing.T) {
|
func TestIsValidForNetworkCompliance(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
route []*Path
|
route routes.Route
|
||||||
fromIncluded map[uint64]bool
|
fromIncluded map[uint64]bool
|
||||||
fromExcluded map[uint64]bool
|
fromExcluded map[uint64]bool
|
||||||
expectedResult bool
|
expectedResult bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Route with all included chain IDs",
|
name: "Route with all included chain IDs",
|
||||||
route: []*Path{pathC1A1, pathC2A2},
|
route: routes.Route{pathC1A1, pathC2A2},
|
||||||
fromIncluded: map[uint64]bool{1: true, 2: true},
|
fromIncluded: map[uint64]bool{1: true, 2: true},
|
||||||
fromExcluded: map[uint64]bool{},
|
fromExcluded: map[uint64]bool{},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route with fromExcluded only",
|
name: "Route with fromExcluded only",
|
||||||
route: []*Path{pathC1A1, pathC2A2},
|
route: routes.Route{pathC1A1, pathC2A2},
|
||||||
fromIncluded: map[uint64]bool{},
|
fromIncluded: map[uint64]bool{},
|
||||||
fromExcluded: map[uint64]bool{3: false, 4: false},
|
fromExcluded: map[uint64]bool{3: false, 4: false},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route without excluded chain IDs",
|
name: "Route without excluded chain IDs",
|
||||||
route: []*Path{pathC1A1, pathC2A2},
|
route: routes.Route{pathC1A1, pathC2A2},
|
||||||
fromIncluded: map[uint64]bool{1: false, 2: false},
|
fromIncluded: map[uint64]bool{1: false, 2: false},
|
||||||
fromExcluded: map[uint64]bool{3: false, 4: false},
|
fromExcluded: map[uint64]bool{3: false, 4: false},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route with an excluded chain ID",
|
name: "Route with an excluded chain ID",
|
||||||
route: []*Path{pathC1A1, pathC3A3},
|
route: routes.Route{pathC1A1, pathC3A3},
|
||||||
fromIncluded: map[uint64]bool{1: false, 2: false},
|
fromIncluded: map[uint64]bool{1: false, 2: false},
|
||||||
fromExcluded: map[uint64]bool{3: false, 4: false},
|
fromExcluded: map[uint64]bool{3: false, 4: false},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route missing one included chain ID",
|
name: "Route missing one included chain ID",
|
||||||
route: []*Path{pathC1A1},
|
route: routes.Route{pathC1A1},
|
||||||
fromIncluded: map[uint64]bool{1: false, 2: false},
|
fromIncluded: map[uint64]bool{1: false, 2: false},
|
||||||
fromExcluded: map[uint64]bool{},
|
fromExcluded: map[uint64]bool{},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route with no fromIncluded or fromExcluded",
|
name: "Route with no fromIncluded or fromExcluded",
|
||||||
route: []*Path{pathC1A1, pathC2A2},
|
route: routes.Route{pathC1A1, pathC2A2},
|
||||||
fromIncluded: map[uint64]bool{},
|
fromIncluded: map[uint64]bool{},
|
||||||
fromExcluded: map[uint64]bool{},
|
fromExcluded: map[uint64]bool{},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty route",
|
name: "Empty route",
|
||||||
route: []*Path{},
|
route: routes.Route{},
|
||||||
fromIncluded: map[uint64]bool{1: false, 2: false},
|
fromIncluded: map[uint64]bool{1: false, 2: false},
|
||||||
fromExcluded: map[uint64]bool{3: false, 4: false},
|
fromExcluded: map[uint64]bool{3: false, 4: false},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
|
@ -291,14 +292,14 @@ func TestIsValidForNetworkCompliance(t *testing.T) {
|
||||||
func TestHasSufficientCapacity(t *testing.T) {
|
func TestHasSufficientCapacity(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
route []*Path
|
route routes.Route
|
||||||
amountIn *big.Int
|
amountIn *big.Int
|
||||||
fromLockedAmount map[uint64]*hexutil.Big
|
fromLockedAmount map[uint64]*hexutil.Big
|
||||||
expected bool
|
expected bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "All paths meet required amount",
|
name: "All paths meet required amount",
|
||||||
route: []*Path{pathC1A1, pathC2A2, pathC3A3},
|
route: routes.Route{pathC1A1, pathC2A2, pathC3A3},
|
||||||
amountIn: big.NewInt(600),
|
amountIn: big.NewInt(600),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3},
|
||||||
expected: true,
|
expected: true,
|
||||||
|
@ -308,7 +309,7 @@ func TestHasSufficientCapacity(t *testing.T) {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
name: "A path does not meet required amount",
|
name: "A path does not meet required amount",
|
||||||
route: []*Path{pathC1A1, pathC2A2, pathC3A3},
|
route: routes.Route{pathC1A1, pathC2A2, pathC3A3},
|
||||||
amountIn: big.NewInt(600),
|
amountIn: big.NewInt(600),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 4: &amount4},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 4: &amount4},
|
||||||
expected: false,
|
expected: false,
|
||||||
|
@ -316,42 +317,42 @@ func TestHasSufficientCapacity(t *testing.T) {
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
name: "No fromLockedAmount",
|
name: "No fromLockedAmount",
|
||||||
route: []*Path{pathC1A1, pathC2A2, pathC3A3},
|
route: routes.Route{pathC1A1, pathC2A2, pathC3A3},
|
||||||
amountIn: big.NewInt(600),
|
amountIn: big.NewInt(600),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{},
|
fromLockedAmount: map[uint64]*hexutil.Big{},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single path meets required amount",
|
name: "Single path meets required amount",
|
||||||
route: []*Path{pathC1A1},
|
route: routes.Route{pathC1A1},
|
||||||
amountIn: big.NewInt(100),
|
amountIn: big.NewInt(100),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single path does not meet required amount",
|
name: "Single path does not meet required amount",
|
||||||
route: []*Path{pathC1A1},
|
route: routes.Route{pathC1A1},
|
||||||
amountIn: big.NewInt(200),
|
amountIn: big.NewInt(200),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Path meets required amount with excess",
|
name: "Path meets required amount with excess",
|
||||||
route: []*Path{pathC1A1, pathC2A2},
|
route: routes.Route{pathC1A1, pathC2A2},
|
||||||
amountIn: big.NewInt(250),
|
amountIn: big.NewInt(250),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Path does not meet required amount due to insufficient rest",
|
name: "Path does not meet required amount due to insufficient rest",
|
||||||
route: []*Path{pathC1A1, pathC2A2, pathC4A4},
|
route: routes.Route{pathC1A1, pathC2A2, pathC4A4},
|
||||||
amountIn: big.NewInt(800),
|
amountIn: big.NewInt(800),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 4: &amount4},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 4: &amount4},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty route",
|
name: "Empty route",
|
||||||
route: []*Path{},
|
route: routes.Route{},
|
||||||
amountIn: big.NewInt(500),
|
amountIn: big.NewInt(500),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2},
|
||||||
expected: true,
|
expected: true,
|
||||||
|
@ -369,13 +370,13 @@ func TestHasSufficientCapacity(t *testing.T) {
|
||||||
func TestFilterNetworkCompliance(t *testing.T) {
|
func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
routes [][]*Path
|
routes []routes.Route
|
||||||
fromLockedAmount map[uint64]*hexutil.Big
|
fromLockedAmount map[uint64]*hexutil.Big
|
||||||
expected [][]*Path
|
expected []routes.Route
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Mixed routes with valid and invalid paths",
|
name: "Mixed routes with valid and invalid paths",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network3},
|
{FromChain: network3},
|
||||||
|
@ -394,7 +395,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
2: (*hexutil.Big)(big.NewInt(0)),
|
2: (*hexutil.Big)(big.NewInt(0)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network3},
|
{FromChain: network3},
|
||||||
|
@ -403,7 +404,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "All valid routes",
|
name: "All valid routes",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network3},
|
{FromChain: network3},
|
||||||
|
@ -416,7 +417,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network3},
|
{FromChain: network3},
|
||||||
|
@ -429,7 +430,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "All invalid routes",
|
name: "All invalid routes",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network2},
|
{FromChain: network2},
|
||||||
{FromChain: network3},
|
{FromChain: network3},
|
||||||
|
@ -443,19 +444,19 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
2: (*hexutil.Big)(big.NewInt(0)),
|
2: (*hexutil.Big)(big.NewInt(0)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{},
|
expected: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty routes",
|
name: "Empty routes",
|
||||||
routes: [][]*Path{},
|
routes: []routes.Route{},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{},
|
expected: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "No locked amounts",
|
name: "No locked amounts",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network2},
|
{FromChain: network2},
|
||||||
|
@ -466,7 +467,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{},
|
fromLockedAmount: map[uint64]*hexutil.Big{},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network2},
|
{FromChain: network2},
|
||||||
|
@ -479,7 +480,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single route with mixed valid and invalid paths",
|
name: "Single route with mixed valid and invalid paths",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network2},
|
{FromChain: network2},
|
||||||
|
@ -490,11 +491,11 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
2: (*hexutil.Big)(big.NewInt(0)),
|
2: (*hexutil.Big)(big.NewInt(0)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{},
|
expected: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes with duplicate chain IDs",
|
name: "Routes with duplicate chain IDs",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
|
@ -504,7 +505,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
|
@ -514,7 +515,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Minimum and maximum chain IDs",
|
name: "Minimum and maximum chain IDs",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: ¶ms.Network{ChainID: 0}},
|
{FromChain: ¶ms.Network{ChainID: 0}},
|
||||||
{FromChain: ¶ms.Network{ChainID: ^uint64(0)}},
|
{FromChain: ¶ms.Network{ChainID: ^uint64(0)}},
|
||||||
|
@ -524,7 +525,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
0: (*hexutil.Big)(big.NewInt(100)),
|
0: (*hexutil.Big)(big.NewInt(100)),
|
||||||
^uint64(0): (*hexutil.Big)(big.NewInt(100)),
|
^uint64(0): (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: ¶ms.Network{ChainID: 0}},
|
{FromChain: ¶ms.Network{ChainID: 0}},
|
||||||
{FromChain: ¶ms.Network{ChainID: ^uint64(0)}},
|
{FromChain: ¶ms.Network{ChainID: ^uint64(0)}},
|
||||||
|
@ -533,34 +534,34 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Large number of routes",
|
name: "Large number of routes",
|
||||||
routes: func() [][]*Path {
|
routes: func() []routes.Route {
|
||||||
var routes [][]*Path
|
var routes1 []routes.Route
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
routes = append(routes, []*Path{
|
routes1 = append(routes1, routes.Route{
|
||||||
{FromChain: ¶ms.Network{ChainID: uint64(i + 1)}},
|
{FromChain: ¶ms.Network{ChainID: uint64(i + 1)}},
|
||||||
{FromChain: ¶ms.Network{ChainID: uint64(i + 1001)}},
|
{FromChain: ¶ms.Network{ChainID: uint64(i + 1001)}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return routes
|
return routes1
|
||||||
}(),
|
}(),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
1001: (*hexutil.Big)(big.NewInt(100)),
|
1001: (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expected: func() [][]*Path {
|
expected: func() []routes.Route {
|
||||||
var routes [][]*Path
|
var routes1 []routes.Route
|
||||||
for i := 0; i < 1; i++ {
|
for i := 0; i < 1; i++ {
|
||||||
routes = append(routes, []*Path{
|
routes1 = append(routes1, routes.Route{
|
||||||
{FromChain: ¶ms.Network{ChainID: uint64(i + 1)}},
|
{FromChain: ¶ms.Network{ChainID: uint64(i + 1)}},
|
||||||
{FromChain: ¶ms.Network{ChainID: uint64(i + 1001)}},
|
{FromChain: ¶ms.Network{ChainID: uint64(i + 1001)}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return routes
|
return routes1
|
||||||
}(),
|
}(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes with missing data",
|
name: "Routes with missing data",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: nil},
|
{FromChain: nil},
|
||||||
{FromChain: network2},
|
{FromChain: network2},
|
||||||
|
@ -574,11 +575,11 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
2: (*hexutil.Big)(big.NewInt(0)),
|
2: (*hexutil.Big)(big.NewInt(0)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{},
|
expected: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Consistency check",
|
name: "Consistency check",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network2},
|
{FromChain: network2},
|
||||||
|
@ -591,7 +592,7 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1},
|
{FromChain: network1},
|
||||||
{FromChain: network2},
|
{FromChain: network2},
|
||||||
|
@ -604,77 +605,77 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes without excluded chain IDs, missing included path",
|
name: "Routes without excluded chain IDs, missing included path",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes with an excluded chain ID",
|
name: "Routes with an excluded chain ID",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3, path0},
|
{pathC2A2, pathC3A3, path0},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 4: &amount0},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 4: &amount0},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes with all included chain IDs",
|
name: "Routes with all included chain IDs",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2, pathC3A3},
|
{pathC1A1, pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{pathC1A1, pathC2A2, pathC3A3},
|
{pathC1A1, pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes missing one included chain ID",
|
name: "Routes missing one included chain ID",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC1A1},
|
{pathC1A1},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3},
|
||||||
expected: [][]*Path{},
|
expected: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes with no fromLockedAmount",
|
name: "Routes with no fromLockedAmount",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{},
|
fromLockedAmount: map[uint64]*hexutil.Big{},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes with fromExcluded only",
|
name: "Routes with fromExcluded only",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{4: &amount0},
|
fromLockedAmount: map[uint64]*hexutil.Big{4: &amount0},
|
||||||
expected: [][]*Path{
|
expected: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Routes with all excluded chain IDs",
|
name: "Routes with all excluded chain IDs",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{path0, pathC1A1},
|
{path0, pathC1A1},
|
||||||
{path0, pathC2A2},
|
{path0, pathC2A2},
|
||||||
},
|
},
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3, 4: &amount0},
|
fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 3: &amount3, 4: &amount0},
|
||||||
expected: [][]*Path{},
|
expected: []routes.Route{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,14 +692,14 @@ func TestFilterNetworkCompliance(t *testing.T) {
|
||||||
func TestFilterCapacityValidation(t *testing.T) {
|
func TestFilterCapacityValidation(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
routes [][]*Path
|
routes []routes.Route
|
||||||
amountIn *big.Int
|
amountIn *big.Int
|
||||||
fromLockedAmount map[uint64]*hexutil.Big
|
fromLockedAmount map[uint64]*hexutil.Big
|
||||||
expectedRoutes [][]*Path
|
expectedRoutes []routes.Route
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Sufficient capacity with multiple paths",
|
name: "Sufficient capacity with multiple paths",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
|
@ -717,7 +718,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(50)),
|
1: (*hexutil.Big)(big.NewInt(50)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
|
@ -731,7 +732,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Insufficient capacity",
|
name: "Insufficient capacity",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
|
@ -742,11 +743,11 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(50)),
|
1: (*hexutil.Big)(big.NewInt(50)),
|
||||||
2: (*hexutil.Big)(big.NewInt(50)),
|
2: (*hexutil.Big)(big.NewInt(50)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Exact capacity match",
|
name: "Exact capacity match",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
|
@ -757,7 +758,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
2: (*hexutil.Big)(big.NewInt(50)),
|
2: (*hexutil.Big)(big.NewInt(50)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
|
@ -766,7 +767,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "No locked amounts",
|
name: "No locked amounts",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
|
@ -774,7 +775,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
amountIn: big.NewInt(150),
|
amountIn: big.NewInt(150),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{},
|
fromLockedAmount: map[uint64]*hexutil.Big{},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
|
@ -783,7 +784,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single route with sufficient capacity",
|
name: "Single route with sufficient capacity",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
|
@ -793,7 +794,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(50)),
|
1: (*hexutil.Big)(big.NewInt(50)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network2, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
|
@ -802,7 +803,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single route with inappropriately locked amount",
|
name: "Single route with inappropriately locked amount",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
},
|
},
|
||||||
|
@ -811,11 +812,11 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(50)),
|
1: (*hexutil.Big)(big.NewInt(50)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single route with insufficient capacity",
|
name: "Single route with insufficient capacity",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
},
|
},
|
||||||
|
@ -824,20 +825,20 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(50)),
|
1: (*hexutil.Big)(big.NewInt(50)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty routes",
|
name: "Empty routes",
|
||||||
routes: [][]*Path{},
|
routes: []routes.Route{},
|
||||||
amountIn: big.NewInt(150),
|
amountIn: big.NewInt(150),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: (*hexutil.Big)(big.NewInt(50)),
|
1: (*hexutil.Big)(big.NewInt(50)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Partial locked amounts",
|
name: "Partial locked amounts",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
|
@ -850,7 +851,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
2: (*hexutil.Big)(big.NewInt(0)), // Excluded path
|
2: (*hexutil.Big)(big.NewInt(0)), // Excluded path
|
||||||
3: (*hexutil.Big)(big.NewInt(100)),
|
3: (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(50))},
|
||||||
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
|
@ -860,7 +861,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Mixed networks with sufficient capacity",
|
name: "Mixed networks with sufficient capacity",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(200))},
|
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(200))},
|
||||||
|
@ -871,7 +872,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(100)),
|
1: (*hexutil.Big)(big.NewInt(100)),
|
||||||
3: (*hexutil.Big)(big.NewInt(200)),
|
3: (*hexutil.Big)(big.NewInt(200)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(200))},
|
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(200))},
|
||||||
|
@ -880,7 +881,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Mixed networks with insufficient capacity",
|
name: "Mixed networks with insufficient capacity",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{
|
{
|
||||||
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
{FromChain: network3, AmountIn: (*hexutil.Big)(big.NewInt(100))},
|
||||||
|
@ -891,7 +892,7 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
1: (*hexutil.Big)(big.NewInt(50)),
|
1: (*hexutil.Big)(big.NewInt(50)),
|
||||||
3: (*hexutil.Big)(big.NewInt(100)),
|
3: (*hexutil.Big)(big.NewInt(100)),
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,50 +909,50 @@ func TestFilterCapacityValidation(t *testing.T) {
|
||||||
func TestFilterRoutes(t *testing.T) {
|
func TestFilterRoutes(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
routes [][]*Path
|
routes []routes.Route
|
||||||
amountIn *big.Int
|
amountIn *big.Int
|
||||||
fromLockedAmount map[uint64]*hexutil.Big
|
fromLockedAmount map[uint64]*hexutil.Big
|
||||||
expectedRoutes [][]*Path
|
expectedRoutes []routes.Route
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Empty fromLockedAmount and routes don't match amountIn",
|
name: "Empty fromLockedAmount and routes don't match amountIn",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC3A3, pathC4A4},
|
{pathC3A3, pathC4A4},
|
||||||
},
|
},
|
||||||
amountIn: big.NewInt(150),
|
amountIn: big.NewInt(150),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{},
|
fromLockedAmount: map[uint64]*hexutil.Big{},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty fromLockedAmount and sigle route match amountIn",
|
name: "Empty fromLockedAmount and sigle route match amountIn",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC3A3, pathC4A4},
|
{pathC3A3, pathC4A4},
|
||||||
},
|
},
|
||||||
amountIn: big.NewInt(300),
|
amountIn: big.NewInt(300),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{},
|
fromLockedAmount: map[uint64]*hexutil.Big{},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty fromLockedAmount and more routes match amountIn",
|
name: "Empty fromLockedAmount and more routes match amountIn",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC3A3, pathC4A4},
|
{pathC3A3, pathC4A4},
|
||||||
{pathC1A1, pathC2A1, pathC3A1},
|
{pathC1A1, pathC2A1, pathC3A1},
|
||||||
},
|
},
|
||||||
amountIn: big.NewInt(300),
|
amountIn: big.NewInt(300),
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{},
|
fromLockedAmount: map[uint64]*hexutil.Big{},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC1A1, pathC2A1, pathC3A1},
|
{pathC1A1, pathC2A1, pathC3A1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "All paths appear in fromLockedAmount but not within a single route",
|
name: "All paths appear in fromLockedAmount but not within a single route",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC3A3},
|
{pathC1A1, pathC3A3},
|
||||||
{pathC2A2, pathC4A4},
|
{pathC2A2, pathC4A4},
|
||||||
},
|
},
|
||||||
|
@ -962,11 +963,11 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
3: &amount3,
|
3: &amount3,
|
||||||
4: &amount4,
|
4: &amount4,
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Mixed valid and invalid routes I",
|
name: "Mixed valid and invalid routes I",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
{pathC1A1, pathC4A4},
|
{pathC1A1, pathC4A4},
|
||||||
|
@ -977,13 +978,13 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
1: &amount1,
|
1: &amount1,
|
||||||
2: &amount2,
|
2: &amount2,
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Mixed valid and invalid routes II",
|
name: "Mixed valid and invalid routes II",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
{pathC1A1, pathC4A4},
|
{pathC1A1, pathC4A4},
|
||||||
|
@ -993,14 +994,14 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: &amount1,
|
1: &amount1,
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2},
|
{pathC1A1, pathC2A2},
|
||||||
{pathC1A1, pathC2A1, pathC3A1},
|
{pathC1A1, pathC2A1, pathC3A1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "All invalid routes",
|
name: "All invalid routes",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
{pathC4A4, pathC5A5},
|
{pathC4A4, pathC5A5},
|
||||||
},
|
},
|
||||||
|
@ -1008,11 +1009,11 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||||
1: &amount1,
|
1: &amount1,
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single valid route",
|
name: "Single valid route",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC3A3},
|
{pathC1A1, pathC3A3},
|
||||||
{pathC2A2, pathC3A3},
|
{pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
|
@ -1021,13 +1022,13 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
1: &amount1,
|
1: &amount1,
|
||||||
3: &amount3,
|
3: &amount3,
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{pathC1A1, pathC3A3},
|
{pathC1A1, pathC3A3},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route with mixed valid and invalid paths I",
|
name: "Route with mixed valid and invalid paths I",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC2A2, pathC3A3},
|
{pathC1A1, pathC2A2, pathC3A3},
|
||||||
},
|
},
|
||||||
amountIn: big.NewInt(300),
|
amountIn: big.NewInt(300),
|
||||||
|
@ -1035,11 +1036,11 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
1: &amount1,
|
1: &amount1,
|
||||||
2: &amount0, // This path should be filtered out due to being excluded via a zero amount
|
2: &amount0, // This path should be filtered out due to being excluded via a zero amount
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{},
|
expectedRoutes: []routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route with mixed valid and invalid paths II",
|
name: "Route with mixed valid and invalid paths II",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC3A3},
|
{pathC1A1, pathC3A3},
|
||||||
},
|
},
|
||||||
amountIn: big.NewInt(400),
|
amountIn: big.NewInt(400),
|
||||||
|
@ -1047,13 +1048,13 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
1: &amount1,
|
1: &amount1,
|
||||||
2: &amount0, // This path should be filtered out due to being excluded via a zero amount, 0 value locked means this chain is disabled
|
2: &amount0, // This path should be filtered out due to being excluded via a zero amount, 0 value locked means this chain is disabled
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{pathC1A1, pathC3A3},
|
{pathC1A1, pathC3A3},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Route with mixed valid and invalid paths III",
|
name: "Route with mixed valid and invalid paths III",
|
||||||
routes: [][]*Path{
|
routes: []routes.Route{
|
||||||
{pathC1A1, pathC3A3},
|
{pathC1A1, pathC3A3},
|
||||||
{pathC1A1, pathC3A2, pathC4A1},
|
{pathC1A1, pathC3A2, pathC4A1},
|
||||||
},
|
},
|
||||||
|
@ -1062,7 +1063,7 @@ func TestFilterRoutes(t *testing.T) {
|
||||||
1: &amount1,
|
1: &amount1,
|
||||||
2: &amount0, // This path should be filtered out due to being excluded via a zero amount, 0 value locked means this chain is disabled
|
2: &amount0, // This path should be filtered out due to being excluded via a zero amount, 0 value locked means this chain is disabled
|
||||||
},
|
},
|
||||||
expectedRoutes: [][]*Path{
|
expectedRoutes: []routes.Route{
|
||||||
{pathC1A1, pathC3A3},
|
{pathC1A1, pathC3A3},
|
||||||
{pathC1A1, pathC3A2, pathC4A1},
|
{pathC1A1, pathC3A2, pathC4A1},
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,8 +21,10 @@ import (
|
||||||
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/services/wallet/market"
|
"github.com/status-im/status-go/services/wallet/market"
|
||||||
"github.com/status-im/status-go/services/wallet/requests"
|
"github.com/status-im/status-go/services/wallet/requests"
|
||||||
|
"github.com/status-im/status-go/services/wallet/responses"
|
||||||
"github.com/status-im/status-go/services/wallet/router/fees"
|
"github.com/status-im/status-go/services/wallet/router/fees"
|
||||||
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||||
|
"github.com/status-im/status-go/services/wallet/router/routes"
|
||||||
"github.com/status-im/status-go/services/wallet/router/sendtype"
|
"github.com/status-im/status-go/services/wallet/router/sendtype"
|
||||||
"github.com/status-im/status-go/services/wallet/token"
|
"github.com/status-im/status-go/services/wallet/token"
|
||||||
walletToken "github.com/status-im/status-go/services/wallet/token"
|
walletToken "github.com/status-im/status-go/services/wallet/token"
|
||||||
|
@ -54,21 +56,12 @@ type ProcessorError struct {
|
||||||
|
|
||||||
type SuggestedRoutes struct {
|
type SuggestedRoutes struct {
|
||||||
Uuid string
|
Uuid string
|
||||||
Best []*Path
|
Best routes.Route
|
||||||
Candidates []*Path
|
Candidates routes.Route
|
||||||
TokenPrice float64
|
TokenPrice float64
|
||||||
NativeChainTokenPrice float64
|
NativeChainTokenPrice float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type SuggestedRoutesResponse struct {
|
|
||||||
Uuid string `json:"Uuid"`
|
|
||||||
Best []*Path `json:"Best,omitempty"`
|
|
||||||
Candidates []*Path `json:"Candidates,omitempty"`
|
|
||||||
TokenPrice *float64 `json:"TokenPrice,omitempty"`
|
|
||||||
NativeChainTokenPrice *float64 `json:"NativeChainTokenPrice,omitempty"`
|
|
||||||
ErrorResponse *errors.ErrorResponse `json:"ErrorResponse,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Router struct {
|
type Router struct {
|
||||||
rpcClient *rpc.Client
|
rpcClient *rpc.Client
|
||||||
tokenManager *token.Manager
|
tokenManager *token.Manager
|
||||||
|
@ -121,11 +114,11 @@ func (r *Router) GetPathProcessors() map[string]pathprocessor.PathProcessor {
|
||||||
func newSuggestedRoutes(
|
func newSuggestedRoutes(
|
||||||
uuid string,
|
uuid string,
|
||||||
amountIn *big.Int,
|
amountIn *big.Int,
|
||||||
candidates []*Path,
|
candidates routes.Route,
|
||||||
fromLockedAmount map[uint64]*hexutil.Big,
|
fromLockedAmount map[uint64]*hexutil.Big,
|
||||||
tokenPrice float64,
|
tokenPrice float64,
|
||||||
nativeChainTokenPrice float64,
|
nativeChainTokenPrice float64,
|
||||||
) (*SuggestedRoutes, [][]*Path) {
|
) (*SuggestedRoutes, []routes.Route) {
|
||||||
suggestedRoutes := &SuggestedRoutes{
|
suggestedRoutes := &SuggestedRoutes{
|
||||||
Uuid: uuid,
|
Uuid: uuid,
|
||||||
Candidates: candidates,
|
Candidates: candidates,
|
||||||
|
@ -136,11 +129,11 @@ func newSuggestedRoutes(
|
||||||
return suggestedRoutes, nil
|
return suggestedRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
node := &Node{
|
node := &routes.Node{
|
||||||
Path: nil,
|
Path: nil,
|
||||||
Children: buildGraph(amountIn, candidates, 0, []uint64{}),
|
Children: routes.BuildGraph(amountIn, candidates, 0, []uint64{}),
|
||||||
}
|
}
|
||||||
allRoutes := node.buildAllRoutes()
|
allRoutes := node.BuildAllRoutes()
|
||||||
allRoutes = filterRoutes(allRoutes, amountIn, fromLockedAmount)
|
allRoutes = filterRoutes(allRoutes, amountIn, fromLockedAmount)
|
||||||
|
|
||||||
if len(allRoutes) > 0 {
|
if len(allRoutes) > 0 {
|
||||||
|
@ -158,7 +151,7 @@ func (r *Router) SuggestedRoutesAsync(input *requests.RouteInputParams) {
|
||||||
r.scheduler.Enqueue(routerTask, func(ctx context.Context) (interface{}, error) {
|
r.scheduler.Enqueue(routerTask, func(ctx context.Context) (interface{}, error) {
|
||||||
return r.SuggestedRoutes(ctx, input)
|
return r.SuggestedRoutes(ctx, input)
|
||||||
}, func(result interface{}, taskType async.TaskType, err error) {
|
}, func(result interface{}, taskType async.TaskType, err error) {
|
||||||
routesResponse := SuggestedRoutesResponse{
|
routesResponse := responses.RouterSuggestedRoutes{
|
||||||
Uuid: input.Uuid,
|
Uuid: input.Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +504,7 @@ func (r *Router) getSelectedChains(input *requests.RouteInputParams) (selectedFr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInputParams, selectedFromChains []*params.Network,
|
func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInputParams, selectedFromChains []*params.Network,
|
||||||
selectedToChains []*params.Network, balanceMap map[string]*big.Int) (candidates []*Path, processorErrors []*ProcessorError, err error) {
|
selectedToChains []*params.Network, balanceMap map[string]*big.Int) (candidates routes.Route, processorErrors []*ProcessorError, err error) {
|
||||||
var (
|
var (
|
||||||
testsMode = input.TestsMode && input.TestParams != nil
|
testsMode = input.TestsMode && input.TestParams != nil
|
||||||
group = async.NewAtomicGroup(ctx)
|
group = async.NewAtomicGroup(ctx)
|
||||||
|
@ -533,7 +526,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPathFn := func(path *Path) {
|
appendPathFn := func(path *routes.Path) {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
candidates = append(candidates, path)
|
candidates = append(candidates, path)
|
||||||
|
@ -731,7 +724,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp
|
||||||
requiredNativeBalance.Add(requiredNativeBalance, ethTotalFees)
|
requiredNativeBalance.Add(requiredNativeBalance, ethTotalFees)
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPathFn(&Path{
|
appendPathFn(&routes.Path{
|
||||||
ProcessorName: pProcessor.Name(),
|
ProcessorName: pProcessor.Name(),
|
||||||
FromChain: network,
|
FromChain: network,
|
||||||
ToChain: dest,
|
ToChain: dest,
|
||||||
|
@ -767,9 +760,9 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp
|
||||||
|
|
||||||
EstimatedTime: estimatedTime,
|
EstimatedTime: estimatedTime,
|
||||||
|
|
||||||
subtractFees: amountOption.subtractFees,
|
SubtractFees: amountOption.subtractFees,
|
||||||
requiredTokenBalance: requiredTokenBalance,
|
RequiredTokenBalance: requiredTokenBalance,
|
||||||
requiredNativeBalance: requiredNativeBalance,
|
RequiredNativeBalance: requiredNativeBalance,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -788,7 +781,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp
|
||||||
return candidates, processorErrors, nil
|
return candidates, processorErrors, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute []*Path, balanceMap map[string]*big.Int) (hasPositiveBalance bool, err error) {
|
func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute routes.Route, balanceMap map[string]*big.Int) (hasPositiveBalance bool, err error) {
|
||||||
balanceMapCopy := walletCommon.CopyMapGeneric(balanceMap, func(v interface{}) interface{} {
|
balanceMapCopy := walletCommon.CopyMapGeneric(balanceMap, func(v interface{}) interface{} {
|
||||||
return new(big.Int).Set(v.(*big.Int))
|
return new(big.Int).Set(v.(*big.Int))
|
||||||
}).(map[string]*big.Int)
|
}).(map[string]*big.Int)
|
||||||
|
@ -811,16 +804,16 @@ func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute []*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if path.requiredTokenBalance != nil && path.requiredTokenBalance.Cmp(pathprocessor.ZeroBigIntValue) > 0 {
|
if path.RequiredTokenBalance != nil && path.RequiredTokenBalance.Cmp(pathprocessor.ZeroBigIntValue) > 0 {
|
||||||
if tokenBalance, ok := balanceMapCopy[tokenKey]; ok {
|
if tokenBalance, ok := balanceMapCopy[tokenKey]; ok {
|
||||||
if tokenBalance.Cmp(path.requiredTokenBalance) == -1 {
|
if tokenBalance.Cmp(path.RequiredTokenBalance) == -1 {
|
||||||
err := &errors.ErrorResponse{
|
err := &errors.ErrorResponse{
|
||||||
Code: ErrNotEnoughTokenBalance.Code,
|
Code: ErrNotEnoughTokenBalance.Code,
|
||||||
Details: fmt.Sprintf(ErrNotEnoughTokenBalance.Details, path.FromToken.Symbol, path.FromChain.ChainID),
|
Details: fmt.Sprintf(ErrNotEnoughTokenBalance.Details, path.FromToken.Symbol, path.FromChain.ChainID),
|
||||||
}
|
}
|
||||||
return hasPositiveBalance, err
|
return hasPositiveBalance, err
|
||||||
}
|
}
|
||||||
balanceMapCopy[tokenKey].Sub(tokenBalance, path.requiredTokenBalance)
|
balanceMapCopy[tokenKey].Sub(tokenBalance, path.RequiredTokenBalance)
|
||||||
} else {
|
} else {
|
||||||
return hasPositiveBalance, ErrTokenNotFound
|
return hasPositiveBalance, ErrTokenNotFound
|
||||||
}
|
}
|
||||||
|
@ -828,14 +821,14 @@ func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute []*
|
||||||
|
|
||||||
ethKey := makeBalanceKey(path.FromChain.ChainID, pathprocessor.EthSymbol)
|
ethKey := makeBalanceKey(path.FromChain.ChainID, pathprocessor.EthSymbol)
|
||||||
if nativeBalance, ok := balanceMapCopy[ethKey]; ok {
|
if nativeBalance, ok := balanceMapCopy[ethKey]; ok {
|
||||||
if nativeBalance.Cmp(path.requiredNativeBalance) == -1 {
|
if nativeBalance.Cmp(path.RequiredNativeBalance) == -1 {
|
||||||
err := &errors.ErrorResponse{
|
err := &errors.ErrorResponse{
|
||||||
Code: ErrNotEnoughNativeBalance.Code,
|
Code: ErrNotEnoughNativeBalance.Code,
|
||||||
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, path.FromChain.ChainID),
|
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, path.FromChain.ChainID),
|
||||||
}
|
}
|
||||||
return hasPositiveBalance, err
|
return hasPositiveBalance, err
|
||||||
}
|
}
|
||||||
balanceMapCopy[ethKey].Sub(nativeBalance, path.requiredNativeBalance)
|
balanceMapCopy[ethKey].Sub(nativeBalance, path.RequiredNativeBalance)
|
||||||
} else {
|
} else {
|
||||||
return hasPositiveBalance, ErrNativeTokenNotFound
|
return hasPositiveBalance, ErrNativeTokenNotFound
|
||||||
}
|
}
|
||||||
|
@ -844,7 +837,7 @@ func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute []*
|
||||||
return hasPositiveBalance, nil
|
return hasPositiveBalance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) resolveRoutes(ctx context.Context, input *requests.RouteInputParams, candidates []*Path, balanceMap map[string]*big.Int) (suggestedRoutes *SuggestedRoutes, err error) {
|
func (r *Router) resolveRoutes(ctx context.Context, input *requests.RouteInputParams, candidates routes.Route, balanceMap map[string]*big.Int) (suggestedRoutes *SuggestedRoutes, err error) {
|
||||||
var prices map[string]float64
|
var prices map[string]float64
|
||||||
if input.TestsMode {
|
if input.TestsMode {
|
||||||
prices = input.TestParams.TokenPrices
|
prices = input.TestParams.TokenPrices
|
||||||
|
@ -858,7 +851,7 @@ func (r *Router) resolveRoutes(ctx context.Context, input *requests.RouteInputPa
|
||||||
tokenPrice := prices[input.TokenID]
|
tokenPrice := prices[input.TokenID]
|
||||||
nativeTokenPrice := prices[pathprocessor.EthSymbol]
|
nativeTokenPrice := prices[pathprocessor.EthSymbol]
|
||||||
|
|
||||||
var allRoutes [][]*Path
|
var allRoutes []routes.Route
|
||||||
suggestedRoutes, allRoutes = newSuggestedRoutes(input.Uuid, input.AmountIn.ToInt(), candidates, input.FromLockedAmount, tokenPrice, nativeTokenPrice)
|
suggestedRoutes, allRoutes = newSuggestedRoutes(input.Uuid, input.AmountIn.ToInt(), candidates, input.FromLockedAmount, tokenPrice, nativeTokenPrice)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -872,13 +865,13 @@ func (r *Router) resolveRoutes(ctx context.Context, input *requests.RouteInputPa
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
bestRoute []*Path
|
bestRoute routes.Route
|
||||||
lastBestRouteWithPositiveBalance []*Path
|
lastBestRouteWithPositiveBalance routes.Route
|
||||||
lastBestRouteErr error
|
lastBestRouteErr error
|
||||||
)
|
)
|
||||||
|
|
||||||
for len(allRoutes) > 0 {
|
for len(allRoutes) > 0 {
|
||||||
bestRoute = findBest(allRoutes, tokenPrice, nativeTokenPrice)
|
bestRoute = routes.FindBestRoute(allRoutes, tokenPrice, nativeTokenPrice)
|
||||||
var hasPositiveBalance bool
|
var hasPositiveBalance bool
|
||||||
hasPositiveBalance, err = r.checkBalancesForTheBestRoute(ctx, bestRoute, balanceMap)
|
hasPositiveBalance, err = r.checkBalancesForTheBestRoute(ctx, bestRoute, balanceMap)
|
||||||
|
|
||||||
|
@ -913,7 +906,7 @@ func (r *Router) resolveRoutes(ctx context.Context, input *requests.RouteInputPa
|
||||||
if len(bestRoute) > 0 {
|
if len(bestRoute) > 0 {
|
||||||
// At this point we have to do the final check and update the amountIn (subtracting fees) if complete balance is going to be sent for native token (ETH)
|
// At this point we have to do the final check and update the amountIn (subtracting fees) if complete balance is going to be sent for native token (ETH)
|
||||||
for _, path := range bestRoute {
|
for _, path := range bestRoute {
|
||||||
if path.subtractFees && path.FromToken.IsNative() {
|
if path.SubtractFees && path.FromToken.IsNative() {
|
||||||
path.AmountIn.ToInt().Sub(path.AmountIn.ToInt(), path.TxFee.ToInt())
|
path.AmountIn.ToInt().Sub(path.AmountIn.ToInt(), path.TxFee.ToInt())
|
||||||
if path.TxL1Fee.ToInt().Cmp(pathprocessor.ZeroBigIntValue) > 0 {
|
if path.TxL1Fee.ToInt().Cmp(pathprocessor.ZeroBigIntValue) > 0 {
|
||||||
path.AmountIn.ToInt().Sub(path.AmountIn.ToInt(), path.TxL1Fee.ToInt())
|
path.AmountIn.ToInt().Sub(path.AmountIn.ToInt(), path.TxL1Fee.ToInt())
|
||||||
|
|
|
@ -10,7 +10,9 @@ import (
|
||||||
"github.com/status-im/status-go/appdatabase"
|
"github.com/status-im/status-go/appdatabase"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
"github.com/status-im/status-go/rpc"
|
"github.com/status-im/status-go/rpc"
|
||||||
|
"github.com/status-im/status-go/services/wallet/responses"
|
||||||
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||||
|
"github.com/status-im/status-go/services/wallet/router/routes"
|
||||||
"github.com/status-im/status-go/signal"
|
"github.com/status-im/status-go/signal"
|
||||||
"github.com/status-im/status-go/t/helpers"
|
"github.com/status-im/status-go/t/helpers"
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ func amountOptionsMapsEqual(map1, map2 map[uint64][]amountOption) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertPathsEqual(t *testing.T, expected, actual []*Path) {
|
func assertPathsEqual(t *testing.T, expected, actual routes.Route) {
|
||||||
assert.Equal(t, len(expected), len(actual))
|
assert.Equal(t, len(expected), len(actual))
|
||||||
if len(expected) == 0 {
|
if len(expected) == 0 {
|
||||||
return
|
return
|
||||||
|
@ -124,19 +126,19 @@ func setupRouter(t *testing.T) (*Router, func()) {
|
||||||
return router, cleanTmpDb
|
return router, cleanTmpDb
|
||||||
}
|
}
|
||||||
|
|
||||||
type suggestedRoutesResponseEnvelope struct {
|
type routerSuggestedRoutesEnvelope struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Routes SuggestedRoutesResponse `json:"event"`
|
Routes responses.RouterSuggestedRoutes `json:"event"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupSignalHandler(t *testing.T) (chan SuggestedRoutesResponse, func()) {
|
func setupSignalHandler(t *testing.T) (chan responses.RouterSuggestedRoutes, func()) {
|
||||||
suggestedRoutesCh := make(chan SuggestedRoutesResponse)
|
suggestedRoutesCh := make(chan responses.RouterSuggestedRoutes)
|
||||||
signalHandler := signal.MobileSignalHandler(func(data []byte) {
|
signalHandler := signal.MobileSignalHandler(func(data []byte) {
|
||||||
var envelope signal.Envelope
|
var envelope signal.Envelope
|
||||||
err := json.Unmarshal(data, &envelope)
|
err := json.Unmarshal(data, &envelope)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if envelope.Type == string(signal.SuggestedRoutes) {
|
if envelope.Type == string(signal.SuggestedRoutes) {
|
||||||
var response suggestedRoutesResponseEnvelope
|
var response routerSuggestedRoutesEnvelope
|
||||||
err := json.Unmarshal(data, &response)
|
err := json.Unmarshal(data, &response)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/status-im/status-go/services/wallet/requests"
|
"github.com/status-im/status-go/services/wallet/requests"
|
||||||
"github.com/status-im/status-go/services/wallet/router/fees"
|
"github.com/status-im/status-go/services/wallet/router/fees"
|
||||||
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||||
|
"github.com/status-im/status-go/services/wallet/router/routes"
|
||||||
"github.com/status-im/status-go/services/wallet/router/sendtype"
|
"github.com/status-im/status-go/services/wallet/router/sendtype"
|
||||||
"github.com/status-im/status-go/services/wallet/token"
|
"github.com/status-im/status-go/services/wallet/token"
|
||||||
)
|
)
|
||||||
|
@ -205,7 +206,7 @@ var defaultNetworks = []params.Network{
|
||||||
type normalTestParams struct {
|
type normalTestParams struct {
|
||||||
name string
|
name string
|
||||||
input *requests.RouteInputParams
|
input *requests.RouteInputParams
|
||||||
expectedCandidates []*Path
|
expectedCandidates routes.Route
|
||||||
expectedError *errors.ErrorResponse
|
expectedError *errors.ErrorResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
Code: errors.GenericErrorCode,
|
Code: errors.GenericErrorCode,
|
||||||
Details: fmt.Sprintf("failed with 50000000 gas: insufficient funds for gas * price + value: address %s", common.HexToAddress("0x1")),
|
Details: fmt.Sprintf("failed with 50000000 gas: insufficient funds for gas * price + value: address %s", common.HexToAddress("0x1")),
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ETH transfer - No Specific FromChain - No Specific ToChain - 0 AmountIn",
|
name: "ETH transfer - No Specific FromChain - No Specific ToChain - 0 AmountIn",
|
||||||
|
@ -278,7 +279,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -326,7 +327,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -412,7 +413,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -462,7 +463,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
|
@ -531,7 +532,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -581,7 +582,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
|
@ -650,7 +651,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -689,7 +690,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -728,7 +729,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -767,7 +768,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -824,7 +825,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -865,7 +866,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: ErrNoBestRouteFound,
|
expectedError: ErrNoBestRouteFound,
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ETH transfer - No Specific FromChain - No Specific ToChain - Single Chain LockedAmount",
|
name: "ETH transfer - No Specific FromChain - No Specific ToChain - Single Chain LockedAmount",
|
||||||
|
@ -898,7 +899,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -997,7 +998,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
|
@ -1053,7 +1054,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -1152,7 +1153,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -1252,7 +1253,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: requests.ErrLockedAmountLessThanSendAmountAllNetworks,
|
expectedError: requests.ErrLockedAmountLessThanSendAmountAllNetworks,
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ETH transfer - No Specific FromChain - No Specific ToChain - LockedAmount exceeds sending amount",
|
name: "ETH transfer - No Specific FromChain - No Specific ToChain - LockedAmount exceeds sending amount",
|
||||||
|
@ -1287,7 +1288,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: requests.ErrLockedAmountExceedsTotalSendAmount,
|
expectedError: requests.ErrLockedAmountExceedsTotalSendAmount,
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ERC20 transfer - No Specific FromChain - No Specific ToChain",
|
name: "ERC20 transfer - No Specific FromChain - No Specific ToChain",
|
||||||
|
@ -1317,7 +1318,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -1403,7 +1404,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -1453,7 +1454,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
|
@ -1521,7 +1522,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -1571,7 +1572,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
|
@ -1640,7 +1641,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -1679,7 +1680,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -1718,7 +1719,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -1757,7 +1758,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -1814,7 +1815,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -1854,7 +1855,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: ErrNoBestRouteFound,
|
expectedError: ErrNoBestRouteFound,
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ERC20 transfer - All FromChains - No Locked Amount - Enough Token Balance Across All Chains",
|
name: "ERC20 transfer - All FromChains - No Locked Amount - Enough Token Balance Across All Chains",
|
||||||
|
@ -1884,7 +1885,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2083,7 +2084,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2151,7 +2152,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
|
@ -2195,7 +2196,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2251,7 +2252,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -2295,7 +2296,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
|
@ -2353,7 +2354,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: ErrNoBestRouteFound,
|
expectedError: ErrNoBestRouteFound,
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bridge - Specific Single FromChain - Specific Single ToChain - Different Chains",
|
name: "Bridge - Specific Single FromChain - Specific Single ToChain - Different Chains",
|
||||||
|
@ -2385,7 +2386,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -2425,7 +2426,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: ErrNoBestRouteFound,
|
expectedError: ErrNoBestRouteFound,
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bridge - Specific Multiple FromChain - Specific Multiple ToChain - Multiple Common Chains",
|
name: "Bridge - Specific Multiple FromChain - Specific Multiple ToChain - Multiple Common Chains",
|
||||||
|
@ -2457,7 +2458,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2502,7 +2503,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -2542,7 +2543,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: ErrNoBestRouteFound,
|
expectedError: ErrNoBestRouteFound,
|
||||||
expectedCandidates: []*Path{},
|
expectedCandidates: routes.Route{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ETH transfer - Not Enough Native Balance",
|
name: "ETH transfer - Not Enough Native Balance",
|
||||||
|
@ -2577,7 +2578,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
Code: ErrNotEnoughNativeBalance.Code,
|
Code: ErrNotEnoughNativeBalance.Code,
|
||||||
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, walletCommon.EthereumMainnet),
|
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, walletCommon.EthereumMainnet),
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2619,7 +2620,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
Code: ErrNotEnoughTokenBalance.Code,
|
Code: ErrNotEnoughTokenBalance.Code,
|
||||||
Details: fmt.Sprintf(ErrNotEnoughTokenBalance.Details, pathprocessor.UsdcSymbol, walletCommon.EthereumMainnet),
|
Details: fmt.Sprintf(ErrNotEnoughTokenBalance.Details, pathprocessor.UsdcSymbol, walletCommon.EthereumMainnet),
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2659,7 +2660,7 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: ErrLowAmountInForHopBridge,
|
expectedError: ErrLowAmountInForHopBridge,
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
@ -2674,8 +2675,8 @@ func getNormalTestParamsList() []normalTestParams {
|
||||||
type noBalanceTestParams struct {
|
type noBalanceTestParams struct {
|
||||||
name string
|
name string
|
||||||
input *requests.RouteInputParams
|
input *requests.RouteInputParams
|
||||||
expectedCandidates []*Path
|
expectedCandidates routes.Route
|
||||||
expectedBest []*Path
|
expectedBest routes.Route
|
||||||
expectedError *errors.ErrorResponse
|
expectedError *errors.ErrorResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2750,14 +2751,14 @@ func getNoBalanceTestParamsList() []noBalanceTestParams {
|
||||||
Code: ErrNotEnoughNativeBalance.Code,
|
Code: ErrNotEnoughNativeBalance.Code,
|
||||||
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, walletCommon.OptimismMainnet),
|
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, walletCommon.OptimismMainnet),
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorTransferName,
|
ProcessorName: pathprocessor.ProcessorTransferName,
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
ToChain: &optimism,
|
ToChain: &optimism,
|
||||||
ApprovalRequired: false,
|
ApprovalRequired: false,
|
||||||
requiredTokenBalance: big.NewInt(testAmount100USDC),
|
RequiredTokenBalance: big.NewInt(testAmount100USDC),
|
||||||
requiredNativeBalance: big.NewInt((testBaseFee + testPriorityFeeLow) * testApprovalGasEstimation),
|
RequiredNativeBalance: big.NewInt((testBaseFee + testPriorityFeeLow) * testApprovalGasEstimation),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2837,7 +2838,7 @@ func getNoBalanceTestParamsList() []noBalanceTestParams {
|
||||||
Code: ErrNotEnoughNativeBalance.Code,
|
Code: ErrNotEnoughNativeBalance.Code,
|
||||||
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, walletCommon.ArbitrumMainnet),
|
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, walletCommon.ArbitrumMainnet),
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2849,8 +2850,8 @@ func getNoBalanceTestParamsList() []noBalanceTestParams {
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
ToChain: &optimism,
|
ToChain: &optimism,
|
||||||
ApprovalRequired: false,
|
ApprovalRequired: false,
|
||||||
requiredTokenBalance: big.NewInt(testAmount100USDC),
|
RequiredTokenBalance: big.NewInt(testAmount100USDC),
|
||||||
requiredNativeBalance: big.NewInt((testBaseFee + testPriorityFeeLow) * testApprovalGasEstimation),
|
RequiredNativeBalance: big.NewInt((testBaseFee + testPriorityFeeLow) * testApprovalGasEstimation),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
|
@ -2891,7 +2892,7 @@ func getNoBalanceTestParamsList() []noBalanceTestParams {
|
||||||
ApprovalL1Fee: testApprovalL1Fee,
|
ApprovalL1Fee: testApprovalL1Fee,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedCandidates: []*Path{
|
expectedCandidates: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &mainnet,
|
FromChain: &mainnet,
|
||||||
|
@ -2903,8 +2904,8 @@ func getNoBalanceTestParamsList() []noBalanceTestParams {
|
||||||
FromChain: &optimism,
|
FromChain: &optimism,
|
||||||
ToChain: &optimism,
|
ToChain: &optimism,
|
||||||
ApprovalRequired: false,
|
ApprovalRequired: false,
|
||||||
requiredTokenBalance: big.NewInt(testAmount100USDC),
|
RequiredTokenBalance: big.NewInt(testAmount100USDC),
|
||||||
requiredNativeBalance: big.NewInt((testBaseFee + testPriorityFeeLow) * testApprovalGasEstimation),
|
RequiredNativeBalance: big.NewInt((testBaseFee + testPriorityFeeLow) * testApprovalGasEstimation),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
|
@ -2913,7 +2914,7 @@ func getNoBalanceTestParamsList() []noBalanceTestParams {
|
||||||
ApprovalRequired: true,
|
ApprovalRequired: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedBest: []*Path{
|
expectedBest: routes.Route{
|
||||||
{
|
{
|
||||||
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
ProcessorName: pathprocessor.ProcessorBridgeHopName,
|
||||||
FromChain: &arbitrum,
|
FromChain: &arbitrum,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package router
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
@ -8,80 +8,10 @@ import (
|
||||||
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Graph []*Node
|
type Route []*Path
|
||||||
|
|
||||||
type Node struct {
|
func FindBestRoute(routes []Route, tokenPrice float64, nativeTokenPrice float64) Route {
|
||||||
Path *Path
|
var best Route
|
||||||
Children Graph
|
|
||||||
}
|
|
||||||
|
|
||||||
func newNode(path *Path) *Node {
|
|
||||||
return &Node{Path: path, Children: make(Graph, 0)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildGraph(AmountIn *big.Int, routes []*Path, level int, sourceChainIDs []uint64) Graph {
|
|
||||||
graph := make(Graph, 0)
|
|
||||||
for _, route := range routes {
|
|
||||||
found := false
|
|
||||||
for _, chainID := range sourceChainIDs {
|
|
||||||
if chainID == route.FromChain.ChainID {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
node := newNode(route)
|
|
||||||
|
|
||||||
newRoutes := make([]*Path, 0)
|
|
||||||
for _, r := range routes {
|
|
||||||
if route.Equal(r) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
newRoutes = append(newRoutes, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
newAmountIn := new(big.Int).Sub(AmountIn, route.AmountIn.ToInt())
|
|
||||||
if newAmountIn.Sign() > 0 {
|
|
||||||
newSourceChainIDs := make([]uint64, len(sourceChainIDs))
|
|
||||||
copy(newSourceChainIDs, sourceChainIDs)
|
|
||||||
newSourceChainIDs = append(newSourceChainIDs, route.FromChain.ChainID)
|
|
||||||
node.Children = buildGraph(newAmountIn, newRoutes, level+1, newSourceChainIDs)
|
|
||||||
|
|
||||||
if len(node.Children) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
graph = append(graph, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n Node) buildAllRoutes() [][]*Path {
|
|
||||||
res := make([][]*Path, 0)
|
|
||||||
|
|
||||||
if len(n.Children) == 0 && n.Path != nil {
|
|
||||||
res = append(res, []*Path{n.Path})
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, node := range n.Children {
|
|
||||||
for _, route := range node.buildAllRoutes() {
|
|
||||||
extendedRoute := route
|
|
||||||
if n.Path != nil {
|
|
||||||
extendedRoute = append([]*Path{n.Path}, route...)
|
|
||||||
}
|
|
||||||
res = append(res, extendedRoute)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func findBest(routes [][]*Path, tokenPrice float64, nativeTokenPrice float64) []*Path {
|
|
||||||
var best []*Path
|
|
||||||
bestCost := big.NewFloat(math.Inf(1))
|
bestCost := big.NewFloat(math.Inf(1))
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
currentCost := big.NewFloat(0)
|
currentCost := big.NewFloat(0)
|
|
@ -0,0 +1,77 @@
|
||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Graph []*Node
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
Path *Path
|
||||||
|
Children Graph
|
||||||
|
}
|
||||||
|
|
||||||
|
func newNode(path *Path) *Node {
|
||||||
|
return &Node{Path: path, Children: make(Graph, 0)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildGraph(AmountIn *big.Int, route Route, level int, sourceChainIDs []uint64) Graph {
|
||||||
|
graph := make(Graph, 0)
|
||||||
|
for _, path := range route {
|
||||||
|
found := false
|
||||||
|
for _, chainID := range sourceChainIDs {
|
||||||
|
if chainID == path.FromChain.ChainID {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
node := newNode(path)
|
||||||
|
|
||||||
|
newRoute := make(Route, 0)
|
||||||
|
for _, p := range route {
|
||||||
|
if path.Equal(p) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newRoute = append(newRoute, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
newAmountIn := new(big.Int).Sub(AmountIn, path.AmountIn.ToInt())
|
||||||
|
if newAmountIn.Sign() > 0 {
|
||||||
|
newSourceChainIDs := make([]uint64, len(sourceChainIDs))
|
||||||
|
copy(newSourceChainIDs, sourceChainIDs)
|
||||||
|
newSourceChainIDs = append(newSourceChainIDs, path.FromChain.ChainID)
|
||||||
|
node.Children = BuildGraph(newAmountIn, newRoute, level+1, newSourceChainIDs)
|
||||||
|
|
||||||
|
if len(node.Children) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graph = append(graph, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Node) BuildAllRoutes() []Route {
|
||||||
|
res := make([]Route, 0)
|
||||||
|
|
||||||
|
if len(n.Children) == 0 && n.Path != nil {
|
||||||
|
res = append(res, Route{n.Path})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, node := range n.Children {
|
||||||
|
for _, route := range node.BuildAllRoutes() {
|
||||||
|
extendedRoute := route
|
||||||
|
if n.Path != nil {
|
||||||
|
extendedRoute = append(Route{n.Path}, route...)
|
||||||
|
}
|
||||||
|
res = append(res, extendedRoute)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package router
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -46,9 +46,9 @@ type Path struct {
|
||||||
|
|
||||||
EstimatedTime fees.TransactionEstimation
|
EstimatedTime fees.TransactionEstimation
|
||||||
|
|
||||||
requiredTokenBalance *big.Int // (in selected token)
|
RequiredTokenBalance *big.Int // (in selected token)
|
||||||
requiredNativeBalance *big.Int // (in ETH WEI)
|
RequiredNativeBalance *big.Int // (in ETH WEI)
|
||||||
subtractFees bool
|
SubtractFees bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Path) Equal(o *Path) bool {
|
func (p *Path) Equal(o *Path) bool {
|
Loading…
Reference in New Issue