Skip to content
This repository was archived by the owner on Feb 28, 2021. It is now read-only.

Properly isolate and document core state entities #205

Merged
merged 2 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ members = [
"core",
"node",
"runtime",
"registry-spec",
"test-utils"
]
27 changes: 0 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ See [`DEVELOPING.md`][dev-manual] for developer information.
- [Account Keys](#account-keys)
- [Developing with the Client](#developing-with-the-client)
- [Using the CLI](#using-the-cli)
- [Registry Specification](#registry-specification)
- [License](#license)

<!-- tocstop -->
Expand Down Expand Up @@ -148,32 +147,6 @@ learn more run `cargo run -p radicle-registry-cli -- --help`.
[wasm-gc]: https://github.com/alexcrichton/wasm-gc


Registry Specification
--------------------

In the `registry-spec` folder, there is a Rust crate that details the Oscoin
registry specification with traits, types and a sizable amount of documentation.

It is intended to bridge the formal description of the registry from the
whitepaper with the registry's future implementation, providing a "sandbox"
with which to test and discuss design ideas before implementing them in
earnest.

The `registry-spec` crate is meant to evolve with the project, and at each point
in time its contents will reflect the team's requirements from and
understanding of the Oscoin registry.

Note that although there is no actual implementation of any function or
datatype in the crate, it compiles and is part of the build process.

### Structure

`registry-spec` is a library with three modules:
* `lib.rs`, defining the main traits with which to interact with the Oscoin
registry
* `error.rs` defining errors that may arise when interacting with the registry.
* `types.rs`, defining the primitive types that will populate the registry state.

License
-------

Expand Down
6 changes: 3 additions & 3 deletions client/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ pub trait ClientT {
) -> Result<Response<TransactionApplied<Message_>, Error>, Error>;

/// Fetch the nonce for the given account from the chain state
async fn account_nonce(&self, account_id: &AccountId) -> Result<Index, Error>;
async fn account_nonce(&self, account_id: &AccountId) -> Result<state::Index, Error>;

/// Return the gensis hash of the chain we are communicating with.
fn genesis_hash(&self) -> Hash;

async fn free_balance(&self, account_id: &AccountId) -> Result<Balance, Error>;

async fn get_project(&self, id: ProjectId) -> Result<Option<Project>, Error>;
async fn get_project(&self, id: ProjectId) -> Result<Option<state::Project>, Error>;

async fn list_projects(&self) -> Result<Vec<ProjectId>, Error>;

async fn get_checkpoint(&self, id: CheckpointId) -> Result<Option<Checkpoint>, Error>;
async fn get_checkpoint(&self, id: CheckpointId) -> Result<Option<state::Checkpoint>, Error>;
}
8 changes: 4 additions & 4 deletions client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,17 +208,17 @@ impl ClientT for Client {
self.backend.get_genesis_hash()
}

async fn account_nonce(&self, account_id: &AccountId) -> Result<Index, Error> {
async fn account_nonce(&self, account_id: &AccountId) -> Result<state::Index, Error> {
self.fetch_map_value::<frame_system::AccountNonce<Runtime>, _, _>(*account_id)
.await
}

async fn free_balance(&self, account_id: &AccountId) -> Result<Balance, Error> {
async fn free_balance(&self, account_id: &AccountId) -> Result<state::AccountBalance, Error> {
self.fetch_map_value::<balances::FreeBalance<Runtime>, _, _>(account_id.clone())
.await
}

async fn get_project(&self, id: ProjectId) -> Result<Option<Project>, Error> {
async fn get_project(&self, id: ProjectId) -> Result<Option<state::Project>, Error> {
self.fetch_map_value::<registry::store::Projects, _, _>(id)
.await
}
Expand All @@ -235,7 +235,7 @@ impl ClientT for Client {
Ok(project_ids)
}

async fn get_checkpoint(&self, id: CheckpointId) -> Result<Option<Checkpoint>, Error> {
async fn get_checkpoint(&self, id: CheckpointId) -> Result<Option<state::Checkpoint>, Error> {
self.fetch_map_value::<registry::store::Checkpoints, _, _>(id)
.await
}
Expand Down
18 changes: 7 additions & 11 deletions client/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,16 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

//! Provides [Transaction] and [TransactionExtra].
use crate::TxHash;
use core::marker::PhantomData;
use parity_scale_codec::Encode;
pub use radicle_registry_core::{AccountId, Balance, Project, ProjectId};
use radicle_registry_runtime::Hashing;
use radicle_registry_runtime::UncheckedExtrinsic;
pub use sp_core::crypto::{Pair as CryptoPair, Public as CryptoPublic};
pub use sp_core::ed25519;
use sp_runtime::generic::{Era, SignedPayload};
use sp_runtime::traits::Hash as _;
use sp_runtime::traits::SignedExtension;
use std::marker::PhantomData;
use sp_runtime::traits::{Hash as _, SignedExtension};

pub use crate::message::Message;
pub use radicle_registry_runtime::{Call as RuntimeCall, Hash, Index, SignedExtra};
use crate::{ed25519, message::Message, CryptoPair as _, TxHash};
use radicle_registry_core::state::Index;
use radicle_registry_runtime::{
Call as RuntimeCall, Hash, Hashing, SignedExtra, UncheckedExtrinsic,
};

#[derive(Clone, Debug)]
/// Transaction the can be submitted to the blockchain.
Expand Down
2 changes: 1 addition & 1 deletion client/tests/end_to_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async fn register_project() {
);

let checkpoint = client.get_checkpoint(checkpoint_id).await.unwrap().unwrap();
let checkpoint_ = Checkpoint {
let checkpoint_ = state::Checkpoint {
parent: None,
hash: project_hash,
};
Expand Down
18 changes: 18 additions & 0 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,21 @@ cover all edge cases. The documentation for a message has the following sections
<dd>Describes the validations that are required for the message to be applied
successfully and that depend on the current ledger state state.</dd>
</dd>

State
-----

All entities that are stored in the ledger state are defined in the `state`
module.

For each entity the documentation has the following sections

<dl>
<dt>Storage</dt>
<dd>Describes how the entity is stored in the state and how the state storage
key is calculated.</dd>
<dt>Invariants</dt>
<dd>Describes the invariants of the data in the state entity that always hold.</dd>
<dt>Relevant messages</dt>
<dd>Links to message types that effect or use the entity.</dd>
</dd>
32 changes: 4 additions & 28 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@

extern crate alloc;

use alloc::prelude::v1::*;

use parity_scale_codec::{Decode, Encode};
use sp_core::{ed25519, H256};
use sp_runtime::traits::BlakeTwo256;

pub use sp_runtime::DispatchError;

pub mod message;
pub mod state;

pub mod bytes128;
pub use bytes128::Bytes128;
Expand All @@ -42,42 +40,20 @@ pub use project_domain::ProjectDomain;
mod error;
pub use error::RegistryError;

/// Index of a transaction in the chain.
pub type Index = u32;

/// The hashing algorightm to use
pub type Hashing = BlakeTwo256;

/// Some way of identifying an account on the chain. We intentionally make it equivalent
/// to the public key of our transaction signing scheme.
/// Identifier for accounts, an Ed25519 public key.
///
/// Each account has an associated [message::AccountBalance] and [message::Index].
pub type AccountId = ed25519::Public;

/// Balance of an account.
pub type Balance = u128;

/// # Registry types

/// The name a project is registered with.
pub type ProjectName = String32;

pub type ProjectId = (ProjectName, ProjectDomain);

pub type CheckpointId = H256;

/// A project's version. Used in checkpointing.
pub type Version = String;

#[derive(Decode, Encode, Clone, Debug, Eq, PartialEq)]
pub struct Checkpoint {
pub parent: Option<CheckpointId>,
pub hash: H256,
}

#[derive(Decode, Encode, Clone, Debug, Eq, PartialEq)]
pub struct Project {
pub id: ProjectId,
pub account_id: AccountId,
pub members: Vec<AccountId>,
pub current_cp: CheckpointId,
pub metadata: Bytes128,
}
21 changes: 10 additions & 11 deletions core/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,18 @@
//! See the README.md for more information on how to document messages.
extern crate alloc;

use crate::{AccountId, Balance, Bytes128, CheckpointId, ProjectId};
use crate::{AccountId, Balance, Bytes128, CheckpointId, ProjectId, H256};
use parity_scale_codec::{Decode, Encode};
use sp_core::H256;

/// Registers a project on the Radicle Registry with the given ID.
///
/// # State changes
///
/// If successful, a new [crate::Project] with the given properties is added to the state.
/// If successful, a new [crate::state::Project] with the given properties is added to the state.
///
/// [crate::Project::members] is initialized with the transaction author as the only member.
/// [crate::state::Project::members] is initialized with the transaction author as the only member.
///
/// [crate::Project::account_id] is generated randomly.
/// [crate::state::Project::account_id] is generated randomly.
///
/// # State-dependent validations
///
Expand All @@ -54,7 +53,7 @@ pub struct RegisterProject {
///
/// # State changes
///
/// If successful, adds a new [crate::Checkpoint] with the given parameters to the state.
/// If successful, adds a new [crate::state::Checkpoint] with the given parameters to the state.
///
/// # State-dependent validations
///
Expand All @@ -65,19 +64,19 @@ pub struct CreateCheckpoint {
pub previous_checkpoint_id: Option<CheckpointId>,
}

/// Updates [crate::Project::current_cp].
/// Updates [crate::state::Project::current_cp].
///
/// # State changes
///
/// If successful, adds a new [crate::Checkpoint] with the given parameters to the state.
/// If successful, adds a new [crate::state::Checkpoint] with the given parameters to the state.
///
/// # State-dependent validations
///
/// The project `project_id` must exist.
///
/// The checkpoint `new_checkpoint_id` must exist.
///
/// The transaction author must be in [crate::Project::members] of the given project.
/// The transaction author must be in [crate::state::Project::members] of the given project.
#[derive(Decode, Encode, Clone, Debug, Eq, PartialEq)]
pub struct SetCheckpoint {
pub project_id: ProjectId,
Expand All @@ -89,14 +88,14 @@ pub struct SetCheckpoint {
/// # State changes
///
/// If successful, `balance` is deducated from the project account and added to the the recipient
/// account. The project account is given by [crate::Project::account_id] of the given project.
/// account. The project account is given by [crate::state::Project::account_id] of the given project.
///
/// If the recipient account did not exist before, it is created. The recipient account may be a
/// user account or a project account.
///
/// # State-dependent validations
///
/// The author must be a member of [crate::Project::members].
/// The author must be a member of [crate::state::Project::members].
///
/// The project account must have a balance of at least `balance`.
#[derive(Decode, Encode, Clone, Debug, Eq, PartialEq)]
Expand Down
Loading