Skip to content
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

Upgrade to polkadot-v1.1.0 and some refactoring work on project layout #266

Merged
merged 8 commits into from
Dec 5, 2023
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2,331 changes: 1,445 additions & 886 deletions Cargo.lock

Large diffs are not rendered by default.

372 changes: 203 additions & 169 deletions Cargo.toml

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ cargo test --release
## Module Documentation


* [Files Bank](c-pallets/file-bank)
* [Audit](c-pallets/audit)
* [Sminer](c-pallets/sminer)
* [Tee Worker](c-pallets/tee-worker)
* [Files Bank](pallets/file-bank)
* [Audit](pallets/audit)
* [Sminer](pallets/sminer)
* [Tee Worker](pallets/tee-worker)

## Contribute

Expand Down
35 changes: 0 additions & 35 deletions c-pallets/tee-worker/src/tests.rs

This file was deleted.

17 changes: 17 additions & 0 deletions crates/bloom-filter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "cp-bloom-filter"
version = "0.1.0"
edition = "2021"

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] }
scale-info = { workspace = true, features = ["derive"] }
sp-core = { workspace = true }

[features]
default = ["std"]
std = [
"codec/std",
"scale-info/std",
"sp-core/std",
]
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::{
RuntimeDebug,
dispatch::{Decode, Encode},
};
use codec::{MaxEncodedLen};
use codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::RuntimeDebug;

#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, MaxEncodedLen, TypeInfo)]
pub struct BloomFilter(pub [u64; 256]);
Expand Down
2 changes: 1 addition & 1 deletion primitives/common/Cargo.toml → crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
log = { workspace = true }
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive", "max-encoded-len"] }
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] }
scale-info = { workspace = true, features = ["derive"] }

frame-support = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion primitives/common/src/lib.rs → crates/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

use frame_support::{
BoundedVec,
RuntimeDebug,
pallet_prelude::ConstU32,
};
use codec::{MaxEncodedLen, Decode, Encode};
use scale_info::TypeInfo;
use sp_core::RuntimeDebug;
use sp_std::prelude::Box;

#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, MaxEncodedLen, TypeInfo, PartialOrd, Ord)]
Expand Down
14 changes: 14 additions & 0 deletions crates/enclave-verify/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "cp-enclave-verify"
version = "0.1.0"
edition = "2021"

[dependencies]
rsa = { workspace = true }

[dev-dependencies]
hex = { workspace = true, features = ['alloc'] }

[features]
default = ["std"]
std = []
51 changes: 51 additions & 0 deletions crates/enclave-verify/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#![cfg_attr(not(feature = "std"), no_std)]

use rsa::{pkcs1::DecodeRsaPublicKey, Pkcs1v15Sign, PublicKey};

pub fn verify_rsa(key: &[u8], msg: &[u8], sig: &[u8]) -> bool {
let pk = rsa::RsaPublicKey::from_pkcs1_der(key).unwrap();

match pk.verify(Pkcs1v15Sign::new_raw(), msg, sig) {
Ok(()) => return true,
Err(_) => return false,
};
}

#[cfg(test)]
mod test {
use rsa::{
pkcs1::{DecodeRsaPublicKey, EncodeRsaPublicKey},
pkcs8::DecodePrivateKey,
Pkcs1v15Sign, PublicKey, RsaPrivateKey, RsaPublicKey,
};

#[test]
fn cryptos_rsa() {
let priv_key = RsaPrivateKey::from_pkcs8_der(&hex::decode("308204bd020100300d06092a864886f70d0101010500048204a7308204a3020100028201010097f726d8bc510040ef6552b5861e54ab781527c4d852110ae14e5b23b6083201a4ebcec9e9dfae7d8a33460e14c634c7098e41b7fb861672f2cda91c73d55252aa3f39183b88a2e77beabbaff45fe8fe82112ea3c95df4f0b31e2bdd43e2a11635a14ddd7c30153eb56c3f0a07a05caa976f337000b7a8db4e691d2f54229f1176c27304d06e384c16cac868d26166b7563f6c32b315ec93398e4c43f3eba2ca93a394ed07e57afa4bf963f29d2288af4a8c499109833858f9af111a5d480f3255e65b7ceb1a68c8a1a089f903310777cf647f6cd7fbd6e4b4dddf0ca342d6b96454410647f02df76bc1ee44435ca1df012b9689daddd5e8240579203b814b050203010001028201000cc6c4c7581ddf4d9653087f26858a4cd84dbf0837bfbe9b11924aeb57b49cafb2b3f8b0d52eef36b2d5d8bffa5327c0cc36dfa39e4c09bb245ad22b083a192fc60c86ba58d7060b3c49e1f9cb2bfd24d8bea513342ce8190c962ecded953241f1c45c0d911161d7e1dcf5f7dbe849a236152d57ef5781a4de94cbd55cd784540c633f4ce96a053d6a19533b9830c7b8396f190f020099a4e481e24a41022a1191330ac599a7199ca776913db12be96cf5b949ad5d73be9d3b66311a8ba10a48b00a9deedbccc015aace97fb79ae19bbe39fa0103772d4a25bf7e4f35c2ede2943a935423720d4f3059994f171650558bc1bfabf725d10916095c162b8717cc902818100c393e0b47b91321fef951ad8fb1cdc1ec928e73f715f673ff093847d380dcff6c040691ac7cdcac45bf0ed38299a10b1349a56b60178de81e38095251dda7b2bb0ca96c5457fe162daf9b7a0bf30d1a8eae47340d75622dd72c22aa12f3fb45154896b791ab4a5275be06657098bb9def81010297981b0d531af2c4ee08da78b02818100c6ea027695077584eca26d7ef4b4e361f3cc583ff5fff2114daebbb0a6a92dff11861c7596626e86bad32fd11ae7683f8ad45599eefe2cd2117825e0c5590be86e2187e0bb1636a104cde7b6b0a573e169f56c2ae8ff171eece31295964a3426009fc4c2672ace0be0d59c99c427c0fbf8e7e9d4636165e9ba8803c24f53a9af02818100b24e0e8ddd1e09c9cdde6d64a6c3aff72d446a578fdfffbcee733f55fe15b1a4efaf89634e07d3b5e370aa850a8098794650f37ee9a6ad8d53c175b82a187734e4f03e36c9df05b7df95cd10f35de9b78bb70d506f41eb75635b9c0be98cb5b37453f8b4a7614c34aef1cdbbca4b26011ebd5e4ec1a5387795dd7392d1ecb37302818045146fd68edb104d21812755b7d63a418251ad344952a1d6b08bc6530b0e2613371ac437720aad27cd2a1aa91c16d1757fd94e012fa6c61a0e4713a083e8f0e1bf9d957ace7e606a7b28a7182330d295ae1eb57a1180c59ecfd5ec5656e35e48f45e880e9b959a093603f966cd60a0fce0ec69a081030a49a9a622e8107495b10281806de9944afeb9670b92eb33b3afcd4890c20b3ba9f7d055305d5027b2ccd5d8f565488b3f56342f04968d29cdaee716ad333868beecbd7df5cd2aeeba0c1c4d810f78162e0a02e3c1aa54ee9103469efc6cf3542e9292bddffc8d328996a8bb67f78a7701e9f113ad790bdfd981d39cf116b5ee41dd5e42fcc2b1f3d11e6a7d15").unwrap()).unwrap();
// let skey = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
let pub_key = RsaPublicKey::from(&priv_key);
println!("{:?}", hex::encode(pub_key.to_pkcs1_der().unwrap().to_vec()));

let original_text = [
193, 246, 62, 231, 50, 88, 107, 103, 221, 158, 61, 148, 6, 248, 29, 248, 56, 172, 222,
109, 191, 170, 225, 72, 211, 29, 42, 18, 51, 234, 205, 136,
];

// let priv_key_der = priv_key.to_pkcs1_der().unwrap();
// println!("priv_key_der: {:?}", priv_key_der.as_bytes());
// println!();

let doc = pub_key.to_pkcs1_der().unwrap();
// println!("pub_key: {:?}, length: {}", doc.as_bytes(), doc.as_bytes().len());

let pk = rsa::RsaPublicKey::from_pkcs1_der(doc.as_bytes()).unwrap();

let binding = priv_key.sign(Pkcs1v15Sign::new_raw(), &original_text).unwrap();
let sig: &[u8] = binding.as_ref();
println!("sig is: {:?}, sig is length: {:?}", sig, sig.len());

let result = pk.verify(Pkcs1v15Sign::new_raw(), &original_text, &sig);

println!("result: {:?}", result);
}
}
56 changes: 56 additions & 0 deletions crates/rrsc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[package]
name = "cessc-consensus-rrsc"
version = "0.10.0-dev"
authors = ["CESS"]
description = "RRSC consensus algorithm"
edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
homepage = "https://cess.one"
repository = "https://github.com/CESSProject/substrate"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
async-trait = { workspace = true }
scale-info = { workspace = true, features = ["derive"] }
codec = { package = "parity-scale-codec", version = "3.6.1", features = ["derive"] }
futures = { workspace = true }
log = { workspace = true }
num-bigint = { workspace = true }
num-rational = { workspace = true }
num-traits = { workspace = true }
parking_lot = { workspace = true }
thiserror = { workspace = true }
fork-tree = { workspace = true }
prometheus-endpoint = { workspace = true }
sc-client-api = { workspace = true }
sc-consensus = { workspace = true }
sc-consensus-epochs = { workspace = true }
sc-consensus-slots = { workspace = true }
sc-keystore = { workspace = true }
sc-telemetry = { workspace = true }
sc-transaction-pool-api = { workspace = true }
sp-api = { workspace = true, default-features = true }
sp-application-crypto = { workspace = true, default-features = true }
sp-block-builder = { workspace = true, default-features = true }
sp-blockchain = { workspace = true, default-features = true }
sp-consensus = { workspace = true, default-features = true }
sp-consensus-slots = { workspace = true, default-features = true }
sp-core = { workspace = true, default-features = true }
sp-inherents = { workspace = true, default-features = true }
sp-keystore = { workspace = true, default-features = true }
sp-runtime = { workspace = true, default-features = true }
cessp-consensus-rrsc = { workspace = true, default-features = true }

[dev-dependencies]
rand_chacha = { workspace = true }
sc-block-builder = { workspace = true }
sp-keyring = { workspace = true }
sc-network = { workspace = true }
sc-network-test = { workspace = true }
sp-timestamp = { workspace = true }
sp-tracing = { workspace = true }
substrate-test-runtime-client = { workspace = true }
tokio = { workspace = true }
139 changes: 139 additions & 0 deletions crates/rrsc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# RRSC (Random Rotational Selection Consensus)

## What is Consensus in Blockchain?

A consensus is a method used by nodes within a network to come into agreement. All nodes should come into agreement on a single state of the network at a given time. The nodes in a decentralized network stay synced with each other by adhering to the consensus mechanism. In the blockchain network, the consensus method helps generate new blocks and maintain the state of the network.

## Substrate Consensus

### Block Production: BABE

Blind Assignment for Blockchain Extension (BABE) is a block production mechanism that runs on validator nodes and determines the authors of new blocks.

Follow the following links to read more about BABE:

● https://wiki.polkadot.network/docs/learn-consensus#block-production-babe

● https://research.web3.foundation/en/latest/polkadot/block-production/Babe.html

BABE uses VRF for determining the next validator in every slot.

Slots are discrete units of time six seconds in length. Each slot can contain a block, but may not. Slots make up epochs - on Polkadot, 2400 slots make one epoch, which makes epochs four hours long.

In every slot, each validator "rolls a die". They execute a function (the VRF) that takes as input the following:

● The "secret key", a key specifically made for these die rolls.

● An epoch randomness value, which is the hash of VRF values from the blocks in the epoch before last (N-2), so past randomness affects the current pending randomness (N).

● The slot number.

# ![Figure 1](https://raw.githubusercontent.com/CESSProject/W3F-illustration/main/rrsc/image.png)

The output is two values: a RESULT (the random value) and a PROOF (a proof that the random value was generated correctly).

The RESULT is then compared to a threshold defined in the implementation of the protocol (specifically, in the Polkadot Host). If the value is less than the threshold, then the validator who rolled this number is a viable block production candidate for that slot. The validator then attempts to create a block and submits this block into the network along with the previously obtained PROOF and RESULT. Under VRF, every validator rolls a number for themselves, checks it against a threshold, and produces a block if the random roll is under that threshold.

The astute reader will notice that due to the way this works, some slots may have no validators as block producer candidates because all validator candidates rolled too high and missed the threshold. We clarify how we resolve this issue and make sure that Polkadot block times remain near constant-time in the wiki page on consensus.

## Random Rotational Selection(R²S)

### 1.1 Definitions

