-
Notifications
You must be signed in to change notification settings - Fork 152
BM-1466: Ec2/claim digest #1004
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 50 commits
435e8c4
4c36ef5
d798851
a1d3222
575d8b5
1ebbc60
924c53f
2e2156a
63d873a
da0cc55
661daa6
7cd90bb
a672a0a
918934a
4a8b78e
48822c6
ebbccd1
0985ba3
9b25d47
e4dbfd4
00f1078
3c43edf
25c7b42
7b905ef
27d0dc0
41aa8b6
9566b73
50167b3
fc6bd7f
e2013f8
eaa391f
0032fa2
c90f973
4ae5304
ea907a8
1937e1b
69abfb7
5df52a5
7864baa
ac3c914
3e0d070
8d8a0c8
d3c9ace
2ba252f
8833ded
e161dff
de0d3e2
3b54725
7f2172e
04f6f99
0600765
88b981b
d294e34
dd44c54
d70bc72
de7225e
3778944
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 |
---|---|---|
@@ -1,22 +1,22 @@ | ||
{ | ||
"fulfill (with callback): batch of 001": "132142", | ||
"fulfill (with callback): batch of 002": "218443", | ||
"fulfill (with callback): batch of 004": "392147", | ||
"fulfill (with callback): batch of 008": "739579", | ||
"fulfill (with callback): batch of 016": "1272464", | ||
"fulfill (with callback): batch of 032": "2373148", | ||
"fulfill (with selector): batch of 001": "92745", | ||
"fulfill (with selector): batch of 002": "139726", | ||
"fulfill (with selector): batch of 004": "236258", | ||
"fulfill (with selector): batch of 008": "420231", | ||
"fulfill (with selector): batch of 016": "790425", | ||
"fulfill (with selector): batch of 032": "1558877", | ||
"fulfill: batch of 001": "90487", | ||
"fulfill: batch of 002": "135232", | ||
"fulfill: batch of 004": "227181", | ||
"fulfill: batch of 008": "402117", | ||
"fulfill: batch of 016": "754179", | ||
"fulfill: batch of 032": "1485129", | ||
"fulfill: batch of 064": "3014348", | ||
"fulfill: batch of 128": "6255291" | ||
"fulfill (with callback): batch of 001": "133867", | ||
"fulfill (with callback): batch of 002": "221508", | ||
"fulfill (with callback): batch of 004": "397945", | ||
"fulfill (with callback): batch of 008": "750387", | ||
"fulfill (with callback): batch of 016": "1292502", | ||
"fulfill (with callback): batch of 032": "2409336", | ||
"fulfill (with selector): batch of 001": "94414", | ||
"fulfill (with selector): batch of 002": "142699", | ||
"fulfill (with selector): batch of 004": "241820", | ||
"fulfill (with selector): batch of 008": "430750", | ||
"fulfill (with selector): batch of 016": "810306", | ||
"fulfill (with selector): batch of 032": "1594177", | ||
"fulfill: batch of 001": "92164", | ||
"fulfill: batch of 002": "138207", | ||
"fulfill: batch of 004": "232791", | ||
"fulfill: batch of 008": "412665", | ||
"fulfill: batch of 016": "773951", | ||
"fulfill: batch of 032": "1520776", | ||
"fulfill: batch of 064": "3070189", | ||
"fulfill: batch of 128": "6308304" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,8 +24,10 @@ import {Account} from "./types/Account.sol"; | |
import {AssessorJournal} from "./types/AssessorJournal.sol"; | ||
import {AssessorCallback} from "./types/AssessorCallback.sol"; | ||
import {AssessorCommitment} from "./types/AssessorCommitment.sol"; | ||
import {CallbackData} from "./types/CallbackData.sol"; | ||
import {Fulfillment} from "./types/Fulfillment.sol"; | ||
import {AssessorReceipt} from "./types/AssessorReceipt.sol"; | ||
import {PredicateType} from "./types/Predicate.sol"; | ||
import {ProofRequest} from "./types/ProofRequest.sol"; | ||
import {LockRequest, LockRequestLibrary} from "./types/LockRequest.sol"; | ||
import {RequestId} from "./types/RequestId.sol"; | ||
|
@@ -239,6 +241,7 @@ contract BoundlessMarket is | |
} | ||
bytes32[] memory leaves = new bytes32[](fills.length); | ||
bool[] memory hasSelector = new bool[](fills.length); | ||
PredicateType[] memory predicateTypes = new PredicateType[](fills.length); | ||
|
||
// Check the selector constraints. | ||
// NOTE: The assessor guest adds non-zero selector values to the list. | ||
|
@@ -255,16 +258,16 @@ contract BoundlessMarket is | |
// Verify the application receipts. | ||
for (uint256 i = 0; i < fills.length; i++) { | ||
Fulfillment calldata fill = fills[i]; | ||
predicateTypes[i] = fill.predicateType; | ||
|
||
bytes32 claimDigest = ReceiptClaimLib.ok(fill.imageId, sha256(fill.journal)).digest(); | ||
leaves[i] = AssessorCommitment(i, fill.id, fill.requestDigest, claimDigest).eip712Digest(); | ||
leaves[i] = AssessorCommitment(i, fill.id, fill.requestDigest, fill.claimDigest).eip712Digest(); | ||
|
||
// If the requestor did not specify a selector, we verify with DEFAULT_MAX_GAS_FOR_VERIFY gas limit. | ||
// This ensures that by default, client receive proofs that can be verified cheaply as part of their applications. | ||
if (!hasSelector[i]) { | ||
VERIFIER.verifyIntegrity{gas: DEFAULT_MAX_GAS_FOR_VERIFY}(Receipt(fill.seal, claimDigest)); | ||
VERIFIER.verifyIntegrity{gas: DEFAULT_MAX_GAS_FOR_VERIFY}(Receipt(fill.seal, fill.claimDigest)); | ||
} else { | ||
VERIFIER.verifyIntegrity(Receipt(fill.seal, claimDigest)); | ||
VERIFIER.verifyIntegrity(Receipt(fill.seal, fill.claimDigest)); | ||
} | ||
} | ||
|
||
|
@@ -278,6 +281,7 @@ contract BoundlessMarket is | |
root: batchRoot, | ||
callbacks: assessorReceipt.callbacks, | ||
selectors: assessorReceipt.selectors, | ||
predicateTypes: predicateTypes, | ||
prover: assessorReceipt.prover | ||
}) | ||
) | ||
|
@@ -333,13 +337,31 @@ contract BoundlessMarket is | |
} | ||
|
||
uint256 callbackIndexPlusOne = fillToCallbackIndexPlusOne[i]; | ||
if (callbackIndexPlusOne > 0) { | ||
// We do not support callbacks for claim digest matches. | ||
if ((fill.predicateType != PredicateType.ClaimDigestMatch) && (callbackIndexPlusOne > 0)) { | ||
(bytes32 imageId, bytes calldata journal) = _decodeCallbackData(fill.callbackData); | ||
|
||
AssessorCallback calldata callback = assessorReceipt.callbacks[callbackIndexPlusOne - 1]; | ||
_executeCallback(fill.id, callback.addr, callback.gasLimit, fill.imageId, fill.journal, fill.seal); | ||
_executeCallback(fill.id, callback.addr, callback.gasLimit, imageId, journal, fill.seal); | ||
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. If I'm reading this correctly, it seems that imageId and journal here are not authenticated. 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 now that I think about it, are we only guaranteeing the callbackData in case of a callback is required? Cause in that case the only way to get back a journal now is by requesting a callback and I'm not sure is what we want |
||
} | ||
} | ||
} | ||
|
||
function _decodeCallbackData(bytes calldata data) internal pure returns (bytes32 imageId, bytes calldata journal) { | ||
assembly { | ||
// Extract imageId (first 32 bytes after length) | ||
imageId := calldataload(add(data.offset, 0x20)) | ||
|
||
// Extract journal offset and create calldata slice | ||
let journalOffset := calldataload(add(data.offset, 0x40)) | ||
let journalPtr := add(data.offset, add(0x20, journalOffset)) | ||
let journalLength := calldataload(journalPtr) | ||
|
||
journal.offset := add(journalPtr, 0x20) | ||
journal.length := journalLength | ||
} | ||
} | ||
|
||
/// @inheritdoc IBoundlessMarket | ||
function priceAndFulfillAndWithdraw( | ||
ProofRequest[] calldata requests, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
pragma solidity ^0.8.20; | ||
|
||
import {AssessorCallback} from "./AssessorCallback.sol"; | ||
import {PredicateType} from "./Predicate.sol"; | ||
import {Selector} from "./Selector.sol"; | ||
|
||
/// @title Assessor Journal Struct | ||
|
@@ -17,6 +18,8 @@ struct AssessorJournal { | |
/// @notice The (optional) selectors for the requests committed by the assessor. | ||
/// @dev This is used to verify the fulfillment of the request against its selector's seal. | ||
Selector[] selectors; | ||
/// @notice The list of `PredicateType` for each request. | ||
PredicateType[] predicateTypes; | ||
Comment on lines
+21
to
+22
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 don't think we need this. Also, if we do this should be in |
||
/// @notice Root of the Merkle tree committing to the set of proven claims. | ||
/// @dev In the case of a batch of size one, this may simply be the eip712Digest of the `AssessorCommitment`. | ||
bytes32 root; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright 2025 RISC Zero, Inc. | ||
// | ||
// Use of this source code is governed by the Business Source License | ||
// as found in the LICENSE-BSL file. | ||
pragma solidity ^0.8.24; | ||
|
||
using CallbackDataLibrary for CallbackData global; | ||
|
||
/// @title Callback Struct and Library | ||
/// @notice Represents a callback configuration for proof delivery | ||
struct CallbackData { | ||
/// @notice Image ID of the guest that was verifiably executed to satisfy the request. | ||
bytes32 imageId; | ||
/// @notice Journal committed by the guest program execution. | ||
/// @dev The journal is checked to satisfy the predicate specified on the request's requirements. | ||
bytes journal; | ||
} | ||
|
||
library CallbackDataLibrary {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
pragma solidity ^0.8.20; | ||
|
||
import {RequestId} from "./RequestId.sol"; | ||
import {PredicateType} from "./Predicate.sol"; | ||
|
||
using FulfillmentLibrary for Fulfillment global; | ||
|
||
|
@@ -15,16 +16,14 @@ struct Fulfillment { | |
RequestId id; | ||
/// @notice EIP-712 digest of request struct. | ||
bytes32 requestDigest; | ||
/// @notice Image ID of the guest that was verifiably executed to satisfy the request. | ||
/// @dev Must match the value in the request's requirements. | ||
bytes32 imageId; | ||
// TODO: Add a flag in the request to decide whether to post the journal. Note that | ||
// if the journal and journal digest do not need to be delivered to the client, imageId will | ||
// be replaced with claim digest, since it is captured in the requirements on the request, | ||
// checked by the Assessor guest. | ||
/// @notice Journal committed by the guest program execution. | ||
/// @dev The journal is checked to satisfy the predicate specified on the request's requirements. | ||
bytes journal; | ||
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. Ultimately, I think removing the journal from the |
||
/// @notice The `PredicateType` of the request that is being fulfilled. | ||
/// @dev When the `PredicateType` is `ClaimDigestMatch`, the imageIdOrClaimDigest field is the claim digest, | ||
/// and otherwise it is the image ID of the guest that was executed. | ||
ec2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
PredicateType predicateType; | ||
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. Related to my other comments, I think we can remove this. |
||
/// @notice Claim Digest | ||
bytes32 claimDigest; | ||
/// @notice The callback data, if requested. | ||
bytes callbackData; | ||
Comment on lines
+24
to
+25
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. Related to my other comments, this should come with the |
||
/// @notice Cryptographic proof for the validity of the execution results. | ||
/// @dev This will be sent to the `IRiscZeroVerifier` associated with this contract. | ||
bytes seal; | ||
|
Uh oh!
There was an error while loading. Please reload this page.