-
Notifications
You must be signed in to change notification settings - Fork 0
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: starknet GMP (INTERNAL REVIEW) #57
base: main
Are you sure you want to change the base?
Conversation
// while let Some(result) = futures.next().await { | ||
// if !result { | ||
// panic!("expected conversion to fail for malformed event"); | ||
// } | ||
// } |
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.
old code?
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.
// while let Some(result) = futures.next().await { | |
// if !result { | |
// panic!("expected conversion to fail for malformed event"); | |
// } | |
// } |
ampd/src/starknet/json_rpc.rs
Outdated
|
||
let event: Option<(Felt, ContractCallEvent)> = match receipt_with_block_info.receipt { | ||
TransactionReceipt::Invoke(tx) => { | ||
// NOTE: There should be only one ContractCall event per gateway tx |
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 is meant by gateway tx
? Because there can be many ContractCalls in a single tx
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.
not sure about your question, but there would be more ContractCalls only in scenario where within single transaction frame we call multiple times Gateway::ContractCall, no? otherwise it should be one event per transaction.
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.
Same question as Marcin. I believe we expect a single ContractCall per tx.
Is multicall what you're referring to and are you familiar with it's use case and if we should actually implement it?
I remember that Squid might need it, but I have no details on the matter.
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.
but there would be more ContractCalls only in scenario where within single transaction frame we call multiple times Gateway::ContractCall
Exactly, and based on the //NOTE:
comment I assume that this is not covered 😄
Multicall is one example.
Another example would be ITS, which allows to call arbitrary contracts upon token bridiging with a custom payload (all within the same tx), these contracts can be user-made contracts, or even the Multicall contract that calls the Gateway eg 3x times. What if I want to send 10 memo messages from starknet to EVM by only having to sign & send a single tx on Starknet 😄
summary: I don't think any of the implementations (evm, Solana, multiversx) assume that there would be only a single ContractCall event per on-chain tx, and I dont think you should assume that too.
/// | ||
/// # Type Parameters | ||
/// * `C` - A Starknet client type that implements the [`StarknetClient`] trait | ||
#[allow(dead_code)] |
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.
#[allow(dead_code)] |
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, left some comments
ampd/src/starknet/json_rpc.rs
Outdated
|
||
let event: Option<(Felt, ContractCallEvent)> = match receipt_with_block_info.receipt { | ||
TransactionReceipt::Invoke(tx) => { | ||
// NOTE: There should be only one ContractCall event per gateway tx |
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.
not sure about your question, but there would be more ContractCalls only in scenario where within single transaction frame we call multiple times Gateway::ContractCall, no? otherwise it should be one event per transaction.
use crate::handlers::starknet_verify_msg::Message; | ||
use crate::handlers::starknet_verify_verifier_set::VerifierSetConfirmation; | ||
|
||
/// Attempts to fetch the tx provided in `axl_msg.tx_id`. |
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 would add full Docs body
} | ||
} | ||
|
||
pub fn verify_verifier_set( |
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 would add full Docs body here as well
/// Error returned when a required signers hash is missing from a | ||
/// transaction. | ||
#[error("missing signers hash for transaction")] | ||
MissingSignersHash, | ||
|
||
/// Error returned when payload data cannot be parsed correctly. | ||
#[error("failed to parse payload data, error: {0}")] | ||
FailedToParsePayloadData(String), | ||
|
||
/// Error returned when the payload data is missing. | ||
#[error("missing payload data for transaction")] | ||
MissingPayloadData, | ||
|
||
/// Error returned when the epoch number in a transaction is invalid or | ||
/// unexpected. | ||
#[error("incorrect epoch for transaction")] | ||
IncorrectEpoch, | ||
|
||
/// Error returned when the first key doesn't correspod to the | ||
/// SignersRotated event. | ||
#[error("not a SignersRotated event")] | ||
InvalidEvent, | ||
|
||
/// Error returned when the threshold in a transaction is invalid or | ||
/// unexpected. | ||
#[error("incorrect threshold for transaction")] | ||
IncorrectThreshold, | ||
|
||
/// Error returned when the nonce in a transaction is missing. | ||
#[error("missing nonce for transaction")] | ||
MissingNonce, | ||
|
||
/// Error returned when the keys in a transaction are missing. | ||
#[error("missing keys for transaction")] | ||
MissingKeys, | ||
} |
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.
the empty lines between arent needed
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.
/// Error returned when a required signers hash is missing from a | |
/// transaction. | |
#[error("missing signers hash for transaction")] | |
MissingSignersHash, | |
/// Error returned when payload data cannot be parsed correctly. | |
#[error("failed to parse payload data, error: {0}")] | |
FailedToParsePayloadData(String), | |
/// Error returned when the payload data is missing. | |
#[error("missing payload data for transaction")] | |
MissingPayloadData, | |
/// Error returned when the epoch number in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect epoch for transaction")] | |
IncorrectEpoch, | |
/// Error returned when the first key doesn't correspod to the | |
/// SignersRotated event. | |
#[error("not a SignersRotated event")] | |
InvalidEvent, | |
/// Error returned when the threshold in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect threshold for transaction")] | |
IncorrectThreshold, | |
/// Error returned when the nonce in a transaction is missing. | |
#[error("missing nonce for transaction")] | |
MissingNonce, | |
/// Error returned when the keys in a transaction are missing. | |
#[error("missing keys for transaction")] | |
MissingKeys, | |
} | |
/// Error returned when a required signers hash is missing from a | |
/// transaction. | |
#[error("missing signers hash for transaction")] | |
MissingSignersHash, | |
/// Error returned when payload data cannot be parsed correctly. | |
#[error("failed to parse payload data, error: {0}")] | |
FailedToParsePayloadData(String), | |
/// Error returned when the payload data is missing. | |
#[error("missing payload data for transaction")] | |
MissingPayloadData, | |
/// Error returned when the epoch number in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect epoch for transaction")] | |
IncorrectEpoch, | |
/// Error returned when the first key doesn't correspod to the | |
/// SignersRotated event. | |
#[error("not a SignersRotated event")] | |
InvalidEvent, | |
/// Error returned when the threshold in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect threshold for transaction")] | |
IncorrectThreshold, | |
/// Error returned when the nonce in a transaction is missing. | |
#[error("missing nonce for transaction")] | |
MissingNonce, | |
/// Error returned when the keys in a transaction are missing. | |
#[error("missing keys for transaction")] | |
MissingKeys, | |
} |
|
||
#[cfg(test)] | ||
mod tests { | ||
// use futures::stream::{FuturesUnordered, StreamExt}; |
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.
could be removed
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.
// use futures::stream::{FuturesUnordered, StreamExt}; |
.map_err(|err| ContractCallError::TryFromConversion(err.to_string()))? | ||
.into(); | ||
|
||
// It's + 3, because we need to offset the 0th element, pending_word and |
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's + 3, because we need to offset the 0th element, pending_word and | |
// it's + 3, because we need to offset the 0th element, pending_word and |
type Error = ArraySpanError; | ||
|
||
fn try_from(data: Vec<Felt>) -> Result<Self, Self::Error> { | ||
// First element is always the array length, which is a felt (so u8 is enough) |
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.
// First element is always the array length, which is a felt (so u8 is enough) | |
// first element is always the array length, which is a felt (so u8 is enough) |
|
||
let result = StarknetMessage::from_token(starknet_msg_token); | ||
|
||
// Tested like this, because InvalidOutputType doesn't implement PartialEq |
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.
// Tested like this, because InvalidOutputType doesn't implement PartialEq | |
// tested like this, because InvalidOutputType doesn't implement PartialEq |
|
||
let result = StarknetMessage::from_token(starknet_msg_token); | ||
|
||
// Tested like this, because InvalidOutputType doesn't implement PartialEq |
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.
// Tested like this, because InvalidOutputType doesn't implement PartialEq | |
// tested like this, because InvalidOutputType doesn't implement PartialEq |
|
||
let result = StarknetMessage::from_token(starknet_msg_token); | ||
|
||
// Tested like this, because InvalidOutputType doesn't implement PartialEq |
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.
// Tested like this, because InvalidOutputType doesn't implement PartialEq | |
// tested like this, because InvalidOutputType doesn't implement PartialEq |
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.
LGTM2 left suggestions
/// Error returned when a required signers hash is missing from a | ||
/// transaction. | ||
#[error("missing signers hash for transaction")] | ||
MissingSignersHash, | ||
|
||
/// Error returned when payload data cannot be parsed correctly. | ||
#[error("failed to parse payload data, error: {0}")] | ||
FailedToParsePayloadData(String), | ||
|
||
/// Error returned when the payload data is missing. | ||
#[error("missing payload data for transaction")] | ||
MissingPayloadData, | ||
|
||
/// Error returned when the epoch number in a transaction is invalid or | ||
/// unexpected. | ||
#[error("incorrect epoch for transaction")] | ||
IncorrectEpoch, | ||
|
||
/// Error returned when the first key doesn't correspod to the | ||
/// SignersRotated event. | ||
#[error("not a SignersRotated event")] | ||
InvalidEvent, | ||
|
||
/// Error returned when the threshold in a transaction is invalid or | ||
/// unexpected. | ||
#[error("incorrect threshold for transaction")] | ||
IncorrectThreshold, | ||
|
||
/// Error returned when the nonce in a transaction is missing. | ||
#[error("missing nonce for transaction")] | ||
MissingNonce, | ||
|
||
/// Error returned when the keys in a transaction are missing. | ||
#[error("missing keys for transaction")] | ||
MissingKeys, | ||
} |
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.
/// Error returned when a required signers hash is missing from a | |
/// transaction. | |
#[error("missing signers hash for transaction")] | |
MissingSignersHash, | |
/// Error returned when payload data cannot be parsed correctly. | |
#[error("failed to parse payload data, error: {0}")] | |
FailedToParsePayloadData(String), | |
/// Error returned when the payload data is missing. | |
#[error("missing payload data for transaction")] | |
MissingPayloadData, | |
/// Error returned when the epoch number in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect epoch for transaction")] | |
IncorrectEpoch, | |
/// Error returned when the first key doesn't correspod to the | |
/// SignersRotated event. | |
#[error("not a SignersRotated event")] | |
InvalidEvent, | |
/// Error returned when the threshold in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect threshold for transaction")] | |
IncorrectThreshold, | |
/// Error returned when the nonce in a transaction is missing. | |
#[error("missing nonce for transaction")] | |
MissingNonce, | |
/// Error returned when the keys in a transaction are missing. | |
#[error("missing keys for transaction")] | |
MissingKeys, | |
} | |
/// Error returned when a required signers hash is missing from a | |
/// transaction. | |
#[error("missing signers hash for transaction")] | |
MissingSignersHash, | |
/// Error returned when payload data cannot be parsed correctly. | |
#[error("failed to parse payload data, error: {0}")] | |
FailedToParsePayloadData(String), | |
/// Error returned when the payload data is missing. | |
#[error("missing payload data for transaction")] | |
MissingPayloadData, | |
/// Error returned when the epoch number in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect epoch for transaction")] | |
IncorrectEpoch, | |
/// Error returned when the first key doesn't correspod to the | |
/// SignersRotated event. | |
#[error("not a SignersRotated event")] | |
InvalidEvent, | |
/// Error returned when the threshold in a transaction is invalid or | |
/// unexpected. | |
#[error("incorrect threshold for transaction")] | |
IncorrectThreshold, | |
/// Error returned when the nonce in a transaction is missing. | |
#[error("missing nonce for transaction")] | |
MissingNonce, | |
/// Error returned when the keys in a transaction are missing. | |
#[error("missing keys for transaction")] | |
MissingKeys, | |
} |
|
||
#[tokio::test] | ||
async fn test_try_from_event_randomly_malformed_data_x1000() { | ||
// let mut futures = FuturesUnordered::new(); |
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.
// let mut futures = FuturesUnordered::new(); |
keys: event.keys, | ||
}); | ||
assert!(result.is_err()); | ||
// }); |
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 field, should not exceed 252 bits (a felt's length) | ||
let destination_chain = parse_cairo_short_string(&event.keys[1])?; | ||
|
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 about using &event.keys.get(1).expect("I expected this key")
?
No description provided.