refactor CapRefresh

pull/19/head
Niko PLP 7 months ago
parent 3ae83bac3b
commit a90264e391
  1. 4
      ng-net/src/types.rs
  2. 29
      ng-repo/src/commit.rs
  3. 1
      ng-repo/src/object.rs
  4. 116
      ng-repo/src/types.rs
  5. 4
      ng-verifier/src/commits/mod.rs

@ -1258,8 +1258,8 @@ pub struct InnerOverlayLink {
/// The store has a special branch called `overlay` that is used to manage access to the InnerOverlay /// The store has a special branch called `overlay` that is used to manage access to the InnerOverlay
/// only the ReadCapSecret is needed to access the InnerOverlay /// only the ReadCapSecret is needed to access the InnerOverlay
/// the full readcap of this branch is needed in order to subscribe to the topic and decrypt the events. The branchId can be found in the branch Definition /// the full readcap of this branch is needed in order to subscribe to the topic and decrypt the events. The branchId can be found in the branch Definition
/// it can be useful to subscribe to this topic if the user is a member of the store's repo, so it will be notified of refreshReadCap on the overlay /// it can be useful to subscribe to this topic if the user is a member of the store's repo, so it will be notified of BranchCapRefresh on the overlay
/// if the user is an external user to the store, it will lose access to the InnerOverlay after a RefreshReadCap of the overlay branch of the store. /// if the user is an external user to the store, it will lose access to the InnerOverlay after a BranchCapRefresh of the overlay branch of the store.
pub store_overlay_readcap: ReadCap, pub store_overlay_readcap: ReadCap,
} }

@ -838,8 +838,8 @@ impl CommitBody {
CommitBodyV0::AddName(_) => true, CommitBodyV0::AddName(_) => true,
CommitBodyV0::RemoveName(_) => true, CommitBodyV0::RemoveName(_) => true,
//CommitBodyV0::Quorum(_) => true, //CommitBodyV0::Quorum(_) => true,
CommitBodyV0::RefreshReadCap(_) => true, CommitBodyV0::RootCapRefresh(_) => true,
CommitBodyV0::RefreshWriteCap(_) => true, CommitBodyV0::CapRefreshed(_) => true,
CommitBodyV0::SyncSignature(_) => true, CommitBodyV0::SyncSignature(_) => true,
CommitBodyV0::Delete(_) => true, CommitBodyV0::Delete(_) => true,
_ => false, _ => false,
@ -859,8 +859,8 @@ impl CommitBody {
CommitBodyV0::RemoveFile(_) => true, CommitBodyV0::RemoveFile(_) => true,
CommitBodyV0::Compact(_) => true, CommitBodyV0::Compact(_) => true,
CommitBodyV0::AsyncSignature(_) => true, CommitBodyV0::AsyncSignature(_) => true,
CommitBodyV0::RefreshReadCap(_) => true, CommitBodyV0::BranchCapRefresh(_) => true,
CommitBodyV0::RefreshWriteCap(_) => true, CommitBodyV0::CapRefreshed(_) => true,
CommitBodyV0::SyncSignature(_) => true, CommitBodyV0::SyncSignature(_) => true,
_ => false, _ => false,
}, },
@ -921,8 +921,8 @@ impl CommitBody {
//CommitBodyV0::Quorum(_) => true, //CommitBodyV0::Quorum(_) => true,
CommitBodyV0::Compact(_) => true, CommitBodyV0::Compact(_) => true,
CommitBodyV0::SyncTransaction(_) => true, // check Quorum::TotalOrder in CommitContent CommitBodyV0::SyncTransaction(_) => true, // check Quorum::TotalOrder in CommitContent
CommitBodyV0::RefreshReadCap(_) => true, CommitBodyV0::RootCapRefresh(_) => true,
CommitBodyV0::RefreshWriteCap(_) => true, CommitBodyV0::BranchCapRefresh(_) => true,
_ => false, _ => false,
}, },
} }
@ -1003,8 +1003,15 @@ impl CommitBody {
PermissionV0::RemoveWritePermission, PermissionV0::RemoveWritePermission,
PermissionV0::Compact, PermissionV0::Compact,
], ],
CommitBodyV0::RefreshReadCap(_) => vec![PermissionV0::RefreshReadCap], CommitBodyV0::RootCapRefresh(_) => {
CommitBodyV0::RefreshWriteCap(_) => vec![PermissionV0::RefreshWriteCap], vec![PermissionV0::RefreshReadCap, PermissionV0::RefreshWriteCap]
}
CommitBodyV0::BranchCapRefresh(_) => {
vec![PermissionV0::RefreshReadCap, PermissionV0::RefreshWriteCap]
}
CommitBodyV0::CapRefreshed(_) => {
vec![PermissionV0::RefreshReadCap, PermissionV0::RefreshWriteCap]
}
CommitBodyV0::Delete(_) => vec![], CommitBodyV0::Delete(_) => vec![],
CommitBodyV0::AddRepo(_) CommitBodyV0::AddRepo(_)
| CommitBodyV0::RemoveRepo(_) | CommitBodyV0::RemoveRepo(_)
@ -1397,9 +1404,9 @@ impl fmt::Display for CommitBody {
// //
// For both // For both
// //
// CommitBodyV0::RefreshReadCap(b) => write!(f, "RefreshReadCap {}", b), // CommitBodyV0::RootCapRefresh(b) => write!(f, "RootCapRefresh {}", b),
// CommitBodyV0::RefreshWriteCap(b) => { // CommitBodyV0::BranchCapRefresh(b) => {
// write!(f, "RefreshWriteCap {}", b) // write!(f, "BranchCapRefresh {}", b)
// } // }
CommitBodyV0::SyncSignature(b) => write!(f, "SyncSignature {}", b), CommitBodyV0::SyncSignature(b) => write!(f, "SyncSignature {}", b),
//CommitBodyV0::AddRepo(b) => write!(f, "AddRepo {}", b), //CommitBodyV0::AddRepo(b) => write!(f, "AddRepo {}", b),

@ -968,6 +968,7 @@ impl fmt::Display for ObjectContent {
ObjectContentV0::RandomAccessFileMeta(c) => { ObjectContentV0::RandomAccessFileMeta(c) => {
("RandomAccessFileMeta", format!("{}", "")) ("RandomAccessFileMeta", format!("{}", ""))
} }
ObjectContentV0::RefreshCap(c) => ("RefreshCap", format!("{}", "")),
}, },
), ),
}; };

