Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router Filter Modularisation and Test suite #5177

Merged
merged 17 commits into from
May 28, 2024

Conversation

Samyoul
Copy link
Member

@Samyoul Samyoul commented May 17, 2024

Building on the work of #5159, this PR breaks the filterRoutesV2 function down into its main components. This increases the testability and ability to identify places where the code may break in the future.

My original draft is here See here for details

Summary of Each Function

filterRoutesV2

Filters routes based on network compliance and capacity validation. It first checks if the fromLockedAmount map is empty, returning the routes unmodified if so. Otherwise, it applies network compliance filtering followed by capacity validation filtering.

filterNetworkComplianceV2

Performs the first level of filtering based on network inclusion and exclusion criteria. It initializes inclusion and exclusion maps based on the fromLockedAmount map and then iterates through each route to ensure compliance with these criteria. Only routes that pass the compliance check are included in the filtered routes.

isValidForNetworkComplianceV2

Checks if a given route complies with network inclusion and exclusion criteria. It logs the initial inclusion and exclusion maps, then iterates through each path in the route. If any path's ChainID is in the exclusion map or if any required inclusion ChainID is missing, the route is deemed non-compliant and returns false. Otherwise, it returns true.

setupRouteValidationMapsV2

Initializes maps for network inclusion and exclusion based on the fromLockedAmount map. Chains with zero or negative amounts are marked as excluded, while chains with positive amounts are marked as included.

filterCapacityValidationV2

Performs the second level of filtering based on amount and capacity validation. It iterates through the routes and checks if each route has sufficient capacity to handle the required amount using the hasSufficientCapacityV2 function. Only routes that have sufficient capacity are included in the filtered routes.

hasSufficientCapacityV2

Checks if a route has sufficient capacity to handle the required amount. For each path in the route, it calculates the required amount by subtracting the path's locked amount from the input amount. It then calculates the remaining amount in the route excluding the current path. If the remaining amount is greater than or equal to the required amount, the path is marked as having sufficient capacity. Otherwise, the route is deemed insufficient and returns false.

calculateRestAmountInV2

Calculates the remaining amount in for the route, excluding a specified path. It iterates through the paths in the route, summing up the amounts for all paths except the excluded one, and returns the total remaining amount.

Summary of Test Cases for each tested function

TestSetupRouteValidationMapsV2

This test checks the function setupRouteValidationMapsV2 which initializes maps for network inclusion and exclusion based on locked amounts.

Test Cases:

  1. Mixed zero and non-zero amounts: Validates both zero and non-zero amounts are correctly mapped to included and excluded.
  2. All non-zero amounts: Ensures all non-zero amounts are correctly marked as included.
  3. All zero amounts: Ensures all zero amounts are correctly marked as excluded.
  4. Single non-zero and zero amount: Verifies a single non-zero amount and a single zero amount are correctly marked as included and excluded, respectively.
  5. Empty map: Checks that an empty map results in both included and excluded maps being empty.

TestCalculateRestAmountInV2

This test verifies the function calculateRestAmountInV2 which calculates the remaining amount in for the route excluding the specified path.

Test Cases:

  1. Exclude path1: Excludes the first path in a three-path route.
  2. Exclude path2: Excludes the second path in a three-path route.
  3. Exclude path3: Excludes the third path in a three-path route.
  4. Single path, exclude that path: Tests exclusion when only one path is present.
  5. Empty route: Verifies the result for an empty route.
  6. Empty route, with nil exclude: Tests with an empty route and a nil exclude path.

TestIsValidForNetworkComplianceV2

This test validates the function isValidForNetworkComplianceV2 which checks if a route complies with network inclusion/exclusion criteria.

Test Cases:

  1. Route with all included chain IDs: Checks if all included chain IDs in the route return true.
  2. Route with fromExcluded only: Tests compliance with only excluded chain IDs.
  3. Route without excluded chain IDs: Ensures compliance when no excluded chain IDs are present.
  4. Route with an excluded chain ID: Tests failure when an excluded chain ID is present.
  5. Route missing one included chain ID: Ensures failure when one included chain ID is missing.
  6. Route with no fromIncluded or fromExcluded: Checks if an empty inclusion/exclusion map returns true.
  7. Empty route: Verifies failure for an empty route.

TestHasSufficientCapacityV2

This test validates the function hasSufficientCapacityV2 which checks if a route has sufficient capacity to handle the required amount.

Test Cases:

  1. All paths meet required amount: Verifies paths meeting the required amount.
  2. No fromLockedAmount: Checks if sufficient capacity is returned true when no locked amounts are provided.
  3. Single path meets required amount: Validates a single path meeting the required amount.
  4. Single path does not meet required amount: Ensures failure when a single path does not meet the required amount.
  5. Path meets required amount with excess: Verifies paths meeting the required amount with excess capacity.
  6. Empty route: Checks for true when route is empty.
  7. Routes with duplicate chain IDs: Ensures behavior with duplicate chain IDs in a route.
  8. Partial locked amounts: Tests behavior with partially locked amounts.
  9. Mixed networks with sufficient capacity: Validates mixed network paths meeting the required amount.
  10. Mixed networks with insufficient capacity: Ensures failure with mixed network paths lacking sufficient capacity.

TestFilterNetworkComplianceV2

This test validates the function filterNetworkComplianceV2 which performs the first level of filtering based on network inclusion/exclusion criteria.

