Skip to content

feat(node): support l2 plus value transfer#1240

Merged
cryptoAtwill merged 11 commits intosupport-l2-plusfrom
support-l2-value
Dec 31, 2024
Merged

feat(node): support l2 plus value transfer#1240
cryptoAtwill merged 11 commits intosupport-l2-plusfrom
support-l2-value

Conversation

@cryptoAtwill
Copy link
Copy Markdown
Contributor

@cryptoAtwill cryptoAtwill commented Dec 20, 2024

@cryptoAtwill cryptoAtwill requested a review from a team as a code owner December 20, 2024 08:38
Copy link
Copy Markdown
Contributor

@raulk raulk left a comment

Choose a reason for hiding this comment

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

LGTM. For posterity purposes, this is our guiding design sketch:

image

}

function equals(Asset memory asset, Asset memory asset2) internal pure returns (bool) {
return asset.tokenAddress == asset2.tokenAddress;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's compare kinds too to make this code more defensive against future changes, e.g. we may introduce a third asset class identified only by kind, or by attributes other than tokenAddress.

CannotSendToItself,
CommonParentNotExist
CommonParentNotExist,
InvalidSupplySource
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
InvalidSupplySource
IncompatibleSupplySource


/// Checks if the incoming and outgoing subnet supply sources can be mapped.
/// Caller should make sure the incoming/outgoing subnets and current subnet are immediate parent/child subnets.
function checkSubnetsAssets(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
function checkSubnetsAssets(
function checkSubnetsSupplyCompatible(

}
}

bool validSupplySources = checkSubnetsAssets({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
bool validSupplySources = checkSubnetsAssets({
bool supplySourcesCompatible = checkSubnetsAssets({

@cryptoAtwill
Copy link
Copy Markdown
Contributor Author

sendCrossMessageFromChildToParentWithResult(params);
}

function testL2PlusSubnet_TokenMixed_SendCrossMessageFromChildToParentWithOkResult() public {
Copy link
Copy Markdown
Contributor Author

@cryptoAtwill cryptoAtwill Dec 27, 2024

Choose a reason for hiding this comment

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

these tests are removed because tokenL2 to token L3 xnet value transfer does not work. Updated in: https://github.com/consensus-shipyard/ipc/pull/1240/files#diff-53695b3660cd8c2d5418a61e61a1abda1cd2ba05dcc0f607ddd3251b9cc8f57dR436

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Removed temporarily, since we cover this error scenario in the cited PR.

if (crossMsg.kind == IpcMsgKind.Transfer) {
// If the cross msg kind is Result, create result message should have handled the value correctly.
// If the execution is ok, value should be 0, else one should perform refund.
if (crossMsg.kind == IpcMsgKind.Transfer || crossMsg.kind == IpcMsgKind.Result) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is not correct; the version in main is more correct. For a Result message, you will want to perform a call as this returns control back to the caller. Rationale:

  • if it's an account, there will be no code to invoke, so this will be have like a bare transfer
  • but if the original caller was a contract, you will want to give it control so it can handle the result

Copy link
Copy Markdown
Contributor

@raulk raulk left a comment

Choose a reason for hiding this comment

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

LGTM, feel free to merge, just a few nits and comments inline.

sendCrossMessageFromChildToParentWithResult(params);
}

function testL2PlusSubnet_TokenMixed_SendCrossMessageFromChildToParentWithOkResult() public {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Removed temporarily, since we cover this error scenario in the cited PR.

Comment on lines 611 to +617
function validateCrossMessage(IpcEnvelope memory envelope) internal view returns (CrossMessageValidationOutcome) {
GatewayActorStorage storage s = LibGatewayActorStorage.appStorage();
SubnetID memory toSubnetId = envelope.to.subnetId;
(CrossMessageValidationOutcome outcome, ) = checkCrossMessage(envelope);
return outcome;
}

/// @notice Validates a cross message and returns the applyType if the message is valid
function checkCrossMessage(IpcEnvelope memory envelope) internal view returns (CrossMessageValidationOutcome, IPCMsgType applyType) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I would keep these as a single function returning a tuple. Would call this single method inspect().

// Call flow tests.
//---------------------

// testing Native L1 => ERC20 L2 => ERC20 L3, this supply source is not allowed
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can't we add assertions on the returned result here? (i.e. that it's a failure and it carries the correct reason)

Comment on lines +131 to +139
interface IGateway {
function sendContractXnetMessage(
IpcEnvelope memory envelope
) external payable returns (IpcEnvelope memory committed);

function fund(SubnetID calldata subnetId, FvmAddress calldata to) external payable;

function fundWithToken(SubnetID calldata subnetId, FvmAddress calldata to, uint256 amount) external;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we need this local interface definition here? Can't we import the canonical one from interfaces/?

// ======= internal util methods ========

function executeTopdownMessages(IpcEnvelope[] memory msgs, GatewayDiamond gw) internal {
uint256 minted_tokens;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Convention is lower snake case.

Comment on lines +179 to +184
for (uint256 i; i < msgs.length; ) {
minted_tokens += msgs[i].value;
unchecked {
++i;
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since tests do not run in a gas restricted environment, we can unclutter this by removing the unchecked increment.

Comment on lines +199 to +232
function createBottomUpCheckpoint(
SubnetID memory subnet,
GatewayDiamond gw
) internal returns (BottomUpCheckpoint memory checkpoint) {
uint256 e = getNextEpoch(block.number, DEFAULT_CHECKPOINT_PERIOD);

GatewayGetterFacet getter = gw.getter();
CheckpointingFacet checkpointer = gw.checkpointer();

BottomUpMsgBatch memory batch = getter.bottomUpMsgBatch(e);

(, address[] memory addrs, uint256[] memory weights) = TestUtils.getFourValidators(vm);

(bytes32 membershipRoot, ) = MerkleTreeHelper.createMerkleProofsForValidators(addrs, weights);

checkpoint = BottomUpCheckpoint({
subnetID: subnet,
blockHeight: batch.blockHeight,
blockHash: keccak256("block1"),
nextConfigurationNumber: 0,
msgs: batch.msgs,
activity: ActivityHelper.newCompressedActivityRollup(1, 3, bytes32(uint256(0)))
});

vm.prank(FilAddress.SYSTEM_ACTOR);
checkpointer.createBottomUpCheckpoint(
checkpoint,
membershipRoot,
weights[0] + weights[1] + weights[2],
ActivityHelper.dummyActivityRollup()
);

return checkpoint;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we really not have utils for this kind of common stuff in a test library?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

not really, I created an issue to track this good to have: #1244

@cryptoAtwill cryptoAtwill merged commit 8780344 into support-l2-plus Dec 31, 2024
@cryptoAtwill cryptoAtwill deleted the support-l2-value branch December 31, 2024 05:39
karlem pushed a commit that referenced this pull request Jan 9, 2025
Co-authored-by: cryptoAtwill <willes.lau@protocol.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants