-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Return reason of why proof cant be generated #2258
base: master
Are you sure you want to change the base?
Return reason of why proof cant be generated #2258
Conversation
In general my understanding is that breaking changes in graphQL are discouraged, and instead you can add a "no_proof_reason" field to the API. Third-party Applications will be able to use the service, but can update their clients to request the "no_proof_reason" field and handling it accordingly. Overall I don't have a strong opinion, and a breaking change might be okay in this case (I don't have enough context to say whether this is the case), just thought of mentioning the alternative |
@@ -970,7 +970,7 @@ type Query { | |||
""" | |||
owner: Address, first: Int, after: String, last: Int, before: String | |||
): MessageConnection! | |||
messageProof(transactionId: TransactionId!, nonce: Nonce!, commitBlockId: BlockId, commitBlockHeight: U32): MessageProof | |||
messageProof(transactionId: TransactionId!, nonce: Nonce!, commitBlockId: BlockId, commitBlockHeight: U32): MessageProof! |
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.
@acerone85 @luizstacio @LuizAsFight is it a breaking change for you?
If yes, we can just always return Some(proof)
.
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.
This is not a breaking change for the TS SDK, we have null handling but it'll just be redundant.
Not sure about the FE apps though as they do have some custom GQL logic.
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.
no breaking change on FE side
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.
Thanks for the feedback, I'm removing the "breaking" label then.
// Check if we found a leaf. | ||
let Some(proof_index) = proof_index else { | ||
return Err(anyhow::anyhow!("unable to find leaf").into()) | ||
}; | ||
|
||
// Get the proof set. | ||
let Some((_, proof_set)) = tree.prove(proof_index) else { | ||
return Err(anyhow::anyhow!("unable to get proof set").into()); | ||
}; |
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.
It would be nice to get more information during which operation you we got an error
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.
We can consider getting rid of the ok()
here and provide details carried over in MerkleTreeError
.
Is this what you meant?
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.
As agreed, the comment was about using more user-friendly error messages. Updated in Updated in 2199e87.
let Some(block) = database | ||
.block(&block_height) | ||
.into_api_result::<CompressedBlock, StorageError>()? |
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.
I like old naming for vairables more=)
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.
message_block
and message_block_height
are back in 0c2dbc5
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.
What do you think about starting the error message with capital letters?=)
I prefer lowercase mostly because they are usually a part of bigger sentences - and it reads better without a capital letter in the middle of a message. But after all, there's a merit in having consistent error messages. I see that we mostly use uppercase with just a few exceptions. |
…f_cant_be_generated' into 1394_return_reason_of_why_proof_cant_be_generated
_ => return Ok(None), | ||
.into_api_result::<TransactionStatus, StorageError>()? | ||
else { | ||
return Err(anyhow::anyhow!("unable to obtain block height").into()) |
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.
return Err(anyhow::anyhow!("unable to obtain block height").into()) | |
return Err(anyhow::anyhow!("Unable to obtain the message block height").into()) |
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.
Updated in 2199e87
Some(r) => r, | ||
None => return Ok(None), | ||
let Some(data) = data else { | ||
return Err(anyhow::anyhow!("output message doesn't contain any `data`").into()) |
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.
return Err(anyhow::anyhow!("output message doesn't contain any `data`").into()) | |
return Err(anyhow::anyhow!("Output message doesn't contain any `data`").into()) |
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.
Updated in 2199e87
}); | ||
}) | ||
.ok_or::<StorageError>( | ||
anyhow::anyhow!("desired `nonce` missing in transaction receipts").into(), |
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.
anyhow::anyhow!("desired `nonce` missing in transaction receipts").into(), | |
anyhow::anyhow!("Desired `nonce` missing in transaction receipts").into(), |
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.
Updated in 2199e87
) -> StorageResult<Option<MessageProof>> { | ||
// Check if the receipts for this transaction actually contain this message id or exit. | ||
let receipt = database | ||
) -> StorageResult<MessageProof> { |
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.
I think the error should be anyhow since part of the error are not from the storage
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.
I agree the error structure is a little off. We might also take this opportunity and reconsider having Other(anyhow::Error)
variant inside the fuel_core_storage::Error
enum.
I'm keen to create a follow-up issue for this.
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.
Follow-up: #2291
Some(t) => t.into_inner(), | ||
None => return Ok(None), | ||
else { | ||
return Err(anyhow::anyhow!("unable to get block from database").into()) |
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.
return Err(anyhow::anyhow!("unable to get block from database").into()) | |
return Err(anyhow::anyhow!("Unable to get the message block from the database").into()) |
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.
Updated in 2199e87
None => return Ok(None), | ||
else { | ||
return Err( | ||
anyhow::anyhow!("unable to get commit block header from database").into(), |
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.
anyhow::anyhow!("unable to get commit block header from database").into(), | |
anyhow::anyhow!("Unable to get commit block header from database").into(), |
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.
Updated in 2199e87
let verifiable_commit_block_height = | ||
block_height.pred().expect("We checked the height above"); | ||
let Some(verifiable_commit_block_height) = commit_block_header.height().pred() else { | ||
return Err(anyhow::anyhow!("can not look beyond the genesis block").into()) |
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.
return Err(anyhow::anyhow!("can not look beyond the genesis block").into()) | |
return Err(anyhow::anyhow!("Impossible to generate proof beyond the genesis block").into()) |
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.
Updated in 2199e87
} | ||
|
||
fn message_receipts_proof<T: MessageProofData + ?Sized>( | ||
database: &T, | ||
message_id: MessageId, | ||
message_block_txs: &[Bytes32], | ||
) -> StorageResult<Option<MerkleProof>> { | ||
) -> StorageResult<MerkleProof> { | ||
// Get the message receipts from the block. | ||
let leaves: Vec<Vec<Receipt>> = message_block_txs | ||
.iter() |
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.
I think we can remove the usage of into_api_result
method in this file now since we have an error
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.
That's right. into_api_result
was used to disguise the NotFound
error as Ok(None)
. Currently we either have a proper value or a distinct error.
Updated in 10109c9
} | ||
// Check if we found a leaf. | ||
let Some(proof_index) = proof_index else { | ||
return Err(anyhow::anyhow!("unable to find leaf").into()) |
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.
return Err(anyhow::anyhow!("unable to find leaf").into()) | |
return Err(anyhow::anyhow!("Unable to find the message receipt in the transaction to generate the proof").into()) |
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.
Updated in 2199e87
|
||
// Get the proof set. | ||
let Some((_, proof_set)) = tree.prove(proof_index) else { | ||
return Err(anyhow::anyhow!("unable to get proof set").into()); |
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.
return Err(anyhow::anyhow!("unable to get proof set").into()); | |
return Err(anyhow::anyhow!("Unable to generate the Merkle proof for the message from its receipts").into()); |
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.
Updated in 2199e87
For the sake of consistency we'll use the capitalized error messages. |
…med a breaking change
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.
This commit should handle that: eee16f2 |
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.
Looks good to me, but let's merge it after release to avoid any potential problems with API=)
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.
LGTM. Happy to approve after release.
Closes #1394
Description
message_proof()
API is modified to return either the proof or an error with the description why the proof couldn't be created. Previously the reason was discarded by returningOk(None)
.Before requesting review