@ -1103,7 +1103,7 @@ pub struct RootBranchV0 {
/// can only be committed by an owner /// can only be committed by an owner
/// it generates a new certificate /// it generates a new certificate
/// owners are not inherited from store /// owners are not inherited from store
// TODO: ReadCap or PermaCap. If it is a ReadCap, a new RootBranch commit should be published (RefreshReadCap) every time the store read cap changes. // TODO: ReadCap or PermaCap. If it is a ReadCap, a new RootBranch commit should be published (RootCapRefresh, only read_cap changes) every time the store read cap changes.
/// empty for private repos, eventhough they are all implicitly inheriting perms from private store /// empty for private repos, eventhough they are all implicitly inheriting perms from private store
pub inherit_perms_users_and_quorum_from_store: Option<ReadCap>, pub inherit_perms_users_and_quorum_from_store: Option<ReadCap>,
@ -1200,7 +1200,7 @@ impl fmt::Display for RootBranch {
/// Quorum definition V0 /// Quorum definition V0
/// ///
/// Changed when the signers need to be updated. Signers are not necessarily editors of the repo, and they do not need to be members either, as they will be notified of RefreshReadCaps anyway. /// Changed when the signers need to be updated. Signers are not necessarily editors of the repo, and they do not need to be members either, as they will be notified of RootCapRefresh anyway.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct QuorumV0 { pub struct QuorumV0 {
/// Number of signatures required for a partial order commit to be valid (threshold+1) /// Number of signatures required for a partial order commit to be valid (threshold+1)
@ -1464,8 +1464,8 @@ pub enum PermissionV0 {
RemoveBranch, // can send removeBranch, always behind SyncSignature RemoveBranch, // can send removeBranch, always behind SyncSignature
ChangeName, // can send AddName and RemoveName ChangeName, // can send AddName and RemoveName
RefreshReadCap, // can send RefreshReadCap followed by UpdateRootBranch and/or UpdateBranch commits, with or without renewed topicIds. Always behind SyncSignature RefreshReadCap, // can send RootCapRefresh or BranchCapRefresh that do not contain a write_cap, followed by UpdateRootBranch and/or UpdateBranch commits, with or without renewed topicIds. Always behind SyncSignature
RefreshWriteCap, // can send RefreshWriteCap followed by UpdateRootBranch and associated UpdateBranch commits on all branches, with renewed topicIds and RepoWriteCapSecret. Always behind SyncSignature RefreshWriteCap, // can send RootCapRefresh that contains a write_cap and associated BranchCapRefreshes, followed by UpdateRootBranch and associated UpdateBranch commits on all branches, with renewed topicIds and RepoWriteCapSecret. Always behind SyncSignature
// //
// permissions delegated by owners: // permissions delegated by owners:
@ -1479,7 +1479,7 @@ pub enum PermissionV0 {
Inbox, // can read inbox Inbox, // can read inbox
PermaShare, // can create and answer to PermaCap (PermaLink) PermaShare, // can create and answer to PermaCap (PermaLink)
UpdateStore, // only for store root repo (add repo, remove repo) to the store special branch UpdateStore, // only for store root repo (add repo, remove repo) to the store special branch
RefreshOverlay, // Equivalent to RefreshReadCap for the overlay special branch. RefreshOverlay, // Equivalent to BranchCapRefresh for the overlay special branch.
} }
/// Add permission to a member in a repo /// Add permission to a member in a repo
@ -1911,7 +1911,7 @@ impl AsyncSignature {
/// ///
/// points to the new Signature Object /// points to the new Signature Object
/// based on the total order quorum (or owners quorum) /// based on the total order quorum (or owners quorum)
/// mandatory for UpdateRootBranch, UpdateBranch, some AddBranch, RemoveBranch, RemoveMember, RemovePermission, Quorum, Compact, sync Transaction, RefreshReadCap, RefreshWriteCap /// mandatory for UpdateRootBranch, UpdateBranch, some AddBranch, RemoveBranch, RemoveMember, RemovePermission, Quorum, Compact, sync Transaction, RootCapRefresh, BranchCapRefresh
/// DEPS: the last signed commit in chain /// DEPS: the last signed commit in chain
/// ACKS: previous head before the chain of signed commit(s). should be identical to the HEADS (marked as DEPS) of first commit in chain /// ACKS: previous head before the chain of signed commit(s). should be identical to the HEADS (marked as DEPS) of first commit in chain
// #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] // #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
@ -1943,52 +1943,92 @@ impl fmt::Display for SyncSignature {
} }
} }
/// RefreshReadCap. renew the ReadCap of a `transactional` branch, or the root_branch, or all transactional branches and the root_branch. /// the second tuple member is only set when a write_cap refresh is performed, and for users that are Editor (any Member that also has at least one permission, plus all the Owners)
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct RefreshSecretV0(SymKey, Option<SymKey>);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct RefreshCapV0 {
/// an ordered list of user IDs, with their corresponding crypto_box of a RefreshSecretV0.
/// A User ID for each Member, Signer and Owner of the repo (except the one that is being excluded, if any)
/// the ordering is important as it allows receivers to perform a binary search on the array (searching for their own ID)
/// the refresh secret is used for encrypting the SyncSignature commit's key in the event sent in old topic (RefreshSecretV0.0) and for an optional write_cap refresh (RefreshSecretV0.1)
pub refresh_secret: Vec<(UserId, serde_bytes::ByteBuf)>,
}
/// RefreshCap
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum RefreshCap {
V0(RefreshCapV0),
}
/// RootCapRefresh. renew the capabilities of the root branch, or all transactional branches and the root_branch.
/// ///
/// Each branch forms its separate chain for that purpose. /// Each branch forms its separate chain for that purpose.
/// can refresh the topic ids, or not /// can refresh the topic ids, or not
/// DEPS: current HEADS in the branch at the moment of refresh. /// ACKS: current HEADS in the branch at the moment of refresh. DEPS to the previous RootBranch commit that will be superseded.
/// followed in the chain by a Branch or RootBranch commit (linked with ACK). The key used in EventV0 for the commit in the future of the RefreshReadCap, is the refresh_secret. /// the chain on the root_branch is : RootCapRefresh -> RemovePermission/RemoveMember -> UpdateRootBranch -> optional AddPermission(s) -> AddBranch x for each branch
/// the chain can be, by example: RefreshReadCap -> RootBranch -> AddBranch /// and on each transactional branch: BranchCapRefresh -> UpdateBranch
/// or for a transactional branch: RefreshReadCap -> Branch /// always eventually followed at the end of each chain by a SyncSignature (each branch its own).
/// always eventually followed at the end of each chain by a SyncSignature (each branch its own) /// The key used in EventV0 to encrypt the key for that SyncSignature commit is the refresh_secret (RefreshSecretV0.0).
///
/// On each new topic, the first commit (singleton) is a BranchCapRefreshed that contains internal references to the old branch (but no DEPS or ACKS).
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum RefreshReadCapV0 { pub struct RootCapRefreshV0 {
/// A randomly generated secret (SymKey) used for the refresh process, encrypted for each Member, Signer and Owner of the repo (except the one that is being excluded, if any) // ObjectRef to the RefreshCap object
/// format to be defined (see crypto_box) pub refresh_ref: ObjectRef,
RefreshSecret(),
// or a reference to a master RefreshReadCap commit when some transactional branches are refreshed together with the root_branch. the refresh_secret is taken from that referenced commit /// write cap encrypted with the refresh_secret RefreshSecretV0.1
MasterRefresh(ObjectRef), /// only allowed if the user has RefreshWriteCap permission
pub write_cap: Option<RepoWriteCapSecret>,
} }
/// RefreshReadCap ///
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum RefreshReadCap { pub enum RootCapRefresh {
V0(RefreshReadCapV0), V0(RootCapRefreshV0),
} }
/// RefreshWriteCap is always done on the root_branch, and always refreshes all the transaction branches WriteCaps, and TopicIDs. /// BranchCapRefresh renew the capabilities of one specific transactional branch
/// ///
/// DEPS: current HEADS in the branch at the moment of refresh. /// ACKS: current HEADS in the branch at the moment of refresh. DEPS to the previous Branch commit that will be superseded.
/// the chain on the root_branch is : RemovePermission/RemoveMember -> RefreshWriteCap -> RootBranch -> optional AddPermission(s) -> AddBranch /// the chain is, on the transactional branch: BranchCapRefresh -> UpdateBranch
/// and on each transactional branch: RefreshWriteCap -> Branch /// if this is an isolated branch refresh (not part of a rootcaprefresh), then the root branch chain is : AddBranch (ACKS to HEADS, quorumtype:TotalOrder )
/// always eventually followed at the end of each chain by a SyncSignature (each branch its own) /// always eventually followed at the end of each chain by a SyncSignature (each branch its own)
/// The key used in EventV0 to encrypt the key for that SyncSignature commit is the refresh_secret (RefreshSecretV0.0), but not on the root branch if it is an isolated branch refresh
///
/// On the new topic, the first commit (singleton) is a BranchCapRefreshed that contains internal references to the old branch (but no DEPS or ACKS).
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct BranchCapRefreshV0 {
/// ObjectRef to the RefreshCap object (shared with a root branch and other transac branches, or specially crafted for this branch if it is an isolated branch refresh)
pub refresh_ref: ObjectRef,
}
/// BranchCapRefresh
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct RefreshWriteCapV0 { pub enum BranchCapRefresh {
/// A RefreshReadCapV0::RefreshSecret when on the root_branch, otherwise on transactional branches, a RefreshReadCapV0::MasterRefresh pointing to this RefreshWriteCapV0 V0(BranchCapRefreshV0),
pub refresh_read_cap: RefreshReadCapV0, }
/// BranchCapRefreshed is a singleton in a new topic. it has no ACKS nor DEPS.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct BranchCapRefreshedV0 {
/// reference to the previous read_cap of the branch
pub continuation_of: ReadCap,
/// reference to the SyncSignature commit that did the refresh
pub refresh: ObjectRef,
/// the new RepoWriteCapSecret, encrypted for each Editor (any Member that also has at least one permission, plus all the Owners). See format of RefreshSecret /// reference to the UpdateBranch/UpdateRootBranch commit within the event of the SyncSignature
// TODO: format. should be encrypted pub new_read_cap: ReadCap,
// None when used for a transaction branch, as we don't want to duplicate this encrypted secret in each branch.
pub write_secret: Option<RepoWriteCapSecret>,
} }
/// RefreshWriteCap /// BranchCapRefreshed
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum RefreshWriteCap { pub enum BranchCapRefreshed {
V0(RefreshWriteCapV0), V0(BranchCapRefreshedV0),
} }
/// A Threshold Signature content /// A Threshold Signature content
@ -2156,6 +2196,7 @@ pub enum CommitBodyV0 {
Repository(Repository), // singleton and should be first in root_branch Repository(Repository), // singleton and should be first in root_branch
RootBranch(RootBranch), // singleton and should be second in root_branch RootBranch(RootBranch), // singleton and should be second in root_branch
UpdateRootBranch(RootBranch), // total order enforced with total_order_quorum UpdateRootBranch(RootBranch), // total order enforced with total_order_quorum
RootCapRefresh(RootCapRefresh), // total order enforced with total_order_quorum
AddMember(AddMember), // total order enforced with total_order_quorum AddMember(AddMember), // total order enforced with total_order_quorum
RemoveMember(RemoveMember), // total order enforced with total_order_quorum RemoveMember(RemoveMember), // total order enforced with total_order_quorum
AddPermission(AddPermission), AddPermission(AddPermission),
@ -2172,6 +2213,7 @@ pub enum CommitBodyV0 {
// For transactional branches: // For transactional branches:
// //
Branch(Branch), // singleton and should be first in branch Branch(Branch), // singleton and should be first in branch
BranchCapRefresh(BranchCapRefresh), // total order enforced with total_order_quorum
UpdateBranch(Branch), // total order enforced with total_order_quorum UpdateBranch(Branch), // total order enforced with total_order_quorum
Snapshot(Snapshot), // a soft snapshot Snapshot(Snapshot), // a soft snapshot
AsyncTransaction(Transaction), // partial_order AsyncTransaction(Transaction), // partial_order
@ -2186,8 +2228,7 @@ pub enum CommitBodyV0 {
// //
// For both // For both
// //
RefreshReadCap(RefreshReadCap), CapRefreshed(BranchCapRefreshed), // singleton and should be first in renewed branch
RefreshWriteCap(RefreshWriteCap),
SyncSignature(SyncSignature), SyncSignature(SyncSignature),
// //
@ -2436,6 +2477,7 @@ pub enum ObjectContentV0 {
Certificate(Certificate), Certificate(Certificate),
SmallFile(SmallFile), SmallFile(SmallFile),
RandomAccessFileMeta(RandomAccessFileMeta), RandomAccessFileMeta(RandomAccessFileMeta),
RefreshCap(RefreshCap),
} }
/// Immutable data stored encrypted in a Merkle tree /// Immutable data stored encrypted in a Merkle tree

@ -426,7 +426,7 @@ impl CommitVerifier for AsyncSignature {
} }
} }
impl CommitVerifier for RefreshReadCap { impl CommitVerifier for RootCapRefresh {
fn verify( fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -437,7 +437,7 @@ impl CommitVerifier for RefreshReadCap {
} }
} }
impl CommitVerifier for RefreshWriteCap { impl CommitVerifier for BranchCapRefresh {
fn verify( fn verify(
&self, &self,
commit: &Commit, commit: &Commit,

Loading…
Cancel
Save