-
Notifications
You must be signed in to change notification settings - Fork 11.4k
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
[fastx client] Add logic for a client to sync a cert to an authority, and two authorities. #285
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.
This is a superb example of the flow for relying on another authority to backfill a late one. Yet it only explores its happy path (none of the authorities are byzantine and the source authority has all we need).
So here's the ask: should it be part of the client's public API ? Should it be an integration test? example?
Should it rather be package-private, and then reused for the client to build more complex logic? (which seems to be where #252 is going?)
// Note: this should never be true in prod, but some tests | ||
// (test_handle_confirmation_order_bad_sequence_number) do | ||
// a poor job of setting up the DB. |
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.
Should we open an issue for that?
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.
Ok we can just kill the broken test.
// Put back the target cert | ||
missing_certificates.push(target_cert); | ||
|
||
for object_ref in input_objects { |
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.
Do we need to require every parent certificate from the authority, or could it be that we're just missing one or two? Could we find out by inspecting FastPayError::MissingEarlierConfirmations
?
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.
Right now, sadly, the authority does not provide us in one shot with all missing objects. Probably we should re-factor to do that (the information is there and already read from the DB).
@huitseeker & @sblackshear Thanks for the early feedback -- I am still working on the todos here, but very useful to get these comments in early. |
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.
Main comment: let's have a place to embed witnesses of byzantine behavior in the byzantine authority error.
#[error( | ||
"We have received cryptographic level of evidence that authority {authority:?} is faulty in a Byzantine manner." | ||
)] | ||
ByzantineAuthoritySuspicion { authority: AuthorityName }, |
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 strongly believe this should embed the error and the data assets that triggered raising this.
The reason why is because those assets should end up in arbitration, something I can tokio-tracing
around, but only if I have the assets in question.
In concrete terms, that means this enum variant should include ByzantineAuthoritySuspicion { authority: AuthorityName, error:
dyn Error + Send + Sync }`.
If that's impossible (e.g. because we require a flurry of traits on FastPayError
), we should at least embed the error.display()
string that triggered 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.
Yeah, I like this idea. We should think how to do this, since the nature of the data may be different for different forms of evidence.
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.
#[derive(Debug, thiserror::Error)]
pub enum FastPayError {
....
#[error("A terrible error showed byzantine behavior {0}")]
ByzantineError(#[from] EmbeddedError),
}
impl From<FooError> for FastPayError {
fn from(error: FooError) -> Self {
Self::ByzantineError(EmbeddedError(error.into()))
}
}
impl From<BarError> for FastPayError {
fn from(error: BarError) -> Self {
Self::ByzantineError(EmbeddedError(error.into()))
}
}
...
/// An error that occured when checking for correct behavior
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct EmbeddedError(
Box<dyn std::error::Error + Send + Sync>,
);
This should cover it for a start, then there's Hash
+ Eq
+ Serialize
+ Deserialize
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 is nice! Lets open an issue to do this, and try to fix the critical correctness bugs in the client beforehand.
47125dd
to
7af1690
Compare
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.
Tip top! I've opened #301
@gdanezis thanks for this and the extensive comments on the functions! |
This addresses issue #252
Out of scope for the moment: