-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Private contract migration and offchain state sync #10748
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.
Never reviewed anything private-tx related before, so left few questions/comments. Will do a final review once they're answered/addressed.
|
||
/// Wrapper over storage for the private states | ||
pub struct PrivateStateStorage { | ||
verification_requests: RwLock<Vec<Arc<VerifiedPrivateTransaction>>>, |
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 don't think you actually need so many RwLock
s - all the data seems to be logically connected. Like in this code:
(1) self.state_storage.state_sync_completed(hash);
(2) if self.state_storage.current_sync_state() == SyncState::Idle {
trace!(target: "privatetx", "Private state sync completed, processing pending requests");
(3) let creation_requests = self.state_storage.drain_creation_queue();
there are 3 calls which are using 3 different RwLock
. And, for example, if check (2) passes (i.e. the state is Idle
) and before line (3) someone adds more states to sync, drain_*()
calls could actually return these new requests, for which states are missing => tx sign/verification will fail.
So probably reconsider API to avoid such issues (and leave <= 1 internal lock)?
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.
Reworked. 2 locks are left. The second one is needed for stalling requests logic implementation (in order to keep currently processed hashes in the separate structure)
40150d4
to
aa5089a
Compare
aa5089a
to
165fc29
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.
The logic looks ok to me, although I've never reviewed anything private-tx related before too.
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
let current_time = Instant::now(); | ||
syncing_hashes | ||
.iter() | ||
.filter(|&(_, expiration_time)| *expiration_time >= current_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.
Not an issue, but probably some optimization for future PRs - there's a LinkedHashMap
struct - I've used it in similar cases (for detecting stale requests) to avoid iterating the whole HashMap
.
c5def9b
to
ad000e3
Compare
1.1) Client can setup the private contract in order to store its state locally in DB and store its hash in the contact only. This allows to use unlimited amount of data in the private contract (see TODO section for temporal limitation)
1.2) Members, that have access to the private contract key, can be modified, new members can be added. In this case newly added members will request the state from the peers.
Usage of the offchain storage is regulated via command line startup flag --private-state-offchain. By default (if flag is not used) it's set to false (to use onchain storage).
Current private transactions usage scenarios were modified for the case of offchain storage
3.1) Private contract's deployment
If not all the states of private contracts required for the deployment available, deployment returns the error PrivateStateNotFound. Client has to repeat the procedure later (see TODO section for improvement of the usability)
3.2) Make changes in the private contract
Originator:
If some states are missing, originator's request saved, missing states requested
After receiving requested states, save them and fire stored originator's request
Verificator:
If during verification some states are not available, state requested and verification request saved.
After receiving actual state, save it and proceed with verification.
3.3) Read of the private state
If some state is not available, the same error is returned, client should try again later
Meanwhile state is requested, stored after retrieving
Closes #9198, closes #9201