From 0d5ee617362003f2d3333f4ef08d1a013e5c2a90 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Tue, 14 May 2024 18:42:54 +0100 Subject: [PATCH] (test/operators): complete test, but needs debugging or improvement, so disabled for now --- test/hub/PathTransferHub.t.sol | 7 +- test/operators/SignedPathOperator.t.so | 206 ++++++++++++++++++++++++ test/operators/SignedPathOperator.t.sol | 113 ------------- test/operators/TrustGraph.sol | 34 +++- 4 files changed, 237 insertions(+), 123 deletions(-) create mode 100644 test/operators/SignedPathOperator.t.so delete mode 100644 test/operators/SignedPathOperator.t.sol diff --git a/test/hub/PathTransferHub.t.sol b/test/hub/PathTransferHub.t.sol index a101929..ce0c56c 100644 --- a/test/hub/PathTransferHub.t.sol +++ b/test/hub/PathTransferHub.t.sol @@ -5,6 +5,7 @@ import {Test} from "forge-std/Test.sol"; import {StdCheats} from "forge-std/StdCheats.sol"; import "forge-std/console.sol"; import "../../src/hub/Hub.sol"; +import "../../src/hub/TypeDefinitions.sol"; import "../setup/TimeCirclesSetup.sol"; import "../setup/HumanRegistration.sol"; import "../utils/Approximation.sol"; @@ -84,12 +85,12 @@ contract HubPathTransferTest is Test, TimeCirclesSetup, HumanRegistration, Appro // C-D . . -5C 5C address[] memory flowVertices = new address[](M); - Hub.FlowEdge[] memory flow = new Hub.FlowEdge[](M - 1); + TypeDefinitions.FlowEdge[] memory flow = new Hub.FlowEdge[](M - 1); // allocate three coordinates per flow edge uint16[] memory coordinates = new uint16[]((M - 1) * 3); - // the flow vertices need to be provided in ascending order\ + // the flow vertices need to be provided in ascending order for (uint256 i = 0; i < M; i++) { flowVertices[i] = sortedAddresses[i]; } @@ -121,7 +122,7 @@ contract HubPathTransferTest is Test, TimeCirclesSetup, HumanRegistration, Appro bytes memory packedCoordinates = packCoordinates(coordinates); // Lastly we need to define the streams (only one from Alice to David) - Hub.Stream[] memory streams = new Hub.Stream[](1); + TypeDefinitions.Stream[] memory streams = new Hub.Stream[](1); // the source coordinate for Alice streams[0].sourceCoordinate = lookupMap[0]; // the flow edges that constitute the termination of this stream diff --git a/test/operators/SignedPathOperator.t.so b/test/operators/SignedPathOperator.t.so new file mode 100644 index 0000000..2237f55 --- /dev/null +++ b/test/operators/SignedPathOperator.t.so @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity >=0.8.24; + +import {Test} from "forge-std/Test.sol"; +import {StdCheats} from "forge-std/StdCheats.sol"; +import "forge-std/console.sol"; +import "../../src/hub/TypeDefinitions.sol"; +import "../../src/operators/SignedPathOperator.sol"; +import "../hub/MockDeployment.sol"; +import "../setup/TimeCirclesSetup.sol"; +import "../setup/HumanRegistration.sol"; +import "./TrustGraph.sol"; + +contract SignedPathOperatorTest is Test, TimeCirclesSetup, HumanRegistration, TrustGraph { + // Constants + + uint96 expiry = type(uint96).max; + + // State variables + + SignedPathOperator public operator; + MockHub public hub; + MockDeployment public deployment; + + // Constructor + + constructor() HumanRegistration(20) {} + + // Setup + + function setUp() public { + // set time to 10 december 2021 + startTime(); + + // deploy all contracts and the signed path operator + deployment = new MockDeployment(INFLATION_DAY_ZERO, 365 days); + hub = deployment.hub(); + operator = new SignedPathOperator(IHubV2(address(hub))); + + // register 20 humans + for (uint256 i = 0; i < N; i++) { + vm.prank(addresses[i]); + hub.registerHumanUnrestricted(); + assertEq(deployment.hub().isTrusted(addresses[i], addresses[i]), true); + } + // skip time to claim Circles + skipTime(14 days + 1 minutes); + for (uint256 i = 0; i < N; i++) { + vm.prank(addresses[i]); + hub.personalMintWithoutV1Check(); + } + + // diagram of the trust graph (all doubly connected) + + // 1---2---3 8---9 + // | \ | / | | / | + // 12 4---5---7---6---10 + // | / | | | \ | + // 11--13 14 15--16 + // | | | | + // 20------17------18--19 + _setTrustGraph(); + + + } + + // Tests + + function testSingleSignedPath() public { + // Alice is node 11; Bob is node 14 + address alice = addresses[11]; + + // only Alice authorizes the operator to execute a signed path on her behalf. + vm.prank(alice); + hub.setApprovalForAll(address(operator), true); + + (address[] memory flowVertices, + TypeDefinitions.FlowEdge[] memory flowEdges, + TypeDefinitions.Stream[] memory streams, + bytes memory packedCoordinates) = _setupExplicitFlowMatrix01(); + + vm.prank(alice); + operator.operateSignedFlowMatrix(flowVertices, flowEdges, streams, packedCoordinates, lookupMap[11]); + } + + // Internal functions + + function _setupExplicitFlowMatrix01() + internal view + returns (address[] memory, TypeDefinitions.FlowEdge[] memory, TypeDefinitions.Stream[] memory, bytes memory) + { + uint256 M = 7; + + // make it max width even if we dont touch all nodes + address[] memory flowVertices = new address[](N); + // allocate memory for some flow edges already + TypeDefinitions.FlowEdge[] memory flowEdges = new TypeDefinitions.FlowEdge[](M); + + uint16[] memory coordinates = new uint16[](M * 3); + + // the flow vertices need to be sorted + for (uint256 i = 0; i < N; i++) { + flowVertices[i] = sortedAddresses[i]; + } + + // todo: figure out how to effectively define advanced flow matrices programatically; + + uint256 index = 0; + + uint256 j = P1.length - 1; + // Alice -> Bob along P1 + for (uint256 i = 0; i < j; i++) { + flowEdges[i] = TypeDefinitions.FlowEdge(uint16(i), uint240(40 * CRC)); + flowEdges[i].streamSinkId = uint16(0); + coordinates[index++] = lookupMap[P1[i]]; // CRC + coordinates[index++] = lookupMap[P1[i]]; // source + coordinates[index++] = lookupMap[P1[i + 1]]; // receiver + } + + // Alice -> Bob along P2; continue counting with index + for (uint256 i = j; i < j + P2.length - 1; i++) { + flowEdges[i] = TypeDefinitions.FlowEdge(uint16(i), uint240(60 * CRC)); + flowEdges[i].streamSinkId = uint16(0); + coordinates[index++] = lookupMap[P2[i]]; // CRC + coordinates[index++] = lookupMap[P2[i]]; // source + coordinates[index++] = lookupMap[P2[i + 1]]; // receiver + } + // set the terminal edges to Bob to refer to the first stream (indexed at 1) + flowEdges[j - 1].streamSinkId = uint16(1); + flowEdges[j + P2.length - 2].streamSinkId = uint16(1); + + // pack the coordinates + bytes memory packedCoordinates = packCoordinates(coordinates); + + TypeDefinitions.Stream[] memory streams = new TypeDefinitions.Stream[](1); + streams[0].sourceCoordinate = lookupMap[11]; + streams[0].flowEdgeIds = new uint16[](2); + streams[0].flowEdgeIds[0] = uint16(j - 1); + streams[0].flowEdgeIds[1] = uint16(j + P2.length - 2); + streams[0].data = new bytes(0); + + return (flowVertices, flowEdges, streams, packedCoordinates); + } + + function _setTrustGraph() internal { + _linearlyDoubleConnect20(L1); + _linearlyDoubleConnect7(L2); + _fullyConnect3(F1); + _fullyConnect3(F2); + _fullyConnect3(F3); + _fullyConnect3(F4); + _fullyConnect3(F5); + } + + function _fullyConnect3(uint256[3] memory _list) internal { + for (uint256 i = 0; i < _list.length; i++) { + for (uint256 j = 0; j < _list.length; j++) { + if (i != j) { + vm.prank(addresses[_list[i]]); + hub.trust(addresses[_list[j]], expiry); + } + } + } + } + + function _linearlySingleConnect(uint256[] memory _list) internal { + for (uint256 i = 0; i < _list.length - 1; i++) { + vm.prank(addresses[_list[i]]); + hub.trust(addresses[_list[i + 1]], expiry); + } + } + + function _linearlyDoubleConnect20(uint256[20] memory _list) internal { + for (uint256 i = 0; i < _list.length - 1; i++) { + vm.prank(addresses[_list[i]]); + hub.trust(addresses[_list[i + 1]], expiry); + vm.prank(addresses[_list[i + 1]]); + hub.trust(addresses[_list[i]], expiry); + } + } + + function _linearlyDoubleConnect7(uint256[7] memory _list) internal { + for (uint256 i = 0; i < _list.length - 1; i++) { + vm.prank(addresses[_list[i]]); + hub.trust(addresses[_list[i + 1]], expiry); + vm.prank(addresses[_list[i + 1]]); + hub.trust(addresses[_list[i]], expiry); + } + } + + // duplicated from test/hub/PathTransferHub.t.sol + /** + * @dev Packs an array of uint16 coordinates into bytes. + * Each coordinate is represented as 16 bits (2 bytes). + * @param _coordinates The array of uint16 coordinates. + * @return packedData_ The packed coordinates as bytes. + */ + function packCoordinates(uint16[] memory _coordinates) private pure returns (bytes memory packedData_) { + packedData_ = new bytes(_coordinates.length * 2); + + for (uint256 i = 0; i < _coordinates.length; i++) { + packedData_[2 * i] = bytes1(uint8(_coordinates[i] >> 8)); // High byte + packedData_[2 * i + 1] = bytes1(uint8(_coordinates[i] & 0xFF)); // Low byte + } + } +} diff --git a/test/operators/SignedPathOperator.t.sol b/test/operators/SignedPathOperator.t.sol deleted file mode 100644 index 51798f3..0000000 --- a/test/operators/SignedPathOperator.t.sol +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.24; - -import {Test} from "forge-std/Test.sol"; -import {StdCheats} from "forge-std/StdCheats.sol"; -import "forge-std/console.sol"; -import "../../src/operators/SignedPathOperator.sol"; -import "../hub/MockDeployment.sol"; -import "../setup/TimeCirclesSetup.sol"; -import "../setup/HumanRegistration.sol"; -import "./TrustGraph.sol"; - -contract SignedPathOperatorTest is Test, TimeCirclesSetup, HumanRegistration, TrustGraph { - // Constants - - uint96 expiry = type(uint96).max; - - // State variables - - SignedPathOperator public operator; - MockHub public hub; - MockDeployment public deployment; - - // Constructor - - constructor() HumanRegistration(20) {} - - // Setup - - function setUp() public { - // set time to 10 december 2021 - startTime(); - - // deploy all contracts and the signed path operator - deployment = new MockDeployment(INFLATION_DAY_ZERO, 365 days); - hub = deployment.hub(); - operator = new SignedPathOperator(IHubV2(address(hub))); - - // register 20 humans - for (uint256 i = 0; i < N; i++) { - vm.prank(addresses[i]); - deployment.hub().registerHumanUnrestricted(); - assertEq(deployment.hub().isTrusted(addresses[i], addresses[i]), true); - } - // skip time to claim Circles - skipTime(14 days + 1 minutes); - for (uint256 i = 0; i < N; i++) { - vm.prank(addresses[i]); - hub.personalMintWithoutV1Check(); - } - - // diagram of the trust graph (all doubly connected) - - // 1---2---3 8---9 - // | \ | / | | / | - // 12 4---5---7---6---10 - // | / | | | \ | - // 11--13 14 15--16 - // | | | | - // 20------17------18--19 - _setTrustGraph(); - } - - // Tests - - // Internal functions - - function _setTrustGraph() internal { - _linearlyDoubleConnect20(L1); - _linearlyDoubleConnect7(L2); - _fullyConnect3(F1); - _fullyConnect3(F2); - _fullyConnect3(F3); - _fullyConnect3(F4); - _fullyConnect3(F5); - } - - function _fullyConnect3(uint256[3] memory _list) internal { - for (uint256 i = 0; i < _list.length; i++) { - for (uint256 j = 0; j < _list.length; j++) { - if (i != j) { - vm.prank(addresses[_list[i]]); - hub.trust(addresses[_list[j]], expiry); - } - } - } - } - - function _linearlySingleConnect(uint256[] memory _list) internal { - for (uint256 i = 0; i < _list.length - 1; i++) { - vm.prank(addresses[_list[i]]); - hub.trust(addresses[_list[i + 1]], expiry); - } - } - - function _linearlyDoubleConnect20(uint256[20] memory _list) internal { - for (uint256 i = 0; i < _list.length - 1; i++) { - vm.prank(addresses[_list[i]]); - hub.trust(addresses[_list[i + 1]], expiry); - vm.prank(addresses[_list[i + 1]]); - hub.trust(addresses[_list[i]], expiry); - } - } - - function _linearlyDoubleConnect7(uint256[7] memory _list) internal { - for (uint256 i = 0; i < _list.length - 1; i++) { - vm.prank(addresses[_list[i]]); - hub.trust(addresses[_list[i + 1]], expiry); - vm.prank(addresses[_list[i + 1]]); - hub.trust(addresses[_list[i]], expiry); - } - } -} diff --git a/test/operators/TrustGraph.sol b/test/operators/TrustGraph.sol index c4baf34..81f04b2 100644 --- a/test/operators/TrustGraph.sol +++ b/test/operators/TrustGraph.sol @@ -16,13 +16,33 @@ contract TrustGraph { // | | | | // 20------17------18--19 + // should be indexed from zero; + + // // contours + // uint256[20] internal L1 = [1, 2, 3, 5, 7, 6, 8, 9, 10, 16, 19, 18, 17, 20, 11, 12]; + // uint256[7] internal L2 = [5, 7, 6, 15, 18, 17, 14]; + // // inside clusters + // uint256[3] internal F1 = [1, 2, 4]; + // uint256[3] internal F2 = [4, 3, 5]; + // uint256[3] internal F3 = [11, 13, 4]; + // uint256[3] internal F4 = [10, 9, 6]; + // uint256[3] internal F5 = [6, 15, 16]; + + // // define paths from Alice (11) to Bob (14) + // uint256[4] internal P1 = [11, 4, 5, 14]; + // uint256[5] internal P2 = [11, 13, 4, 5, 14]; + // contours - uint256[20] internal L1 = [1, 2, 3, 5, 7, 6, 8, 9, 10, 16, 19, 18, 17, 20, 11, 12]; - uint256[7] internal L2 = [5, 7, 6, 15, 18, 17, 14]; + uint256[20] internal L1 = [0, 1, 2, 4, 6, 5, 7, 8, 9, 15, 18, 17, 16, 19, 10, 11]; + uint256[7] internal L2 = [4, 6, 5, 14, 17, 16, 13]; // inside clusters - uint256[3] internal F1 = [1, 2, 4]; - uint256[3] internal F2 = [4, 3, 5]; - uint256[3] internal F3 = [11, 13, 4]; - uint256[3] internal F4 = [10, 9, 6]; - uint256[3] internal F5 = [6, 15, 16]; + uint256[3] internal F1 = [0, 1, 3]; + uint256[3] internal F2 = [3, 2, 4]; + uint256[3] internal F3 = [10, 12, 3]; + uint256[3] internal F4 = [9, 8, 5]; + uint256[3] internal F5 = [5, 14, 15]; + + // define paths from Alice (11) to Bob (14) + uint256[4] internal P1 = [10, 3, 4, 13]; + uint256[5] internal P2 = [10, 12, 3, 4, 13]; }