AirgapTransactionError type from blockstore#6434
AirgapTransactionError type from blockstore#6434steveluscher merged 2 commits intoanza-xyz:masterfrom
TransactionError type from blockstore#6434Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6434 +/- ##
=========================================
- Coverage 82.8% 82.8% -0.1%
=========================================
Files 847 847
Lines 379486 379535 +49
=========================================
+ Hits 314509 314547 +38
- Misses 64977 64988 +11 🚀 New features to boost your workflow:
|
3a6803d to
fb5c61e
Compare
joncinque
left a comment
There was a problem hiding this comment.
Makes sense to me! Confirming that the current generated::TransactionError is just a Vec<u8> currently, so the new type allows us to easily customize serde without any impact on sdk users.
Please get approval from at least one of the other reviewers before merging.
|
|
||
| impl From<TransactionError> for generated::TransactionError { | ||
| fn from(value: TransactionError) -> Self { | ||
| let stored_error = Into::<StoredTransactionError>::into(value).0; |
There was a problem hiding this comment.
nit: this might just be me, but I prefer using from instead of all the Intos
| let stored_error = Into::<StoredTransactionError>::into(value).0; | |
| let stored_error = StoredTransactionError::from(value).0; |
| impl From<StoredTransactionError> for TransactionError { | ||
| fn from(value: StoredTransactionError) -> Self { | ||
| let bytes = value.0; | ||
| bincode::deserialize::<Self>(&bytes).expect("transaction error to deserialize from bytes") |
There was a problem hiding this comment.
nit: is the Self needed here? I think the compiler should be able to figure it out
| bincode::deserialize::<Self>(&bytes).expect("transaction error to deserialize from bytes") | |
| bincode::deserialize(&bytes).expect("transaction error to deserialize from bytes") |
|
How does this look, @steviez? |
I'll try to take a look in the next day or two; sorry for the delay and appreciate your patience |
steviez
left a comment
There was a problem hiding this comment.
Finally got around to looking at this. The general idea of the change makes sense.
I'm having to brush off some cobwebs to remember how all this stuff is hooked up so please bear with me on these questions 😅
Is this line below problematic ? Namely, we're invoking serialize() directly, but should we be using one of the From implementations ?
agave/storage-proto/src/convert.rs
Lines 426 to 431 in ffc8065
And is StoredTransactionError wired up to anything yet ? Should it be connected to this type ?
agave/storage-proto/src/lib.rs
Lines 177 to 178 in ffc8065
Yeesh. It does look as though I missed that. All this code used to be in one PR. PR splitting gone wrong. I'll finish this up next week. |
Problem
At present, we leak the serialization format of
TransactionErrorstraight into blockstore. Any change to the serialization format ofTransactionError(this being an example) could change the bytes that are stored in blockstore. A change in that serialization could cause old validator clients to fail to load transaction errors stored by newer clients, and vice versa.Summary of Changes
In this PR, we create an ‘airgap’ –
StoredTransactionbetweenTransactionErrorand the type that is serialized for storage in blockstore.This provides a locus for custom serialization logic. Now you can conceive of a change to the structure of
TransactionErrorthat can be handled by the custom serialization logic to produce bytes that are backward compatible with old validator clients, and you can create deserialization logic that handles bytes stored by older validator clients.We also add tests to verify that the current serialization format for named, struct, tuple, and particularly
InstructionErrorvariants ofTransactionErrordon't change without a test breaking.This is a prerequisite for #6083