Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Fixes and improvements for PoC-1 Testnet #143

Merged
merged 16 commits into from
May 7, 2018
Merged
103 changes: 102 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,104 @@
# Polkadot

Implementation of a https://polkadot.io node in Rust.
Implementation of a https://polkadot.io node in Rust.

## To play

If you'd like to play with Polkadot, you'll need to install a client like this
one. First, get Rust and the support software if you don't already have it:

```
curl https://sh.rustup.rs -sSf | sh
sudo apt install make clang
```

Then, install Polkadot PoC-1:

```
cargo install --git https://github.com/paritytech/polkadot.git --branch v0.1.0
```

You'll now have a `polkadot` binary installed to your `PATH`. You can drop the
`--branch v0.1.0` to get the very latest version of Polkadot, but these
instructions might not work in that case.

### Development

You can run a simple single-node development "network" on your machine by
running in a terminal:

```
polkadot --chain=dev --validator --key Alice
```

You can muck around by cloning and building the http://github.com/paritytech/polka-ui and http://github.com/paritytech/polkadot-ui or just heading to https://polkadot.js.org/apps.

### PoC-1 Testnet

You can also connect to the global PoC-1 testnet. To do this, just use:

```
polkadot --chain=poc-1
```

If you want to do anything on it (not that there's much to do), then you'll need
to get some PoC-1 testnet DOTs. Ask in the Polkadot watercooler.

## Local Two-node Testnet

If you want to see the multi-node consensus algorithm in action locally, then
you can create a local testnet. You'll need two terminals open. In one, run:

```
polkadot --chain=dev --validator --key Alice -d /tmp/alice
```

and in the other, run:

```
polkadot --chain=dev --validator --key Bob -d /tmp/bob --port 30334 --bootnodes 'enode://ALICE_BOOTNODE_ID_HERE@127.0.0.1:30333'
```

Ensure you replace `ALICE_BOOTNODE_ID_HERE` with the node ID from the output of
the first terminal.

## Hacking on Polkadot

If you'd actually like hack on Polkadot, you can just grab the source code and
build it. Ensure you have Rust and the support software installed:

```
curl https://sh.rustup.rs -sSf | sh
rustup update nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
rustup update stable
cargo install --git https://github.com/alexcrichton/wasm-gc
cargo install --git https://github.com/pepyakin/wasm-export-table.git
sudo apt install make clang
```

Then, grab the Polkadot source code:

```
git clone https://github.com/paritytech/polkadot.git
cd polkadot
```

Then build the code:

```
./build.sh # Builds the WebAssembly binaries
cargo build # Builds all native code
```

You can run the tests if you like:

```
cargo test --all
```

You can start a development chain with:

```
cargo run -- --chain=dev --validator --key Alice
```
4 changes: 2 additions & 2 deletions demo/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ mod tests {
construct_block(
1,
[69u8; 32].into(),
hex!("57ba67304318efaee95c4f9ab95ed5704eafe030bc8db2df00acb08c2f4979c8").into(),
hex!("a63d59c6a7347cd7a1dc1ec139723b531f0ac450e39b1c532d5ca69ff74ad811").into(),
vec![Extrinsic {
signed: Alice.into(),
index: 0,
Expand All @@ -210,7 +210,7 @@ mod tests {
construct_block(
2,
block1().1,
hex!("ead4c60c0cad06b7ee73e64efeec2d4eb82c651469fb2ec748cfe5026bea5c49").into(),
hex!("1c3623b2e3f7e43752debb9015bace4f6931593579b5af34457b931315f5e2ab").into(),
vec![
Extrinsic {
signed: Bob.into(),
Expand Down
Binary file not shown.
Binary file not shown.
12 changes: 8 additions & 4 deletions polkadot/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ extern crate substrate_state_machine as state_machine;
#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate log;

#[cfg(test)]
extern crate substrate_keyring as keyring;

Expand All @@ -42,7 +39,7 @@ use client::Client;
use polkadot_executor::Executor as LocalDispatch;
use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
use state_machine::OverlayedChanges;
use primitives::{AccountId, BlockId, Index, SessionKey, Timestamp};
use primitives::{AccountId, BlockId, Hash, Index, SessionKey, Timestamp};
use primitives::parachain::DutyRoster;
use runtime::{Block, Header, UncheckedExtrinsic, Extrinsic, Call, TimestampCall};

Expand Down Expand Up @@ -126,6 +123,9 @@ pub trait PolkadotApi {
/// Get validators at a given block.
fn validators(&self, at: &Self::CheckedBlockId) -> Result<Vec<AccountId>>;

/// Get the value of the randomness beacon at a given block.
fn random_seed(&self, at: &Self::CheckedBlockId) -> Result<Hash>;

/// Get the authority duty roster at a block.
fn duty_roster(&self, at: &Self::CheckedBlockId) -> Result<DutyRoster>;

Expand Down Expand Up @@ -191,6 +191,10 @@ impl<B: Backend> PolkadotApi for Client<B, NativeExecutor<LocalDispatch>>
with_runtime!(self, at, ::runtime::Session::validators)
}

fn random_seed(&self, at: &CheckedId) -> Result<Hash> {
with_runtime!(self, at, ::runtime::System::random_seed)
}

fn duty_roster(&self, at: &CheckedId) -> Result<DutyRoster> {
// duty roster can only be queried at the start of a block,
// so we create a dummy.
Expand Down
2 changes: 1 addition & 1 deletion polkadot/cli/src/cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ args:
- chain:
long: chain
value_name: CHAIN_SPEC
help: Specify the chain specification (one of dev or poc-1)
help: Specify the chain specification (one of dev, local or poc-1)
takes_value: true
subcommands:
6 changes: 4 additions & 2 deletions polkadot/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
}

match matches.value_of("chain") {
Some("poc-1") => config.chain_spec = ChainSpec::PoC1Testnet,
Some("dev") => config.chain_spec = ChainSpec::Development,
Some("local") => config.chain_spec = ChainSpec::LocalTestnet,
Some("poc-1") => config.chain_spec = ChainSpec::PoC1Testnet,
None => (),
Some(unknown) => panic!("Invalid chain name: {}", unknown),
}
info!("Chain specification: {}", match config.chain_spec {
ChainSpec::Development => "Local Development",
ChainSpec::Development => "Development",
ChainSpec::LocalTestnet => "Local Testnet",
ChainSpec::PoC1Testnet => "PoC-1 Testnet",
});

Expand Down
15 changes: 15 additions & 0 deletions polkadot/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>

let checked_id = self.client.check_id(BlockId::Hash(parent_hash))?;
let duty_roster = self.client.duty_roster(&checked_id)?;
let random_seed = self.client.random_seed(&checked_id)?;

let group_info = make_group_info(duty_roster, authorities)?;
let table = Arc::new(SharedTable::new(group_info, sign_with.clone(), parent_hash));
Expand All @@ -510,6 +511,7 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>
parent_hash,
parent_number: parent_header.number,
parent_id: checked_id,
random_seed,
local_key: sign_with,
client: self.client.clone(),
transaction_pool: self.transaction_pool.clone(),
Expand All @@ -533,6 +535,7 @@ pub struct Proposer<C: PolkadotApi, R> {
parent_hash: HeaderHash,
parent_number: BlockNumber,
parent_id: C::CheckedBlockId,
random_seed: Hash,
client: Arc<C>,
local_key: Arc<ed25519::Pair>,
transaction_pool: Arc<Mutex<TransactionPool>>,
Expand Down Expand Up @@ -561,6 +564,7 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
let mut pool = self.transaction_pool.lock();
let mut unqueue_invalid = Vec::new();
let mut pending_size = 0;
pool.cull(None, readiness_evaluator.clone());
for pending in pool.pending(readiness_evaluator.clone()) {
// skip and cull transactions which are too large.
if pending.encoded_size() > MAX_TRANSACTIONS_SIZE {
Expand Down Expand Up @@ -624,6 +628,16 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
Box::new(self.delay.clone().map_err(Error::from).and_then(move |_| evaluated))
}

fn round_proposer(&self, round_number: usize, authorities: &[AuthorityId]) -> AuthorityId {
use primitives::uint::U256;

let len: U256 = authorities.len().into();
let offset = U256::from_big_endian(&self.random_seed.0) % len;
let offset = offset.low_u64() as usize + round_number;

authorities[offset % authorities.len()].clone()
}

fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior)>) {
use bft::generic::Misbehavior as GenericMisbehavior;
use primitives::bft::{MisbehaviorKind, MisbehaviorReport};
Expand All @@ -634,6 +648,7 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
let mut next_index = {
let readiness_evaluator = Ready::create(self.parent_id.clone(), &*self.client);

pool.cull(None, readiness_evaluator.clone());
let cur_index = pool.pending(readiness_evaluator)
.filter(|tx| tx.as_ref().as_ref().signed == local_id)
.last()
Expand Down
28 changes: 14 additions & 14 deletions polkadot/consensus/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,22 @@ impl Stream for Messages {
}

// check the network
match self.network_stream.poll() {
Err(_) => Err(bft::InputStreamConcluded.into()),
Ok(Async::NotReady) => Ok(Async::NotReady),
Ok(Async::Ready(None)) => Ok(Async::NotReady), // the input stream for agreements is never meant to logically end.
Ok(Async::Ready(Some(message))) => {
if message.parent_hash == self.parent_hash {
match process_message(message, &self.authorities) {
Ok(message) => Ok(Async::Ready(Some(message))),
Err(e) => {
debug!("Message validation failed: {:?}", e);
Ok(Async::NotReady)
loop {
match self.network_stream.poll() {
Err(_) => return Err(bft::InputStreamConcluded.into()),
Ok(Async::NotReady) => return Ok(Async::NotReady),
Ok(Async::Ready(None)) => return Ok(Async::NotReady), // the input stream for agreements is never meant to logically end.
Ok(Async::Ready(Some(message))) => {
if message.parent_hash == self.parent_hash {
match process_message(message, &self.authorities) {
Ok(message) => return Ok(Async::Ready(Some(message))),
Err(e) => {
debug!("Message validation failed: {:?}", e);
}
}
} else {
self.collection.push(message);
}
} else {
self.collection.push(message);
Ok(Async::NotReady)
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions polkadot/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ extern crate substrate_runtime_support as runtime_support;
#[macro_use]
extern crate substrate_runtime_primitives as runtime_primitives;

#[cfg(feature = "std")]
#[macro_use]
extern crate hex_literal;

#[cfg(test)]
extern crate substrate_serializer;

Expand Down Expand Up @@ -298,4 +302,24 @@ mod tests {
println!("{}", HexDisplay::from(&v));
assert_eq!(UncheckedExtrinsic::decode(&mut &v[..]).unwrap(), tx);
}

#[test]
fn serialize_checked() {
let xt = Extrinsic {
signed: hex!["0d71d1a9cad6f2ab773435a7dec1bac019994d05d1dd5eb3108211dcf25c9d1e"],
index: 0u64,
function: Call::CouncilVoting(council::voting::Call::propose(Box::new(
PrivCall::Consensus(consensus::PrivCall::set_code(
vec![]
))
))),
};
let v = Slicable::encode(&xt);

let data = hex!["e00000000d71d1a9cad6f2ab773435a7dec1bac019994d05d1dd5eb3108211dcf25c9d1e000000000000000007000000000000006369D39D892B7B87A6769F90E14C618C2B84EBB293E2CC46640136E112C078C75619AC2E0815F2511568736623C055156C8FC427CE2AEE4AE2838F86EFE80208"];
let uxt: UncheckedExtrinsic = Slicable::decode(&mut &data[..]).unwrap();
assert_eq!(uxt.extrinsic, xt);

assert_eq!(Extrinsic::decode(&mut &v[..]).unwrap(), xt);
}
}
Binary file modified polkadot/runtime/wasm/genesis.wasm
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 3 additions & 1 deletion polkadot/service/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ pub use network::NetworkConfiguration;
/// The chain specification (this should eventually be replaced by a more general JSON-based chain
/// specification).
pub enum ChainSpec {
/// Whatever the current runtime is, with simple Alice/Bob auths.
/// Whatever the current runtime is, with just Alice as an auth.
Development,
/// Whatever the current runtime is, with simple Alice/Bob auths.
LocalTestnet,
/// The PoC-1 testnet.
PoC1Testnet,
}
Expand Down
Loading