Test Cases:

  1. Mixed routes with valid and invalid paths: Verifies filtering with mixed valid and invalid paths.
  2. All valid routes: Checks all valid routes are correctly returned.
  3. All invalid routes: Ensures all invalid routes are filtered out.
  4. Empty routes: Validates behavior with no routes provided.
  5. No locked amounts: Verifies behavior when no locked amounts are provided.
  6. Single route with mixed valid and invalid paths: Ensures filtering with a single route containing both valid and invalid paths.
  7. Routes with duplicate chain IDs: Tests behavior with routes containing duplicate chain IDs.
  8. Minimum and maximum chain IDs: Validates behavior with the smallest and largest chain IDs.
  9. Large number of routes: Tests filtering with a large number of routes.
  10. Routes with missing data: Ensures routes with missing data are filtered out.
  11. Consistency check: Verifies filtering consistency.
  12. Routes without excluded chain IDs, missing included path: Checks routes missing one included chain ID.
  13. Routes with an excluded chain ID: Ensures routes with an excluded chain ID are filtered out.
  14. Routes with all included chain IDs: Verifies routes with all included chain IDs.
  15. Routes missing one included chain ID: Checks routes missing one included chain ID.
  16. Routes with no fromLockedAmount: Validates behavior with no locked amounts provided.
  17. Routes with fromExcluded only: Tests behavior with only excluded paths.
  18. Routes with all excluded chain IDs: Ensures routes with all excluded chain IDs are filtered out.

TestFilterCapacityValidationV2

This test checks the function filterCapacityValidationV2 which performs the second level of filtering based on amount and capacity validation.

Test Cases:

  1. Sufficient capacity with multiple paths: Verifies multiple paths meeting required amount.
  2. Insufficient capacity: Ensures paths with insufficient capacity are filtered out.
  3. Exact capacity match: Validates paths exactly matching required capacity.
  4. No locked amounts: Checks behavior when no locked amounts are provided.
  5. Single route with sufficient capacity: Tests a single route with sufficient capacity.
  6. Single route with insufficient capacity: Ensures a single route with insufficient capacity is filtered out.
  7. Empty routes: Verifies behavior with empty routes.
  8. Routes with duplicate chain IDs: Ensures behavior with routes containing duplicate chain IDs.
  9. Partial locked amounts: Tests behavior with partially locked amounts.
  10. Mixed networks with sufficient capacity: Verifies mixed network paths meeting the required amount.
  11. Mixed networks with insufficient capacity: Ensures mixed network paths lacking sufficient capacity are filtered out.

TestFilterRoutesV2

This test validates the overall filterRoutesV2 function which filters routes based on network compliance and capacity validation.

Test Cases:

  1. Empty fromLockedAmount: Verifies behavior when no locked amounts are provided.
  2. All paths appear in fromLockedAmount but not within a single route: Checks paths appearing in locked amounts but not in a single route.
  3. Mixed valid and invalid routes: Verifies mixed valid and invalid routes are correctly filtered.
  4. All invalid routes: Ensures all invalid routes are filtered out.
  5. Single valid route: Validates a single valid route.
  6. Route with mixed valid and invalid paths: Ensures a route with mixed valid and invalid paths is correctly filtered.

🚨 Danger Zone! 🚨

There are 3 test cases in this PR that I have questions about:

When testing hasSufficientCapacityV2 why does the current test case return true when it should be false?

// TODO: Find out what the expected behaviour for this case should be
// I expect false but the test returns true
{
	name:             "A path does not meet required amount",
	route:            []*PathV2{path1, path2, path3},
	amountIn:         big.NewInt(600),
	fromLockedAmount: map[uint64]*hexutil.Big{1: &amount1, 2: &amount2, 4: &amount4},
	expected:         false,
},

When testing filterCapacityValidationV2 with a single route with sufficient capacity, I expect this test to return a route composed of {From: network1, AmountIn: (*hexutil.Big)(big.NewInt(200))}, but the logic gives an empty route.

This seems incorrect to me. But why?

{
	// TODO Is the behaviour of this test correct? It looks wrong
	name: "Single route with sufficient capacity",
	routes: [][]*PathV2{
		{
			{From: network1, AmountIn: (*hexutil.Big)(big.NewInt(200))},
		},
	},
	amountIn: big.NewInt(150),
	fromLockedAmount: map[uint64]*hexutil.Big{
		1: (*hexutil.Big)(big.NewInt(50)),
	},
	expectedRoutes: [][]*PathV2{},
},

When testing filterCapacityValidationV2 we should probably receive an error, but also in this case the criteria seems to be met. But the test case expects an empty route... This seems wrong to me.

