-
Notifications
You must be signed in to change notification settings - Fork 1
Enhance/precompile resolveaddress #4
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,3 +7,4 @@ out | |
|
|
||
| # VIM | ||
| *.swp | ||
| foundry.lock | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| pragma solidity ^0.8.30; | ||
|
|
||
| import {RESOLVE_ADDRESS} from "./FVMPrecompiles.sol"; | ||
|
|
||
| library FVMAddress { | ||
| function resolveAddress(bytes memory filAddress) internal view returns (bool success, uint64 actorId) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should be returning exists rather than success. success is uninteresting because it only fails if the address is invalid. should revert in that case. |
||
| bytes memory result; | ||
| (success, result) = address(RESOLVE_ADDRESS).staticcall(filAddress); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RESOLVE_ADDRESS is already an address and doesn't need to be cast to address |
||
|
|
||
| if (success && result.length == 32) { | ||
| actorId = abi.decode(result, (uint64)); | ||
| } | ||
| } | ||
|
|
||
| function toActorId(bytes memory filAddress) internal view returns (uint64 actorId) { | ||
| (bool success, uint64 id) = resolveAddress(filAddress); | ||
| require(success, "FVMAddress: Invalid address format"); | ||
| require(id != 0, "FVMAddress: Actor not found"); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0 is a valid ID. It is the id of the system actor. |
||
| return id; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| pragma solidity ^0.8.30; | ||
|
|
||
| contract FVMResolveAddress { | ||
| mapping(bytes32 => uint64) public addressMocks; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mockActorIds |
||
| mapping(bytes32 => bool) public addressExists; | ||
|
|
||
| function mockResolveAddress(bytes memory filAddress, uint64 actorId) external { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also provide a helper for mocking address that converts the address to f4 |
||
| bytes32 hash = keccak256(filAddress); | ||
| addressMocks[hash] = actorId; | ||
| addressExists[hash] = true; | ||
| } | ||
|
|
||
| fallback() external { | ||
| bytes32 addressHash = keccak256(msg.data); | ||
|
|
||
| if (addressExists[addressHash]) { | ||
| uint64 actorId = addressMocks[addressHash]; | ||
| assembly ("memory-safe") { | ||
| mstore(0, actorId) | ||
| return(0, 32) | ||
| } | ||
| } | ||
|
|
||
| assembly ("memory-safe") { | ||
| return(0, 0) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,18 +3,20 @@ pragma solidity ^0.8.30; | |
|
|
||
| import {Test} from "forge-std/Test.sol"; | ||
|
|
||
| import {CALL_ACTOR_BY_ADDRESS, CALL_ACTOR_BY_ID, GET_BEACON_RANDOMNESS} from "../FVMPrecompiles.sol"; | ||
| import {CALL_ACTOR_BY_ADDRESS, CALL_ACTOR_BY_ID, GET_BEACON_RANDOMNESS, RESOLVE_ADDRESS} from "../FVMPrecompiles.sol"; | ||
| import {FVMCallActorByAddress} from "./FVMCallActorByAddress.sol"; | ||
| import {FVMCallActorById} from "./FVMCallActorById.sol"; | ||
| import {FVMGetBeaconRandomness} from "./FVMGetBeaconRandomness.sol"; | ||
| import {FVMResolveAddress} from "./FVMResolveAddress.sol"; | ||
|
|
||
| /// @notice Mocks the FVM precompiles for forge test | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to keep this. Why do you remove it? |
||
| contract MockFVMTest is Test { | ||
| FVMGetBeaconRandomness public constant RANDOMNESS_PRECOMPILE = FVMGetBeaconRandomness(GET_BEACON_RANDOMNESS); | ||
| FVMResolveAddress public constant RESOLVE_ADDRESS_PRECOMPILE = FVMResolveAddress(RESOLVE_ADDRESS); | ||
|
|
||
| function setUp() public virtual { | ||
| vm.etch(CALL_ACTOR_BY_ADDRESS, address(new FVMCallActorByAddress()).code); | ||
| vm.etch(CALL_ACTOR_BY_ID, address(new FVMCallActorById()).code); | ||
| vm.etch(GET_BEACON_RANDOMNESS, address(new FVMGetBeaconRandomness()).code); | ||
| vm.etch(RESOLVE_ADDRESS, address(new FVMResolveAddress()).code); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| pragma solidity ^0.8.30; | ||
|
|
||
| import {MockFVMTest} from "../src/mocks/MockFVMTest.sol"; | ||
| import {FVMAddress} from "../src/FVMAddress.sol"; | ||
|
|
||
| contract AddressTest is MockFVMTest { | ||
| using FVMAddress for bytes; | ||
|
|
||
| function testResolveAddressNotFound() public view { | ||
| bytes memory fakeAddress = hex"0102030405060708090a0b0c0d0e0f10"; | ||
| (bool success, uint64 actorId) = FVMAddress.resolveAddress(fakeAddress); | ||
| assertTrue(success); | ||
| assertEq(actorId, 0); | ||
| } | ||
|
|
||
| function testResolveAddressMocked() public { | ||
| bytes memory testAddress = hex"01234567"; | ||
| uint64 expectedActorId = 12345; | ||
|
|
||
| RESOLVE_ADDRESS_PRECOMPILE.mockResolveAddress(testAddress, expectedActorId); | ||
|
|
||
| (bool success, uint64 actorId) = FVMAddress.resolveAddress(testAddress); | ||
| assertTrue(success); | ||
| assertEq(actorId, expectedActorId); | ||
| } | ||
|
|
||
| function testToActorId() public { | ||
| bytes memory testAddress = hex"0123456789abcdef"; | ||
| uint64 expectedActorId = 99999; | ||
|
|
||
| RESOLVE_ADDRESS_PRECOMPILE.mockResolveAddress(testAddress, expectedActorId); | ||
|
|
||
| uint64 actorId = testAddress.toActorId(); | ||
| assertEq(actorId, expectedActorId); | ||
| } | ||
|
|
||
| function testMultipleAddressResolutions() public { | ||
| bytes memory addr1 = hex"aabbccdd"; | ||
| bytes memory addr2 = hex"11223344"; | ||
| uint64 actorId1 = 1111; | ||
| uint64 actorId2 = 2222; | ||
|
|
||
| RESOLVE_ADDRESS_PRECOMPILE.mockResolveAddress(addr1, actorId1); | ||
| RESOLVE_ADDRESS_PRECOMPILE.mockResolveAddress(addr2, actorId2); | ||
|
|
||
| assertEq(addr1.toActorId(), actorId1); | ||
| assertEq(addr2.toActorId(), actorId2); | ||
| } | ||
|
|
||
| function testDifferentAddressFormats() public { | ||
| bytes memory shortAddr = hex"01"; | ||
| bytes memory longAddr = hex"0123456789abcdef0123456789abcdef"; | ||
| uint64 shortActorId = 100; | ||
| uint64 longActorId = 200; | ||
|
|
||
| RESOLVE_ADDRESS_PRECOMPILE.mockResolveAddress(shortAddr, shortActorId); | ||
| RESOLVE_ADDRESS_PRECOMPILE.mockResolveAddress(longAddr, longActorId); | ||
|
|
||
| (bool success1, uint64 actorId1) = FVMAddress.resolveAddress(shortAddr); | ||
| (bool success2, uint64 actorId2) = FVMAddress.resolveAddress(longAddr); | ||
|
|
||
| assertTrue(success1); | ||
| assertTrue(success2); | ||
| assertEq(actorId1, shortActorId); | ||
| assertEq(actorId2, longActorId); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this overlaps with #3, I think it makes sense for library FVMAddress to be one pull request.