Skip to content

Commit

Permalink
... and we can resume sync where we left off
Browse files Browse the repository at this point in the history
  • Loading branch information
jacogr committed Aug 24, 2018
1 parent ef007f3 commit c670186
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 16 deletions.
78 changes: 66 additions & 12 deletions packages/client-chains/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

import { Header } from '@polkadot/primitives/header';
import { Config } from '@polkadot/client/types';
import { TrieDb } from '@polkadot/client-db/types';
import { BlockDb, StateDb } from '@polkadot/client-db-chain/types';
import { ExecutorInterface } from '@polkadot/client-wasm/types';
import { ChainInterface, ChainGenesis, ChainJson } from './types';
Expand All @@ -17,6 +19,7 @@ import createStateDb from '@polkadot/client-db-chain/state';
import createRuntime from '@polkadot/client-runtime/index';
import Executor from '@polkadot/client-wasm/index';
import createBlock from '@polkadot/primitives/create/block';
import decodeBlock from '@polkadot/primitives/codec/block/decode';
import encodeBlock from '@polkadot/primitives/codec/block/encode';
import encodeHeader from '@polkadot/primitives/codec/header/encode';
import storage from '@polkadot/storage';
Expand All @@ -29,6 +32,12 @@ import trieRoot from '@polkadot/trie-hash/root';

import chains from './chains';

type BlockResult = {
block: Uint8Array,
header: Header,
headerHash: Uint8Array
};

export default class Chain implements ChainInterface {
readonly blocks: BlockDb;
readonly chain: ChainJson;
Expand All @@ -51,7 +60,7 @@ export default class Chain implements ChainInterface {

this.blocks = createBlockDb(blockDb);
this.state = createStateDb(stateDb);
this.genesis = this.initGenesis();
this.genesis = this.initGenesis(stateDb);
this.executor = new Executor(config, this.blocks, this.state, runtime);
}

Expand All @@ -75,27 +84,72 @@ export default class Chain implements ChainInterface {
);
}

private initGenesis () {
this.initGenesisState();
private initGenesis (stateDb: TrieDb): ChainGenesis {
const bestHash = this.blocks.bestHash.get();

const genesis = this.initGenesisBlock();
if (!bestHash || !bestHash.length) {
return this.createGenesis();
}

this.blocks.bestHash.set(genesis.headerHash);
this.blocks.bestNumber.set(0);
this.blocks.block.set(genesis.block, genesis.headerHash);
const bestBlock = this.getBlock(bestHash);

return genesis;
stateDb.setRoot(bestBlock.header.stateRoot);

const genesisHash = this.state.system.blockHashAt.get(0);

if (!genesisHash || !genesisHash.length) {
throw new Error('Unable to retrieve genesis hash, aborting');
}

const genesisBlock = this.getBlock(genesisHash);

return {
...genesisBlock,
code: this.getCode()
};
}

private initGenesisBlock () {
private getBlock (headerHash: Uint8Array): BlockResult {
const block = this.blocks.block.get(headerHash);

if (!block || !block.length) {
throw new Error(`Unable to retrieve block ${u8aToHex(headerHash)}`);
}

const decoded = decodeBlock(block);

return {
block,
header: decoded.header,
headerHash
};
}

private getCode (): Uint8Array {
const code = this.state.db.get(
key(storage.consensus.public.code)()
);

if (code === null) {
if (!code || !code.length) {
throw new Error('Unable to retrieve genesis code');
}

return code;
}

private createGenesis (): ChainGenesis {
this.createGenesisState();

const genesis = this.createGenesisBlock();

this.blocks.bestHash.set(genesis.headerHash);
this.blocks.bestNumber.set(0);
this.blocks.block.set(genesis.block, genesis.headerHash);

return genesis;
}

private createGenesisBlock (): ChainGenesis {
const block = createBlock({
header: {
stateRoot: this.state.db.getRoot(),
Expand All @@ -107,13 +161,13 @@ export default class Chain implements ChainInterface {

return {
block: encodeBlock(block),
code,
code: this.getCode(),
header: block.header,
headerHash
};
}

private initGenesisState () {
private createGenesisState (): void {
const { genesis: { raw } } = this.chain;

this.state.db.checkpoint();
Expand Down
4 changes: 0 additions & 4 deletions packages/client-p2p/src/sync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ export default class Sync extends EventEmitter implements SyncInterface {

// this.l.debug(() => `Importing block #${nextNumber.toString()}`);

if (count && !(count % 8)) {
this.emit('imported');
}

if (!this.chain.executor.importBlock(encoded)) {
break;
}
Expand Down

0 comments on commit c670186

Please sign in to comment.