{
	// TODO this seems wrong also. Should this test case work?
	name: "Routes with duplicate chain IDs",
	routes: [][]*PathV2{
		{
			{From: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
			{From: network1, AmountIn: (*hexutil.Big)(big.NewInt(100))},
		},
	},
	amountIn: big.NewInt(150),
	fromLockedAmount: map[uint64]*hexutil.Big{
		1: (*hexutil.Big)(big.NewInt(50)),
	},
	expectedRoutes: [][]*PathV2{},
},

@Samyoul Samyoul self-assigned this May 17, 2024
@status-im-auto
Copy link
Member

status-im-auto commented May 17, 2024

Jenkins Builds

Click to see older builds (72)
Commit #️⃣ Finished (UTC) Duration Platform Result
✖️ 6339c8c #1 2024-05-17 12:19:35 ~1 min tests 📄log
✔️ 6339c8c #1 2024-05-17 12:22:48 ~4 min linux 📦zip
✔️ 6339c8c #1 2024-05-17 12:24:16 ~6 min android 📦aar
✖️ ba3e139 #2 2024-05-17 12:34:05 ~57 sec tests 📄log
✔️ ba3e139 #2 2024-05-17 12:34:57 ~1 min android 📦aar
✔️ ba3e139 #2 2024-05-17 12:35:26 ~2 min linux 📦zip
✔️ ba3e139 #2 2024-05-17 12:37:49 ~4 min ios 📦zip
✖️ 5f66763 #3 2024-05-17 13:40:26 ~58 sec tests 📄log
✔️ 5f66763 #3 2024-05-17 13:41:05 ~1 min android 📦aar
✔️ 5f66763 #3 2024-05-17 13:41:35 ~2 min linux 📦zip
✖️ 4b30d67 #4 2024-05-17 14:00:45 ~1 min tests 📄log
✔️ 4b30d67 #4 2024-05-17 14:01:28 ~1 min android 📦aar
✔️ 4b30d67 #4 2024-05-17 14:03:44 ~4 min linux 📦zip
✖️ b72ea16 #5 2024-05-17 16:20:20 ~1 min tests 📄log
✖️ b72ea16 #6 2024-05-17 22:01:58 ~1 min tests 📄log
✔️ b72ea16 #5 2024-05-17 16:21:14 ~1 min android 📦aar
✔️ b72ea16 #5 2024-05-17 16:23:47 ~4 min linux 📦zip
✔️ b72ea16 #6 2024-05-17 22:02:32 ~1 min android 📦aar
✔️ b72ea16 #6 2024-05-17 22:03:16 ~2 min linux 📦zip
✔️ b72ea16 #6 2024-05-17 22:04:25 ~3 min ios 📦zip
✖️ ab78ecb #7 2024-05-20 10:29:19 ~56 sec tests 📄log
✖️ ab78ecb #9 2024-05-20 14:25:04 ~57 sec tests 📄log
✔️ ab78ecb #7 2024-05-20 10:31:04 ~2 min linux 📦zip
✔️ ab78ecb #7 2024-05-20 10:31:17 ~2 min android 📦aar
✔️ ab78ecb #7 2024-05-20 10:32:16 ~3 min ios 📦zip
✔️ ab78ecb #9 2024-05-20 14:25:55 ~1 min android 📦aar
✔️ ab78ecb #9 2024-05-20 14:26:14 ~2 min linux 📦zip
✔️ ab78ecb #9 2024-05-20 14:27:40 ~3 min ios 📦zip
f6c6a86 #8 2024-05-20 14:09:58 ~30 sec android 📄log
f6c6a86 #8 2024-05-20 14:10:00 ~32 sec ios 📄log
f6c6a86 #8 2024-05-20 14:10:07 ~37 sec linux 📄log
✖️ f6c6a86 #8 2024-05-20 14:10:24 ~57 sec tests 📄log
✖️ 2c8af7c #10 2024-05-20 23:09:24 ~1 min tests 📄log
✔️ 2c8af7c #10 2024-05-20 23:10:53 ~2 min linux 📦zip
✔️ 2c8af7c #10 2024-05-20 23:11:01 ~2 min android 📦aar
✔️ 2c8af7c #10 2024-05-20 23:12:00 ~3 min ios 📦zip
✖️ 5fc27ff #11 2024-05-22 09:17:57 ~58 sec tests 📄log
✔️ 5fc27ff #11 2024-05-22 09:19:05 ~2 min android 📦aar
✔️ 5fc27ff #11 2024-05-22 09:19:28 ~2 min linux 📦zip
✔️ 5fc27ff #11 2024-05-22 09:19:59 ~3 min ios 📦zip
✖️ 07fec99 #12 2024-05-24 10:21:36 ~1 min tests 📄log
✔️ 07fec99 #12 2024-05-24 10:22:56 ~2 min linux 📦zip
✔️ 07fec99 #12 2024-05-24 10:23:55 ~3 min ios 📦zip
✔️ 07fec99 #12 2024-05-24 10:25:59 ~5 min android 📦aar
✖️ e5d1670 #13 2024-05-24 12:15:10 ~2 min tests 📄log
✔️ e5d1670 #13 2024-05-24 12:15:41 ~2 min android 📦aar
✔️ e5d1670 #13 2024-05-24 12:17:11 ~4 min ios 📦zip
✔️ e5d1670 #13 2024-05-24 12:17:33 ~4 min linux 📦zip
✖️ 9924093 #14 2024-05-24 12:33:30 ~1 min tests 📄log
✔️ 9924093 #14 2024-05-24 12:34:46 ~2 min linux 📦zip
✔️ 9924093 #14 2024-05-24 12:35:55 ~3 min ios 📦zip
✔️ 9924093 #14 2024-05-24 12:38:10 ~5 min android 📦aar
✖️ 8bf1abd #15 2024-05-24 13:07:43 ~57 sec tests 📄log
✔️ 8bf1abd #15 2024-05-24 13:08:27 ~1 min android 📦aar
✔️ 8bf1abd #15 2024-05-24 13:09:27 ~2 min linux 📦zip
✔️ 8bf1abd #15 2024-05-24 13:09:38 ~2 min ios 📦zip
✖️ e1ac1b8 #16 2024-05-24 14:07:25 ~59 sec tests 📄log
✔️ e1ac1b8 #16 2024-05-24 14:08:59 ~2 min linux 📦zip
✔️ e1ac1b8 #16 2024-05-24 14:09:10 ~2 min android 📦aar
✔️ e1ac1b8 #16 2024-05-24 14:09:54 ~3 min ios 📦zip
✖️ 75c5ac1 #17 2024-05-24 14:19:12 ~2 min tests 📄log
✔️ 75c5ac1 #17 2024-05-24 14:19:44 ~3 min android 📦aar
✔️ 75c5ac1 #17 2024-05-24 14:20:16 ~3 min ios 📦zip
✔️ 75c5ac1 #17 2024-05-24 14:20:47 ~4 min linux 📦zip
✖️ 2a7f667 #18 2024-05-28 10:51:19 ~1 min tests 📄log
✔️ 2a7f667 #18 2024-05-28 10:52:32 ~2 min linux 📦zip
✔️ 2a7f667 #18 2024-05-28 10:53:13 ~2 min android 📦aar
✔️ 2a7f667 #18 2024-05-28 10:54:11 ~3 min ios 📦zip
✖️ 3518511 #19 2024-05-28 19:37:29 ~1 min tests 📄log
✔️ 3518511 #19 2024-05-28 19:39:12 ~2 min linux 📦zip
✔️ 3518511 #19 2024-05-28 19:39:22 ~2 min android 📦aar
✔️ 3518511 #19 2024-05-28 19:40:07 ~3 min ios 📦zip
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ e01dab6 #20 2024-05-28 19:47:40 ~1 min android 📦aar
✔️ e01dab6 #20 2024-05-28 19:48:14 ~2 min linux 📦zip
✔️ e01dab6 #20 2024-05-28 19:48:56 ~3 min ios 📦zip
✔️ e01dab6 #20 2024-05-28 20:30:31 ~44 min tests 📄log

@Samyoul
Copy link
Member Author

Samyoul commented May 17, 2024

filterNetworkComplianceV2

Items to check:

  • Mixed routes with valid and invalid paths
  • All valid routes
  • All invalid routes
  • Empty routes
  • No locked amounts
  • Single route with mixed valid and invalid paths
  • Routes with duplicate chain IDs

@Samyoul
Copy link
Member Author

Samyoul commented May 17, 2024

filterCapacityValidationV2

Combinations to check

  • Sufficient capacity with multiple paths
  • Insufficient capacity
  • Exact capacity match
  • No locked amounts
  • Single route with sufficient capacity
  • Single route with insufficient capacity
  • Empty routes
  • Routes with duplicate chain IDs
  • Partial locked amounts
  • Mixed networks with sufficient capacity
  • Mixed networks with insufficient capacity

@Samyoul
Copy link
Member Author

Samyoul commented May 17, 2024

I thought of a few more conditions for filterNetworkComplianceV2

  • Minimum and maximum chain IDs
    • Basically fuzzing to check that extremes of chain IDs are supported or don't cause issues
  • Large number of routes
  • Routes with missing data

@Samyoul
Copy link
Member Author

Samyoul commented May 17, 2024

Interesting fails on test runs. See here for more details https://github.com/status-im/samyoul-notes/blob/master/attachments/2024-05/filter_test_results.md

@Samyoul
Copy link
Member Author

Samyoul commented May 17, 2024

State of tests:

1. TestSetupRouteValidationMapsV2: ✅ All Passing

This test case ensures that the setupRouteValidationMapsV2 function correctly creates the fromIncluded and fromExcluded maps based on the fromLockedAmount input.

  • Test cases:
    • Mixed locked amounts: ✅ Passing
      • Tests with mixed amounts of locked and unlocked values.
    • All amounts locked: ✅ Passing
      • Tests with all values locked.
    • No amounts locked: ✅ Passing
      • Tests with no locked values.

2. TestCalculateTotalRestAmountV2: ✅ All Passing

This test case ensures that the calculateTotalRestAmountV2 function correctly calculates the total amount from the AmountIn values in a route.

  • Test cases:
    • Multiple paths with varying amounts: ✅ Passing
      • Tests with multiple paths having different amounts.
    • Single path: ✅ Passing
      • Tests with a single path.
    • No paths: ✅ Passing
      • Tests with no paths.

3. TestIsValidForNetworkComplianceV2: ✅ All Passing

This test case verifies that the isValidForNetworkComplianceV2 function correctly validates routes based on fromIncluded and fromExcluded maps.

  • Test cases:
    • Valid route with required chain IDs included: ✅ Passing
      • Tests with a route that includes all required chain IDs.
    • Invalid route with excluded chain ID: ✅ Passing
      • Tests with a route that includes an excluded chain ID.
    • Route missing required chain ID: ✅ Passing
      • Tests with a route that is missing a required chain ID.
    • Valid route with multiple included chain IDs: ✅ Passing
      • Tests with a route that includes multiple required chain IDs.
    • Invalid route missing one of the required chain IDs: ✅ Passing
      • Tests with a route missing one of the required chain IDs.

4. TestHasSufficientCapacityV2: ❌ Failure, 🚧 Tests not completed.

This test case ensures that the hasSufficientCapacityV2 function correctly checks if the route has sufficient capacity based on fromLockedAmount and amountIn.

  • Test cases:
    • Sufficient capacity with multiple paths: ✅ Passing
      • Tests with routes having sufficient capacity.
    • Insufficient capacity: ✅ Passing
      • Tests with routes having insufficient capacity.
    • Exact capacity match: ❌ Failing
      • Tests with routes having exactly matching capacity.
    • No locked amounts: 🚧 To Implement
      • Tests with routes and no locked amounts.
    • Single route with sufficient capacity: 🚧 To Implement
      • Tests with a single route having sufficient capacity.
    • Single route with insufficient capacity: 🚧 To Implement
      • Tests with a single route having insufficient capacity.
    • Empty routes: 🚧 To Implement
      • Tests with no routes.
    • Routes with duplicate chain IDs: 🚧 To Implement
      • Tests with routes having duplicate chain IDs.
    • Partial locked amounts: 🚧 To Implement
      • Tests with routes having partial locked amounts.
    • Mixed networks with sufficient capacity: 🚧 To Implement
      • Tests with mixed networks having sufficient capacity.
    • Mixed networks with insufficient capacity: 🚧 To Implement
      • Tests with mixed networks having insufficient capacity.

5. TestFilterNetworkComplianceV2: ❌ Failure

This test case ensures that the filterNetworkComplianceV2 function correctly filters routes based on network compliance.

  • Test cases:
    • Mixed routes with valid and invalid paths: ❌ Failing
      • Tests with mixed valid and invalid routes.
    • All valid routes: ✅ Passing
      • Tests with all valid routes.
    • All invalid routes: ❌ Failing
      • Tests with all invalid routes.
    • Empty routes: ❌ Failing
      • Tests with no routes.
    • No locked amounts: ✅ Passing
      • Tests with routes and no locked amounts.
    • Single route with mixed valid and invalid paths: ❌ Failing
      • Tests with a single route having mixed valid and invalid paths.
    • Routes with duplicate chain IDs: ✅ Passing
      • Tests with routes having duplicate chain IDs.
    • Minimum and maximum chain IDs: ✅ Passing
      • Tests with routes having minimum and maximum chain IDs.
    • Large number of routes: ❌ Failing
      • Tests with a large number of routes.
    • Routes with missing data: ❌ Failing (A lack of validation causes a nil pointer reference panic.)
      • Tests with routes having missing data.
    • Consistency check: ✅ Passing
      • Tests for consistent results with the same input.

6. TestFilterCapacityValidationV2: ❌ Failure

This test case ensures that the filterCapacityValidationV2 function correctly filters routes based on capacity validation.

  • Test cases:
    • Sufficient capacity with multiple paths: ❌ Failing
      • Tests with routes having sufficient capacity.
    • Insufficient capacity: ❌ Failing
      • Tests with routes having insufficient capacity.
    • Exact capacity match: ❌ Failing
      • Tests with routes having exactly matching capacity.
    • No locked amounts: ✅ Passing
      • Tests with routes and no locked amounts.
    • Single route with sufficient capacity: ❌ Failing
      • Tests with a single route having sufficient capacity.
    • Single route with insufficient capacity: ❌ Failing
      • Tests with a single route having insufficient capacity.
    • Empty routes: ❌ Failing
      • Tests with no routes.
    • Routes with duplicate chain IDs: ❌ Failing
      • Tests with routes having duplicate chain IDs.
    • Partial locked amounts: ❌ Failing
      • Tests with routes having partial locked amounts.
    • Mixed networks with sufficient capacity: ✅ Passing
      • Tests with mixed networks having sufficient capacity.
    • Mixed networks with insufficient capacity: ❌ Failing
      • Tests with mixed networks having insufficient capacity.

7. TestFilterRoutesV2: ❌ Failure

This test case ensures that the filterRoutesV2 function correctly filters routes based on both network compliance and capacity validation.

  • Test cases:
    • Test with specific routes and locked amounts: ❌ Failing
      • Tests with a predefined set of routes and locked amounts.

@Samyoul
Copy link
Member Author

Samyoul commented May 17, 2024

Ok it seems that many of these fails are a result of overly precise comparisons expecting even the memory addresses to be identical. I'll tweak those tests to compare values rather than expecting 100% IDENTICAL values.

@saledjenic saledjenic force-pushed the router-improvements-general branch from 5deb408 to f7bc3d4 Compare May 17, 2024 20:44
Base automatically changed from router-improvements-general to develop May 17, 2024 22:00
@saledjenic
Copy link
Contributor

@Samyoul could you rebase it, please?

Copy link
Contributor

@saledjenic saledjenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Samyoul nice modularisation, thanks, I left a few questions.

}

