-
Notifications
You must be signed in to change notification settings - Fork 161
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: add signature verification for delegated accounts #5255
feat: add signature verification for delegated accounts #5255
Conversation
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. Some technical comments, otherwise LGTM.
src/shim/crypto.rs
Outdated
if addr.protocol() != Delegated { | ||
return Err(format!( | ||
"cannot validate a delegated signature against a {} address expected", | ||
addr.protocol(), | ||
)); | ||
} | ||
|
||
if signature.len() != SECP_SIG_LEN { | ||
return Err(format!( | ||
"invalid delegated signature length. Was {}, must be {}", | ||
signature.len(), | ||
SECP_SIG_LEN | ||
)); | ||
} |
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.
nit: there's a nice macro anyhow::ensure
that makes such validations more expressive.
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.
Done.
src/shim/crypto.rs
Outdated
signature: &[u8], | ||
data: &[u8], | ||
addr: &crate::shim::address::Address, | ||
) -> Result<(), String> { |
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's use anyhow::Result<()>
. String
itself should rarely be an error class.
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 then we will have to refactor existing functions: as you can see here.
Also the fvm_shared: verify_bls_sig
, verify_secp256k1_sig
returns Result<(), String>
.
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.
Yes, it would need to be refactored, and it would be a good change. From briefly looking at the calls, it shouldn't be too complex.
The functions from fvm_shared
should also be refactored (historical trivia: those were likely copied from Forest in 2021). However, given that it's a library's public interface, they should rather use a more constrained error type enumeration. Of course, refactoring ref-fvm
methods is out of the scope of this issue, but it might be interesting to do so in the future.
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.
If that's the case then I will update the existing verify function to use anyhow
and we can raise a separate issue for updating ref_evm
functions.
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.
Excellent, thanks @akaladarshi!
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.
Done.
src/shim/crypto.rs
Outdated
// check address against recovered address | ||
if rec_addr == *addr { | ||
Ok(()) | ||
} else { | ||
Err("Delegated signature verification failed".to_owned()) | ||
} |
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.
ensure!
could be used here as well.
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.
Done.
@akaladarshi You can enable "format on save" in your favorite editor to prevent those pesky linter errors. |
Either that or run Line 58 in ae5e424
|
@akaladarshi, did you try running the node locally with your changes? If you look at the logs for calibnet RPC checks for Forest, you will see:
|
@LesnyRumcajs Yeah it was mentioned in the issue as well, that we are able to verify the signature by comparing with lotus signature but while syncing it's failing #5242 (comment) |
I am looking into this behaviour only why it is happening. |
@LesnyRumcajs Based on my investigation, I found out that there were few issues in how we were processing Meanwhile I will try to add few unit tests for the new changes. |
@elmattic would you mind looking taking a look? |
Of course. |
@akaladarshi Looks like |
I am looking into adding more unit tests and fixing/updating existing once, just wanted to get few comments on the changes. |
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.
Great work, looks good. Just a few nits, and consider adding tests for functions like verify_delegated_sig
and authenticate_msg
.
There are also a few small typos to fix, it's
Search for occurrences of |
@elmattic one more thing, I guess test is failing because perviously we were checking |
@akaladarshi Great! Can you just fix the small lint error? Thanks! 🙏 |
src/key_management/wallet.rs
Outdated
let delegated_key_info = KeyInfo::new(SignatureType::Delegated, delegated_priv_key); | ||
let delegated_key = Key::try_from(delegated_key_info).unwrap(); | ||
let addr = delegated_key.address; | ||
println!("addr: {}", addr); |
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.
println!("addr: {}", addr); |
leftover?
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.
Removed.
src/shim/crypto.rs
Outdated
msg: &SignedMessage, | ||
addr: &crate::shim::address::Address, | ||
) -> anyhow::Result<()> { | ||
let mut sig = self.clone(); |
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.
Why do we need to clone the entire instance? Does it need to always be cloned?
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.
self is a Signature
itself, cloning it, so we can update the signature bytes in line 157
, without actually affecting the self.
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.
You can use this syntax as well, which is a bit more idiomatic too: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax
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.
match self.sig_type {
SignatureType::Delegated => {
...
let sig = Signature {
bytes: eth_tx.to_verifiable_signature(Vec::from(self.bytes()), eth_chain_id)?,
..*self
};
let digest = eth_tx.rlp_unsigned_message(eth_chain_id)?;
sig.verify(&digest, addr)
}
_ => {
let digest = msg.message().cid().to_bytes();
self.verify(&digest, addr)
}
}
@elmattic are you talking about something like 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.
Let me re-phrase. Do you think cloning (a relatively costly operation; you need to heap-allocate the entire vector) is necessary in case the signature type is not Delegated
(which is the case most of the time)?
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.
are you talking about something like this ?.
Yes, that's it, this will only clone in case of Delegated
sig. and doing ..*self
should be cheap here.
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.
@LesnyRumcajs Thanks for pointing it out, I think you're right it doesn't make sense at all. I will update it as per my last comment.
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, thanks!
Summary of changes
Changes introduced in this pull request:
Reference issue to close (if applicable)
Closes #5242
Other information and links
Change checklist