- **Slot**: Each slot will generate a new block, that is, the block out time. In the cess test network, 1 slot = 6 seconds.

- **Epoch**: A collection of fixed length slots. Each epoch will update the set of rotation nodes, but not every epoch will trigger the election. The election will be triggered in the first block from the sixth epoch of era. 1 epoch = 1 hour in the cess testnet.

- **Era**: A collection of multiple epochs. Era starts the new rotation node set in the first block, and settles the consensus award of the previous era. In the cess testnet, 1 era = 6 epoch, that is, 6 hours.

### 1.2 Overall process

R²S is an important part of CESS protocol. Compared with the polkadot consensus mechanism, R²S pays more attention to the process of node election and block generation. The following is the overall process:

1. The node has become a consensus node through pledge and registration, and the current pledge amount is 1 million.

2. In each round of era, the validators are rotated. The rotation rule is score ranking. The 11 nodes with the highest scores (4 in the cess testnet) are selected as the validators of era.

3. The final score is determined by reputation score and random score, that is, final score = `(reputation score * 80%) + (random score * 20%)`.

4. Please refer to the next section for credit score calculation, and the random score is determined by VRF.

5. The selected validators generate blocks in sequence.

6. The current way of confirming blocks is the same as GRANDPA.

7. The last epoch of each era starts the validators election of the next era.

<img src="https://raw.githubusercontent.com/CESSProject/W3F-illustration/main/rrsc/image1.png" width = "600" alt="name" align=center />

### 1.3 Reputation model

As each consensus node that joins the cess network needs to maintain the network state, it also needs to undertake the work of storage data scheduling. In order to encourage consensus nodes to do more such work, we designed a reputation model. In our model, each consensus node has a reputation score, which is directly determined by the workload of the scheduler. Specifically, it includes the following items:

1. Total bytes of idle segment processed.

2. Total of bytes of service segment processed.

3. Number of penalties for random challenge timeout of verification file.

Reputation value calculation as follow:

`Scheduler reputation value = 1000 * processing bytes ratio - (10 * penalty times)`

### 1.4 Code Walkthrough

#### 1. The election

final_score = `random_score` * 20% + `credit` * 80%

The final score of the node is composed of two parts, random score accounting for 20% of the weight and reputation score accounting for 80% of the weight. Arrange according to the scores from large to small, and select no more than 11 nodes with the highest scores as the rotation nodes.

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/frame/rrsc/src/vrf_solver.rs#L46-L48

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/frame/rrsc/src/vrf_solver.rs#L61-L62

#### 2. The random scores

- Use the `currentblockrandomness` random function to calculate a random hash value for each node.

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/frame/rrsc/src/vrf_solver.rs#L87-L99

- Convert random hash value to U32 type value.

- Modulo the full score of reputation score with U32 type value to obtain random score.

- During the production of each block, the vrfoutput obtained by executing the VRF function is written into the block header.

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/client/consensus/rrsc/src/authorship.rs#L185-L199

- When each block is initialized, vrfoutput is taken from the block header, converted into randomness, and stored in the authorvrrandomness of pallet rrsc as the seed for running the random function in the current block

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/frame/rrsc/src/lib.rs#L749

- Randomness stored in authorvrrandomness is used as seed, and random hash value is obtained through byte array inversion, splicing and hash operation.

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/frame/rrsc/src/randomness.rs#L136-L148

#### 3. Reputation scores

Obtain reputation scores of all candidate nodes during election

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/frame/rrsc/src/vrf_solver.rs#L33

#### 4. Block generation

- Rotation nodes take turns to output blocks.

- Modulo the number of rotation nodes with the slot serial number, and take the modulo value as the node taken from the subscript of the rotation node list, which is the block out node of this slot. Slot numbers are cumulative, so the out of block nodes take turns.

https://github.com/CESSProject/substrate/blob/6f338348a5488f56fd338ab678d57e30f456e802/client/consensus/rrsc/src/authorship.rs#L180-L181

### 1.5 Future work

Consensus is the foundation of the blockchain network, and it is necessary for us to continuously optimize it. At this stage, we have completed the realization of the core functions. But this is far from enough, and there are still many points that need to be improved in the future.

1. Adjust consensus-related RPC interfaces to adapt to applications such as block explorers.

2. According to the actual test situation, the reputation model is continuously iterated to make it more perfect.

3. A more concrete theoretical security analysis will be conducted.
Loading