// setupRouteValidationMapsV2 initializes maps for network inclusion and exclusion based on locked amounts.
func setupRouteValidationMapsV2(fromLockedAmount map[uint64]*hexutil.Big) (map[uint64]bool, map[uint64]bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should check the validity of fromLockedAmount at the moment when SuggestedRoutesV2 is called.

We should check that are all entries are positive, I guess that if the user deliberately doesn't want to send any amount from a certain chain there are two options to do that from the UI side:

  • disable that chain (which means we should add that chain to DisabledFromChainIDsarray)
  • or set 0 value for locked amount on that chain

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea. We need some better validation generally.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saledjenic I've created an issue for this #5227

fromExcluded := make(map[uint64]bool)

for chainID, amount := range fromLockedAmount {
if amount.ToInt().Cmp(zero) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until we add the check for fromLockedAmount validation, we should check if amount.ToInt().Cmp(zero) <= 0 {, right?

for _, path := range route {
if amount, ok := fromLockedAmount[path.From.ChainID]; ok {
requiredAmountIn := new(big.Int).Sub(amountIn, amount.ToInt())
if totalRestAmount.Cmp(requiredAmountIn) < 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the logic need to be like this?

if amount, ok := fromLockedAmount[path.From.ChainID]; ok {
	requiredAmountIn := new(big.Int).Sub(amountIn, amount.ToInt())
	totalRestAmount.Sub(amountIn, amount.ToInt())    // <===
	if totalRestAmount.Cmp(requiredAmountIn) <= 0 {
		return false
	}
	path.AmountIn = amount
	path.AmountInLocked = true
	totalRestAmount.Sub(totalRestAmount, amount.ToInt())
}

@Samyoul
Copy link
Member Author

Samyoul commented May 20, 2024

Hey @saledjenic thank you for your review. I definitely need to review the logic of the modular functions. I was just trying to build out the modular functionality and then add the tests to cover all the test cases I could think of. I think I may have spotted some cases that have revealed some areas of concern, but after I've checked the logic I can confirm this.

I'll ping you when I'm ready for you to look over this PR again.

@Samyoul
Copy link
Member Author

Samyoul commented May 20, 2024

Hmmm, having some rebase issues:

HEAD is now at 292070a85 feat(spiff-workflow)_: support metrics endpoint
From github.com:status-im/status-go
 * branch                develop    -> FETCH_HEAD
Already up to date.
Switched to branch 'develop'
Your branch is up to date with 'origin/develop'.
First, rewinding head to replay your work on top of it...
fatal: Dirty index: cannot apply patches (dirty: .dockerignore config/status-chain-genesis.json services/web3provider/service.go services/web3provider/signature.go)

git stash doesn't help, probably because the dirty files come from the rebase

% git stash
error: Entry '.dockerignore' not uptodate. Cannot merge.
Cannot save the current worktree state

git add -A and git rebase --continue gives the following problems

status-go % git add -A
status-go % git rebase --continue
fatal: cannot resume: .git/rebase-apply/final-commit does not exist.

@Samyoul
Copy link
Member Author

Samyoul commented May 20, 2024

Oh boy I've got some serious problems:

 % git rebase --skip
Assertion failed: (!is_null_oid(&state->orig_commit)), function am_skip, file builtin/am.c, line 1992.
error: am died of signal 6

@saledjenic saledjenic force-pushed the router-filter-modularisation branch from b72ea16 to ab78ecb Compare May 20, 2024 10:28
@Samyoul
Copy link
Member Author

Samyoul commented May 20, 2024

Ok I've got another issue:

 git status                                                               
On branch router-filter-modularisation
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    shell.nix

So git says that shell.nix is deleted .... But it isn't, see here:

status-go % cat shell.nix
# for passing build optionsm see nix/README
# TODO complet nix/README
{ config ? { } }:

let
  main = import ./nix { inherit config; };
in
  # use the default shell when calling nix-shell without arguments
  main.shells.default

Also with ls

status-go % ls -a
.                       CONTRIBUTING.md         circuitbreaker          ipfs                    scripts
..                      LICENSE.md              cmd                     logutils                server
.DS_Store               MAILSERVER.md           common                  mailserver              services
.codeclimate.yml        Makefile                config                  metrics                 shell.nix
.dependabot             README.md               connection              mobile                  signal
.dockerignore           RELEASING.md            contracts               multiaccounts           sqlite
.ethereumtest           VERSION                 db                      nix                     static
.git                    WAKU.md                 default.nix             node                    t
.github                 _assets                 deprecation             nodecfg                 telemetry
.gitignore              _docs                   discovery               notifier                timesource
.golangci.yml           _examples               eth-node                params                  transactions
.idea                   abi-spec                exchanges               peers                   vendor
.nix-gcroots            account                 exportlogs              postgres                waku
.travis.yml             api                     extkeys                 profiling               wakuv2
.vscode                 appdatabase             go.mod                  protocol                walletdatabase
BOOTNODE.md             appmetrics              go.sum                  rpc
CMakeLists.txt          build                   images                  rtt
s

@Samyoul
Copy link
Member Author

Samyoul commented May 20, 2024

Let's try git restore:

status-go % git restore --staged shell.nix                                            
status-go % git status                    
On branch router-filter-modularisation
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    shell.nix

Ok, what about git add:

status-go % git add shell.nix
status-go % git status
On branch router-filter-modularisation
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    shell.nix

Ok, let's try actually deleting it:

status-go % rm shell.nix
status-go % cat shell.nix                 
cat: shell.nix: No such file or directory

Let's commit that change:

status-go % git commit -S -a -m "Deleting shell.nix for some reason"                                       
[router-filter-modularisation f7bb4ef6f] Deleting shell.nix for some reason
 2 files changed, 109 deletions(-)
 delete mode 100644 shell.nix
 delete mode 100644 telemetry/client.go
status-go % git status
On branch router-filter-modularisation
nothing to commit, working tree clean

delete mode 100644 telemetry/client.go <--- That is weird
Moving on check the log:

status-go % git log
commit f7bb4ef6f6575ef2f26ceffb557a6648aba7f169 (HEAD -> router-filter-modularisation)
Author: Samuel Hawksby-Robinson <[email protected]>
Date:   Mon May 20 11:54:37 2024 +0100

    Deleting shell.nix for some reason

commit b72ea163880fdf90349320d8e02429ddf18a4e69 (origin/router-filter-modularisation)

Reset the branch to the previous commit:

status-go % git reset b72ea163880fdf90349320d8e02429ddf18a4e69 --hard
HEAD is now at b72ea1638 Added much better coverage for testing for filterNetworkComplianceV2

Now checking it is all back to normal.

status-go % git status
On branch router-filter-modularisation
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    shell.nix

😱 !!!

@Samyoul
Copy link
Member Author

Samyoul commented May 20, 2024

My IDE's GUI git tool also reports the file as missing while at the same time showing that the file is present.

Screenshot 2024-05-20 at 12 03 05

One thing that I notice is that the file name is grey, meaning that the file is being .gitignored from somewhere. But the file only has one reference to .nix and no reference to shell:

# Nix
/.nix-gcroots/

Is some local setting ignoring it?

@Samyoul Samyoul force-pushed the router-filter-modularisation branch from ab78ecb to f6c6a86 Compare May 20, 2024 14:09
@saledjenic saledjenic force-pushed the router-filter-modularisation branch from f6c6a86 to ab78ecb Compare May 20, 2024 14:23
@Samyoul Samyoul force-pushed the router-filter-modularisation branch from ab78ecb to 2c8af7c Compare May 20, 2024 23:07
@Samyoul Samyoul changed the title Router Filter Modularisation Router Filter Modularisation and Test suite May 24, 2024
@Samyoul Samyoul marked this pull request as ready for review May 24, 2024 10:29
@Samyoul
Copy link
Member Author

Samyoul commented May 24, 2024

TestSetupRouteValidationMapsV2

This test checks the function setupRouteValidationMapsV2 which initializes maps for network inclusion and exclusion based on locked amounts.

Test Cases:

  1. Mixed zero and non-zero amounts: Validates both zero and non-zero amounts are correctly mapped to included and excluded.
  2. All non-zero amounts: Ensures all non-zero amounts are correctly marked as included.
  3. All zero amounts: Ensures all zero amounts are correctly marked as excluded.
  4. Single non-zero and zero amount: Verifies a single non-zero amount and a single zero amount are correctly marked as included and excluded, respectively.
  5. Empty map: Checks that an empty map results in both included and excluded maps being empty.

TestCalculateRestAmountInV2

This test verifies the function calculateRestAmountInV2 which calculates the remaining amount in for the route excluding the specified path.

Test Cases:

  1. Exclude path1: Excludes the first path in a three-path route.
  2. Exclude path2: Excludes the second path in a three-path route.
  3. Exclude path3: Excludes the third path in a three-path route.
  4. Single path, exclude that path: Tests exclusion when only one path is present.
  5. Empty route: Verifies the result for an empty route.
  6. Empty route, with nil exclude: Tests with an empty route and a nil exclude path.

TestIsValidForNetworkComplianceV2

This test validates the function isValidForNetworkComplianceV2 which checks if a route complies with network inclusion/exclusion criteria.

Test Cases:

  1. Route with all included chain IDs: Checks if all included chain IDs in the route return true.
  2. Route with fromExcluded only: Tests compliance with only excluded chain IDs.
  3. Route without excluded chain IDs: Ensures compliance when no excluded chain IDs are present.
  4. Route with an excluded chain ID: Tests failure when an excluded chain ID is present.
  5. Route missing one included chain ID: Ensures failure when one included chain ID is missing.
  6. Route with no fromIncluded or fromExcluded: Checks if an empty inclusion/exclusion map returns true.
  7. Empty route: Verifies failure for an empty route.

TestHasSufficientCapacityV2

This test validates the function hasSufficientCapacityV2 which checks if a route has sufficient capacity to handle the required amount.

Test Cases:

  1. All paths meet required amount: Verifies paths meeting the required amount.
  2. No fromLockedAmount: Checks if sufficient capacity is returned true when no locked amounts are provided.
  3. Single path meets required amount: Validates a single path meeting the required amount.
  4. Single path does not meet required amount: Ensures failure when a single path does not meet the required amount.
  5. Path meets required amount with excess: Verifies paths meeting the required amount with excess capacity.
  6. Empty route: Checks for true when route is empty.
  7. Routes with duplicate chain IDs: Ensures behavior with duplicate chain IDs in a route.
  8. Partial locked amounts: Tests behavior with partially locked amounts.
  9. Mixed networks with sufficient capacity: Validates mixed network paths meeting the required amount.
  10. Mixed networks with insufficient capacity: Ensures failure with mixed network paths lacking sufficient capacity.

TestFilterNetworkComplianceV2

This test validates the function filterNetworkComplianceV2 which performs the first level of filtering based on network inclusion/exclusion criteria.

Test Cases:

  1. Mixed routes with valid and invalid paths: Verifies filtering with mixed valid and invalid paths.
  2. All valid routes: Checks all valid routes are correctly returned.
  3. All invalid routes: Ensures all invalid routes are filtered out.
  4. Empty routes: Validates behavior with no routes provided.
  5. No locked amounts: Verifies behavior when no locked amounts are provided.
  6. Single route with mixed valid and invalid paths: Ensures filtering with a single route containing both valid and invalid paths.
  7. Routes with duplicate chain IDs: Tests behavior with routes containing duplicate chain IDs.
  8. Minimum and maximum chain IDs: Validates behavior with the smallest and largest chain IDs.
  9. Large number of routes: Tests filtering with a large number of routes.
  10. Routes with missing data: Ensures routes with missing data are filtered out.
  11. Consistency check: Verifies filtering consistency.
  12. Routes without excluded chain IDs, missing included path: Checks routes missing one included chain ID.
  13. Routes with an excluded chain ID: Ensures routes with an excluded chain ID are filtered out.
  14. Routes with all included chain IDs: Verifies routes with all included chain IDs.
  15. Routes missing one included chain ID: Checks routes missing one included chain ID.
  16. Routes with no fromLockedAmount: Validates behavior with no locked amounts provided.
  17. Routes with fromExcluded only: Tests behavior with only excluded paths.
  18. Routes with all excluded chain IDs: Ensures routes with all excluded chain IDs are filtered out.

TestFilterCapacityValidationV2

This test checks the function filterCapacityValidationV2 which performs the second level of filtering based on amount and capacity validation.

Test Cases:

  1. Sufficient capacity with multiple paths: Verifies multiple paths meeting required amount.
  2. Insufficient capacity: Ensures paths with insufficient capacity are filtered out.
  3. Exact capacity match: Validates paths exactly matching required capacity.
  4. No locked amounts: Checks behavior when no locked amounts are provided.
  5. Single route with sufficient capacity: Tests a single route with sufficient capacity.
  6. Single route with insufficient capacity: Ensures a single route with insufficient capacity is filtered out.
  7. Empty routes: Verifies behavior with empty routes.
  8. Routes with duplicate chain IDs: Ensures behavior with routes containing duplicate chain IDs.
  9. Partial locked amounts: Tests behavior with partially locked amounts.
  10. Mixed networks with sufficient capacity: Verifies mixed network paths meeting the required amount.
  11. Mixed networks with insufficient capacity: Ensures mixed network paths lacking sufficient capacity are filtered out.

TestFilterRoutesV2

This test validates the overall filterRoutesV2 function which filters routes based on network compliance and capacity validation.

Test Cases:

  1. Empty fromLockedAmount: Verifies behavior when no locked amounts are provided.
  2. All paths appear in fromLockedAmount but not within a single route: Checks paths appearing in locked amounts but not in a single route.
  3. Mixed valid and invalid routes: Verifies mixed valid and invalid routes are correctly filtered.
  4. All invalid routes: Ensures all invalid routes are filtered out.
  5. Single valid route: Validates a single valid route.
  6. Route with mixed valid and invalid paths: Ensures a route with mixed valid and invalid paths is correctly filtered.

@Samyoul
Copy link
Member Author

Samyoul commented May 28, 2024

Screenshot 2024-05-28 at 11 56 22 Ugh!

Looks like I need to rename all 17 of my commits so far.

Copy link
Contributor

@IvanBelyakoff IvanBelyakoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, Samuel. It is great that you created the issues to track the progress of the concerns that are out of scope of this PR.

@saledjenic
Copy link
Contributor

Danger zone - addressing concerns

Danger 1:

When testing hasSufficientCapacityV2 why does the current test case return true when it should be false?

As you already said, this issues will fix that #5244

Danger 2:

When testing filterCapacityValidationV2 with a single route with sufficient capacity, I expect this test to return a route composed of {From: network1, AmountIn: (*hexutil.Big)(big.NewInt(200))}, but the logic gives an empty route.
This seems incorrect to me. But why?

For this one, the input parameters are wrong as I see.
A very important thing that we need to clarify is terminology/constraints:

  • PathV2 - represents a single tx that can be made, except if an approval is needed for that transaction, then it represents 2 transactions where the first one that needs to be made is an approval tx.
  • a term "route" is actually a list of []*PathV2 - the purpose of the routing algorithm is to give us the best route amount all possible "routes"
  • a term "routes" is actually [][]*PathV2 a list of "route" (list of list of PathV2) - the purpose of "routes" is to identify all possible routes that meet input parameters and later we're searching for the best (the cheapest one) among them
  • A single PathV2 always refers to a single chain
  • In a single route all paths are unique based on the "from" chain and SendType (transfer, bridge, swap), it means no route that will contain the same chain and the same BridgeName twice.
  • Each individual path contains the amount that will be sent from the chain
  • If the amount is locked for "from" chain, then the path on that chain must have exactly the same AmountIn as it's in the locked map for that chain
  • Sum of all AmountIn for all paths in the route must be equal to AmountIn (the total amount the user is trying to send)

Now having all that in mind and params the test case you've provided we see that the only route in routes contains a single path which is {From: network1, AmountIn: (*hexutil.Big)(big.NewInt(200))}, which has AmountIn 200 for network 1, while the total AmountIn is 150, so this test case should not be possible I think. Also another issue here is that you've locked amount 50 for the network 1, and trying to send 150, while there is only a single path in the route for network 1.
After this issue #5244 test cases should be revised.

Danger 3:

When testing filterCapacityValidationV2 we should probably receive an error, but also in this case the criteria seems to be met. But the test case expects an empty route... This seems wrong to me.

Issues in this case are pretty similar as described in "Danger 2", so if you have this 1: (*hexutil.Big)(big.NewInt(50)), which means "I want to send exactly 50 from the chain 1" then you cannot have 2 paths in a final route for the same chain.
After this issue #5244 test cases should be revised.

@Samyoul I hope that helps in understanding what we want.

@Samyoul
Copy link
Member Author

Samyoul commented May 28, 2024

which has AmountIn 200 for network 1, while the total AmountIn is 150, so this test case should not be possible I think. Also another issue here is that you've locked amount 50 for the network 1, and trying to send 150, while there is only a single path in the route for network 1.
After this issue #5244 test cases should be revised.

Ok thank you, @saledjenic, so in this case the test case is correct, this scenario is impossible.


you cannot have 2 paths in a final route for the same chain.

I think that for this case we need to introduce additional validation to ensure that routes only contain a single instance of a network. Although this test fails, it would pass with other parameters.

EDIT:

I've updated #5227 to include the need to ensure routes do not include multiple instances of the same network.

Copy link
Contributor

@saledjenic saledjenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Samyoul comments here are getting bigger and bigger and harder to follow, I guess that you mapped the old logic we had to the new form, you've splited the logic very well that it can be maintained easear now, so please, let's merge it if it doesn't break anything we had and continue improving it through the issues you've created?

@Samyoul Samyoul force-pushed the router-filter-modularisation branch from 2a7f667 to 3518511 Compare May 28, 2024 19:36
@Samyoul Samyoul force-pushed the router-filter-modularisation branch from 3518511 to e01dab6 Compare May 28, 2024 19:45
@Samyoul
Copy link
Member Author

Samyoul commented May 28, 2024

All commits are now reworded to prepend test_:

@Samyoul Samyoul modified the milestone: 2.30.0 Beta May 28, 2024
@Samyoul Samyoul merged commit a3514e5 into develop May 28, 2024
11 of 12 checks passed
@Samyoul Samyoul deleted the router-filter-modularisation branch May 28, 2024 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants