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

feat: checkpointed event #1831

Merged
merged 5 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 147 additions & 2 deletions node/engine/chainservice/adjudicator/NitroAdjudicator.go

Large diffs are not rendered by default.

28 changes: 13 additions & 15 deletions packages/nitro-protocol/contracts/ForceMove.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contract ForceMove is IForceMove, StatusManager {
* @param channelId Unique identifier for a state channel.
* @return turnNumRecord A turnNum that (the adjudicator knows) is supported by a signature from each participant.
* @return finalizesAt The unix timestamp when `channelId` will finalize.
* @return fingerprint The last 160 bits of kecca256(stateHash, outcomeHash)
* @return fingerprint The last 160 bits of keccak256(stateHash, outcomeHash)
*/
function unpackStatus(
bytes32 channelId
Expand Down Expand Up @@ -103,8 +103,19 @@ contract ForceMove is IForceMove, StatusManager {
(supported, reason) = _stateIsSupported(fixedPart, proof, candidate);
require(supported, reason);

ChannelMode currMode = _mode(channelId);

// effects
_clearChallenge(channelId, candidateTurnNum);
statusOf[channelId] = _generateStatus(
ChannelData(candidateTurnNum, 0, bytes32(0), bytes32(0))
);

if (currMode == ChannelMode.Open) {
emit Checkpointed(channelId, candidateTurnNum);
} else {
// `Finalized` was ruled out by the require above
emit ChallengeCleared(channelId, candidateTurnNum);
}
}

/**
Expand Down Expand Up @@ -272,19 +283,6 @@ contract ForceMove is IForceMove, StatusManager {
return rvp;
}

/**
* @notice Clears a challenge by updating the turnNumRecord and resetting the remaining channel storage fields, and emits a ChallengeCleared event.
* @dev Clears a challenge by updating the turnNumRecord and resetting the remaining channel storage fields, and emits a ChallengeCleared event.
* @param channelId Unique identifier for a channel.
* @param newTurnNumRecord New turnNumRecord to overwrite existing value
*/
function _clearChallenge(bytes32 channelId, uint48 newTurnNumRecord) internal {
statusOf[channelId] = _generateStatus(
ChannelData(newTurnNumRecord, 0, bytes32(0), bytes32(0))
);
emit ChallengeCleared(channelId, newTurnNumRecord);
}

/**
* @notice Checks that the submitted turnNumRecord is strictly greater than the turnNumRecord stored on chain.
* @dev Checks that the submitted turnNumRecord is strictly greater than the turnNumRecord stored on chain.
Expand Down
7 changes: 7 additions & 0 deletions packages/nitro-protocol/contracts/interfaces/IForceMove.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ interface IForceMove is INitroTypes {
*/
event ChallengeCleared(bytes32 indexed channelId, uint48 newTurnNumRecord);

/**
* @dev Indicates that an on-chain channel data was successfully updated and now has `newTurnNumRecord` as the latest turn number.
* @param channelId Unique identifier for a state channel.
* @param newTurnNumRecord A latest turnNum that (the adjudicator knows) is supported by adhering to channel application rules.
*/
event Checkpointed(bytes32 indexed channelId, uint48 newTurnNumRecord);

/**
* @dev Indicates that a challenge has been registered against `channelId`.
* @param channelId Unique identifier for a state channel.
Expand Down
6 changes: 3 additions & 3 deletions packages/nitro-protocol/gas-benchmarks/gasResults.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"deployInfrastructureContracts": {
"satp": {
"NitroAdjudicator": 3428703
"NitroAdjudicator": 3443915
}
},
"directlyFundAChannelWithETHFirst": {
Expand Down Expand Up @@ -95,9 +95,9 @@
},
"ETHClearChallenge": {
"satp": {
"checkpointX": 73562,
"checkpointX": 73936,
"challengeResponseX": 96482,
"checkpointL": 69558,
"checkpointL": 69932,
"challengeResponseL": 89655,
"challengeResponseV": 0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ describe('checkpoint', () => {
it.each`
description | largestTurnNum | support | finalizesAt | reason
${accepts1} | ${turnNumRecord + 1} | ${valid} | ${undefined} | ${undefined}
${accepts2} | ${turnNumRecord + 1} | ${valid} | ${never} | ${undefined}
${accepts3} | ${turnNumRecord + 1 + participantsNum} | ${valid} | ${future} | ${undefined}
${accepts2} | ${turnNumRecord + 1} | ${valid} | ${future} | ${undefined}
${accepts3} | ${turnNumRecord + 1 + participantsNum} | ${valid} | ${never} | ${undefined}
Comment on lines -96 to +97
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The description of accepts2 test case states a challenge must be in progress, so finalizesAt should be future.

${reverts1} | ${turnNumRecord} | ${valid} | ${never} | ${TURN_NUM_RECORD_NOT_INCREASED}
${reverts2} | ${turnNumRecord + 1} | ${invalidTransition} | ${never} | ${COUNTING_APP_INVALID_TRANSITION}
${reverts3} | ${turnNumRecord + 1} | ${unsupported} | ${never} | ${INVALID_SIGNED_BY}
Expand Down Expand Up @@ -127,12 +127,11 @@ describe('checkpoint', () => {
bindSignatures(variableParts, signatures, whoSignedWhat)
);

const isOpen = !!finalizesAt;
const outcome = isOpen ? [] : defaultOutcome;
const isChallenged = finalizesAt && finalizesAt > Math.floor(new Date().getTime() / 1000);
const outcome = isChallenged ? defaultOutcome : [];

const challengeState: State | undefined = isOpen
? undefined
: {
const challengeState: State | undefined = isChallenged
? {
turnNum: turnNumRecord,
isFinal: false,
channelNonce,
Expand All @@ -141,7 +140,8 @@ describe('checkpoint', () => {
appData: defaultAbiCoder.encode(['uint256'], [appDatas[0]]),
appDefinition,
challengeDuration,
};
}
: undefined;

const fingerprint = finalizesAt
? channelDataToStatus({
Expand All @@ -162,6 +162,8 @@ describe('checkpoint', () => {
} else {
const receipt = await (await tx).wait();
const event = receipt.events.pop();

expect(event.event).toEqual(isChallenged ? 'ChallengeCleared' : 'Checkpointed');
expect(event.args).toMatchObject({
channelId,
newTurnNumRecord: largestTurnNum,
Expand Down
Loading