├── .dockerignore ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ └── config.yml ├── pull_request_template.md └── workflows │ ├── Entitlements.plist │ ├── chain-spec-snapshot-build.yml │ ├── runtime-snapshot-build.yml │ ├── rust.yml │ ├── rustdoc.yml │ └── snapshot-build.yml ├── .gitignore ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── Dockerfile-bootstrap-node ├── Dockerfile-bootstrap-node.aarch64 ├── Dockerfile-farmer ├── Dockerfile-farmer.aarch64 ├── Dockerfile-node ├── Dockerfile-node.aarch64 ├── Dockerfile-runtime ├── README.md ├── crates ├── pallet-domains │ ├── Cargo.toml │ └── src │ │ ├── benchmarking.rs │ │ ├── lib.rs │ │ ├── tests.rs │ │ └── weights.rs ├── pallet-feeds │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── feed_processor.rs │ │ ├── lib.rs │ │ ├── mock.rs │ │ └── tests.rs ├── pallet-grandpa-finality-verifier │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── chain.rs │ │ ├── grandpa.rs │ │ ├── lib.rs │ │ └── tests │ │ ├── justification.rs │ │ ├── keyring.rs │ │ ├── mock.rs │ │ └── mod.rs ├── pallet-object-store │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── lib.rs │ │ ├── mock.rs │ │ └── tests.rs ├── pallet-offences-subspace │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── lib.rs │ │ ├── mock.rs │ │ └── tests.rs ├── pallet-rewards │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── default_weights.rs │ │ └── lib.rs ├── pallet-runtime-configs │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── pallet-settlement │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── pallet-subspace │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── benchmarking.rs │ │ ├── equivocation.rs │ │ ├── lib.rs │ │ ├── mock.rs │ │ ├── tests.rs │ │ └── weights.rs ├── pallet-transaction-fees │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── default_weights.rs │ │ └── lib.rs ├── sc-consensus-fraud-proof │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── sc-consensus-subspace-rpc │ ├── Cargo.toml │ ├── README.md │ └── src │ │ └── lib.rs ├── sc-consensus-subspace │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── archiver.rs │ │ ├── aux_schema.rs │ │ ├── lib.rs │ │ ├── notification.rs │ │ ├── slot_worker.rs │ │ └── tests.rs ├── sc-subspace-block-relay │ ├── Cargo.toml │ └── src │ │ ├── consensus.rs │ │ ├── lib.rs │ │ ├── protocol.rs │ │ ├── protocol │ │ └── compact_block.rs │ │ └── utils.rs ├── sc-subspace-chain-specs │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── utils.rs ├── sp-consensus-subspace │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── digests.rs │ │ ├── inherents.rs │ │ ├── lib.rs │ │ ├── offence.rs │ │ └── tests.rs ├── sp-domains │ ├── Cargo.toml │ └── src │ │ ├── bundle_election.rs │ │ ├── fraud_proof.rs │ │ ├── lib.rs │ │ ├── merkle_tree.rs │ │ └── transaction.rs ├── sp-lightclient │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── lib.rs │ │ ├── mock.rs │ │ └── tests.rs ├── sp-objects │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── sp-settlement │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── subspace-archiving │ ├── Cargo.toml │ ├── README.md │ ├── benches │ │ └── archiving.rs │ ├── src │ │ ├── archiver.rs │ │ ├── archiver │ │ │ └── incremental_record_commitments.rs │ │ ├── lib.rs │ │ ├── piece_reconstructor.rs │ │ └── reconstructor.rs │ └── tests │ │ └── integration │ │ ├── archiver.rs │ │ ├── main.rs │ │ ├── piece_reconstruction.rs │ │ └── reconstructor.rs ├── subspace-core-primitives │ ├── Cargo.toml │ ├── README.md │ ├── benches │ │ └── kzg.rs │ └── src │ │ ├── crypto.rs │ │ ├── crypto │ │ ├── kzg.rs │ │ └── kzg │ │ │ ├── eth-public-parameters.bin │ │ │ ├── serde.rs │ │ │ └── tests.rs │ │ ├── lib.rs │ │ ├── objects.rs │ │ ├── pieces.rs │ │ ├── pieces │ │ ├── serde.rs │ │ └── tests.rs │ │ ├── segments.rs │ │ ├── serde.rs │ │ └── tests.rs ├── subspace-erasure-coding │ ├── Cargo.toml │ ├── benches │ │ └── commitments.rs │ └── src │ │ ├── lib.rs │ │ └── tests.rs ├── subspace-farmer-components │ ├── Cargo.toml │ ├── README.md │ ├── benches │ │ ├── auditing.rs │ │ ├── plotting.rs │ │ ├── proving.rs │ │ └── reading.rs │ └── src │ │ ├── auditing.rs │ │ ├── file_ext.rs │ │ ├── lib.rs │ │ ├── piece_caching.rs │ │ ├── plotting.rs │ │ ├── proving.rs │ │ ├── reading.rs │ │ ├── sector.rs │ │ └── segment_reconstruction.rs ├── subspace-farmer │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── bin │ │ └── subspace-farmer │ │ │ ├── commands.rs │ │ │ ├── commands │ │ │ ├── farm.rs │ │ │ ├── farm │ │ │ │ └── dsn.rs │ │ │ ├── info.rs │ │ │ └── shared.rs │ │ │ ├── main.rs │ │ │ ├── ss58.rs │ │ │ └── utils.rs │ │ ├── identity.rs │ │ ├── lib.rs │ │ ├── node_client.rs │ │ ├── node_client │ │ └── node_rpc_client.rs │ │ ├── object_mappings.rs │ │ ├── object_mappings │ │ └── tests.rs │ │ ├── reward_signing.rs │ │ ├── single_disk_plot.rs │ │ ├── single_disk_plot │ │ └── piece_reader.rs │ │ ├── utils.rs │ │ ├── utils │ │ ├── farmer_piece_cache.rs │ │ ├── farmer_piece_getter.rs │ │ ├── farmer_provider_storage.rs │ │ ├── node_piece_getter.rs │ │ ├── parity_db_store.rs │ │ ├── piece_cache.rs │ │ ├── piece_validator.rs │ │ ├── readers_and_pieces.rs │ │ └── tests.rs │ │ └── ws_rpc_server.rs ├── subspace-fraud-proof │ ├── Cargo.toml │ └── src │ │ ├── domain_extrinsics_builder.rs │ │ ├── domain_runtime_code.rs │ │ ├── invalid_state_transition_proof.rs │ │ ├── invalid_transaction_proof.rs │ │ ├── lib.rs │ │ ├── tests.rs │ │ └── verifier_api.rs ├── subspace-networking │ ├── Cargo.toml │ ├── examples │ │ ├── announce-piece-complex.rs │ │ ├── announce-piece.rs │ │ ├── custom-store.rs │ │ ├── get-peers-complex.rs │ │ ├── get-peers.rs │ │ ├── networking.rs │ │ └── requests.rs │ └── src │ │ ├── behavior.rs │ │ ├── behavior │ │ ├── persistent_parameters.rs │ │ ├── provider_storage.rs │ │ ├── provider_storage │ │ │ ├── providers.rs │ │ │ └── providers │ │ │ │ └── tests.rs │ │ └── tests.rs │ │ ├── bin │ │ └── subspace-bootstrap-node │ │ │ └── main.rs │ │ ├── create.rs │ │ ├── create │ │ ├── temporary_bans.rs │ │ ├── tests.rs │ │ └── transport.rs │ │ ├── lib.rs │ │ ├── node.rs │ │ ├── node_runner.rs │ │ ├── request_handlers.rs │ │ ├── request_handlers │ │ ├── generic_request_handler.rs │ │ ├── object_mappings.rs │ │ ├── peer_info.rs │ │ ├── piece_announcement.rs │ │ ├── piece_by_key.rs │ │ ├── pieces_by_range.rs │ │ └── segment_header.rs │ │ ├── request_responses.rs │ │ ├── request_responses │ │ └── tests.rs │ │ ├── reserved_peers.rs │ │ ├── reserved_peers │ │ └── handler.rs │ │ ├── shared.rs │ │ ├── utils.rs │ │ └── utils │ │ ├── multihash.rs │ │ ├── piece_announcement.rs │ │ ├── piece_provider.rs │ │ ├── prometheus.rs │ │ ├── tests.rs │ │ ├── unique_record_binary_heap.rs │ │ └── unique_record_binary_heap │ │ └── tests.rs ├── subspace-node │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── res │ │ └── chain-spec-raw-devnet.json │ └── src │ │ ├── bin │ │ └── subspace-node.rs │ │ ├── chain_spec.rs │ │ ├── chain_spec_utils.rs │ │ ├── core_domain.rs │ │ ├── core_domain │ │ └── core_evm_chain_spec.rs │ │ ├── import_blocks_from_dsn.rs │ │ ├── lib.rs │ │ ├── system_domain.rs │ │ └── system_domain │ │ ├── chain_spec.rs │ │ └── cli.rs ├── subspace-proof-of-space │ ├── Cargo.toml │ ├── benches │ │ └── pos.rs │ └── src │ │ ├── chia.rs │ │ ├── chia_legacy.rs │ │ ├── chiapos.rs │ │ ├── chiapos │ │ ├── constants.rs │ │ ├── table.rs │ │ ├── table │ │ │ ├── tests.rs │ │ │ └── types.rs │ │ ├── tables.rs │ │ ├── tables │ │ │ └── tests.rs │ │ ├── tests.rs │ │ └── utils.rs │ │ ├── lib.rs │ │ └── shim.rs ├── subspace-rpc-primitives │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── subspace-runtime-primitives │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── subspace-runtime │ ├── Cargo.toml │ ├── build.rs │ ├── src │ │ ├── domains.rs │ │ ├── feed_processor.rs │ │ ├── fees.rs │ │ ├── lib.rs │ │ ├── object_mapping.rs │ │ ├── signed_extensions.rs │ │ └── weights.rs │ └── tests │ │ └── integration │ │ ├── main.rs │ │ └── object_mapping.rs ├── subspace-service │ ├── Cargo.toml │ └── src │ │ ├── dsn.rs │ │ ├── dsn │ │ ├── import_blocks.rs │ │ ├── import_blocks │ │ │ ├── piece_validator.rs │ │ │ └── segment_headers.rs │ │ └── node_provider_storage.rs │ │ ├── lib.rs │ │ ├── metrics.rs │ │ ├── piece_cache.rs │ │ ├── piece_cache │ │ └── tests.rs │ │ ├── rpc.rs │ │ ├── segment_headers.rs │ │ └── tx_pre_validator.rs ├── subspace-solving │ ├── Cargo.toml │ ├── README.md │ └── src │ │ └── lib.rs ├── subspace-transaction-pool │ ├── Cargo.toml │ └── src │ │ ├── bundle_validator.rs │ │ └── lib.rs ├── subspace-verification │ ├── Cargo.toml │ ├── README.md │ └── src │ │ └── lib.rs └── subspace-wasm-tools │ ├── Cargo.toml │ └── src │ └── lib.rs ├── docs ├── development.md └── farming.md ├── domains ├── README.md ├── client │ ├── block-builder │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ └── lib.rs │ ├── block-preprocessor │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── inherents.rs │ │ │ ├── lib.rs │ │ │ ├── runtime_api.rs │ │ │ ├── runtime_api_full.rs │ │ │ ├── runtime_api_light.rs │ │ │ └── xdm_verifier.rs │ ├── consensus-relay-chain │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── import_queue.rs │ │ │ └── lib.rs │ ├── cross-domain-message-gossip │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── gossip_worker.rs │ │ │ ├── lib.rs │ │ │ └── message_listener.rs │ ├── domain-executor │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ ├── aux_schema.rs │ │ │ ├── bundle_election_solver.rs │ │ │ ├── domain_block_processor.rs │ │ │ ├── domain_bundle_producer.rs │ │ │ ├── domain_bundle_proposer.rs │ │ │ ├── domain_worker.rs │ │ │ ├── fraud_proof.rs │ │ │ ├── gossip_message_validator.rs │ │ │ ├── lib.rs │ │ │ ├── parent_chain.rs │ │ │ ├── sortition.rs │ │ │ ├── system_bundle_processor.rs │ │ │ ├── system_domain_worker.rs │ │ │ ├── system_executor.rs │ │ │ ├── system_gossip_message_validator.rs │ │ │ ├── tests.rs │ │ │ └── utils.rs │ ├── eth-service │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ ├── provider.rs │ │ │ ├── rpc.rs │ │ │ └── service.rs │ ├── executor-gossip │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ └── worker.rs │ └── relayer │ │ ├── Cargo.toml │ │ └── src │ │ ├── lib.rs │ │ └── worker.rs ├── pallets │ ├── domain-registry │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── benchmarking.rs │ │ │ ├── lib.rs │ │ │ ├── tests.rs │ │ │ └── weights.rs │ ├── executive │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── executor-registry │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── benchmarking.rs │ │ │ ├── lib.rs │ │ │ ├── tests.rs │ │ │ └── weights.rs │ ├── messenger │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ ├── benchmarking.rs │ │ │ ├── fees.rs │ │ │ ├── lib.rs │ │ │ ├── messages.rs │ │ │ ├── mock.rs │ │ │ ├── relayer.rs │ │ │ ├── tests.rs │ │ │ └── weights.rs │ └── transporter │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ ├── benchmarking.rs │ │ ├── lib.rs │ │ ├── mock.rs │ │ ├── tests.rs │ │ └── weights.rs ├── primitives │ ├── digests │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── executor-registry │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── messenger │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── endpoint.rs │ │ │ ├── lib.rs │ │ │ ├── messages.rs │ │ │ └── verification.rs │ ├── runtime │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ └── system-runtime │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── runtime │ ├── core-evm │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ │ ├── lib.rs │ │ │ ├── precompiles.rs │ │ │ └── runtime.rs │ └── system │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ ├── lib.rs │ │ └── runtime.rs ├── service │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ ├── lib.rs │ │ ├── providers.rs │ │ ├── rpc.rs │ │ ├── system_domain.rs │ │ └── system_domain_tx_pre_validator.rs └── test │ ├── primitives │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── runtime │ └── system │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ ├── lib.rs │ │ └── runtime.rs │ └── service │ ├── Cargo.toml │ └── src │ ├── chain_spec.rs │ ├── lib.rs │ └── system_domain.rs ├── frame-weight-template.hbs ├── orml ├── README.md └── vesting │ ├── Cargo.toml │ ├── README.md │ └── src │ ├── default_weight.rs │ ├── lib.rs │ ├── mock.rs │ ├── tests.rs │ └── weights.rs ├── rust-toolchain.toml ├── rustfmt.toml └── test ├── subspace-test-client ├── Cargo.toml └── src │ ├── chain_spec.rs │ └── lib.rs ├── subspace-test-runtime ├── Cargo.toml ├── build.rs └── src │ └── lib.rs └── subspace-test-service ├── Cargo.toml └── src └── lib.rs /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !/crates 3 | !/domains 4 | !/orml 5 | !/test 6 | !/Cargo.lock 7 | !/Cargo.toml 8 | !/rust-toolchain.toml 9 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Order matters 2 | # below ones takes precedence over the upper ones 3 | 4 | # Global owners 5 | * @nazar-pc @rg3l3dr 6 | 7 | /crates @liuchengxu @nazar-pc @rg3l3dr 8 | /crates/pallet-* @liuchengxu @nazar-pc @rg3l3dr @vedhavyas 9 | /crates/sp-* @liuchengxu @nazar-pc @rg3l3dr @vedhavyas 10 | /crates/subspace-archiving @liuchengxu @i1i1 @nazar-pc @rg3l3dr 11 | /crates/subspace-farmer @i1i1 @nazar-pc @rg3l3dr 12 | /crates/subspace-networking @nazar-pc @rg3l3dr @shamil-gadelshin 13 | /crates/subspace-runtime* @liuchengxu @nazar-pc @rg3l3dr @vedhavyas 14 | /crates/subspace-solving @i1i1 @liuchengxu @nazar-pc @rg3l3dr 15 | /crates/substrate @nazar-pc @rg3l3dr 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Forum for general questions about Subspace 4 | url: https://forum.subspace.network 5 | about: | 6 | If you have a question about protocol or anything else that is not an engineering-level discussion or definitely a 7 | bug, please create a topic on the forum (better yet, search if similar question was already asked). GitHub issues 8 | are for developers. 9 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Code contributor checklist: 2 | * [ ] I have read, understood and followed [contributing guide](https://github.com/subspace/subspace/blob/main/CONTRIBUTING.md) 3 | -------------------------------------------------------------------------------- /.github/workflows/Entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.apple.security.network.server 7 | 8 | 9 | 10 | com.apple.security.network.client 11 | 12 | 13 | 14 | com.apple.security.files.user-selected.read-write 15 | 16 | 17 | 18 | com.apple.security.cs.allow-unsigned-executable-memory 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/chain-spec-snapshot-build.yml: -------------------------------------------------------------------------------- 1 | # This action enabling building chain spec used in the node build, can be triggered manually or by release creation. 2 | # 3 | # Regular and raw chain specs are built both for releases and for manually triggered runs, uploaded to artifacts and 4 | # assets. 5 | name: Chain spec snapshot build 6 | 7 | on: 8 | workflow_dispatch: 9 | push: 10 | tags: 11 | - 'chain-spec-snapshot-*' 12 | - 'chain-spec-gemini-*' 13 | 14 | jobs: 15 | chains-spec: 16 | runs-on: ubuntu-22.04 17 | permissions: 18 | contents: write 19 | packages: write 20 | 21 | steps: 22 | - name: Build node image 23 | id: build 24 | uses: docker/build-push-action@c56af957549030174b10d6867f20e78cfd7debc5 # @v3.2.0 25 | with: 26 | file: Dockerfile-node 27 | push: false 28 | 29 | - name: Generate testnet chain specifications 30 | run: | 31 | docker run --rm -u root ${{ steps.build.outputs.digest }} build-spec --chain gemini-3d-compiled --disable-default-bootnode > chain-spec-gemini-3d.json 32 | docker run --rm -u root ${{ steps.build.outputs.digest }} build-spec --chain gemini-3d-compiled --disable-default-bootnode --raw > chain-spec-raw-gemini-3d.json 33 | 34 | - name: Upload chain specifications to artifacts 35 | uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # @v3.1.1 36 | with: 37 | name: chain-specifications 38 | path: | 39 | chain-spec-gemini-3d.json 40 | chain-spec-raw-gemini-3d.json 41 | if-no-files-found: error 42 | 43 | - name: Upload chain specifications to assets 44 | uses: alexellis/upload-assets@259de5111cb56966d046ced998941e93f91d2c93 # @0.4.0 45 | env: 46 | GITHUB_TOKEN: ${{ github.token }} 47 | with: 48 | asset_paths: '["chain-spec-gemini-3d.json", "chain-spec-raw-gemini-3d.json"]' 49 | -------------------------------------------------------------------------------- /.github/workflows/runtime-snapshot-build.yml: -------------------------------------------------------------------------------- 1 | # This action enabling building WASM runtime used for forkless runtime upgrades, can be triggered manually or by 2 | # release creation. 3 | # 4 | # WASM bundles are built both for releases and for manually triggered runs, uploaded to artifacts and assets. 5 | name: Runtime snapshot build 6 | 7 | on: 8 | workflow_dispatch: 9 | push: 10 | tags: 11 | - 'runtime-snapshot-*' 12 | - 'runtime-gemini-*' 13 | 14 | jobs: 15 | runtime: 16 | runs-on: ubuntu-22.04 17 | permissions: 18 | contents: write 19 | packages: write 20 | 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # @v3.1.0 24 | 25 | - name: Build runtime 26 | id: build 27 | uses: docker/build-push-action@c56af957549030174b10d6867f20e78cfd7debc5 # @v3.2.0 28 | with: 29 | file: Dockerfile-runtime 30 | push: false 31 | 32 | - name: Extract runtime 33 | run: | 34 | SPEC_VERSION=$(sed -nr 's/.*spec_version: ([0-9]+),/\1/p' crates/subspace-runtime/src/lib.rs) 35 | docker run --rm -u root ${{ steps.build.outputs.digest }} > subspace_runtime-$SPEC_VERSION.compact.compressed.wasm 36 | echo "SPEC_VERSION=$SPEC_VERSION" >> $GITHUB_ENV 37 | 38 | - name: Upload runtime to artifacts 39 | uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # @v3.1.1 40 | with: 41 | name: subspace_runtime 42 | path: | 43 | subspace_runtime-${{ env.SPEC_VERSION }}.compact.compressed.wasm 44 | if-no-files-found: error 45 | 46 | - name: Upload runtime to assets 47 | uses: alexellis/upload-assets@259de5111cb56966d046ced998941e93f91d2c93 # @0.4.0 48 | env: 49 | GITHUB_TOKEN: ${{ github.token }} 50 | with: 51 | asset_paths: '["subspace_runtime-${{ env.SPEC_VERSION }}.compact.compressed.wasm"]' 52 | # Only run for releases 53 | if: github.event_name == 'push' && github.ref_type == 'tag' 54 | -------------------------------------------------------------------------------- /.github/workflows/rustdoc.yml: -------------------------------------------------------------------------------- 1 | name: rustdoc 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: 9 | group: rustdoc-${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | env: 13 | CARGO_INCREMENTAL: 0 14 | CARGO_NET_RETRY: 10 15 | RUSTUP_MAX_RETRIES: 10 16 | 17 | jobs: 18 | rustdoc: 19 | runs-on: ubuntu-22.04 20 | 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # @v3.1.0 24 | 25 | - name: Install Protoc 26 | uses: arduino/setup-protoc@64c0c85d18e984422218383b81c52f8b077404d3 # @v1.1.2 27 | with: 28 | repo-token: ${{ secrets.GITHUB_TOKEN }} 29 | 30 | # Build the rust crate docs 31 | - name: Build Documentation 32 | run: cargo doc --all --no-deps --lib 33 | env: 34 | RUSTDOCFLAGS: "-Z unstable-options --enable-index-page" 35 | 36 | - name: Deploy Docs 37 | uses: JamesIves/github-pages-deploy-action@ba1486788b0490a235422264426c45848eac35c6 # @v4.4.1 38 | with: 39 | branch: gh-pages 40 | folder: target/doc 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /target 3 | -------------------------------------------------------------------------------- /Dockerfile-bootstrap-node: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG RUSTC_VERSION=nightly-2023-05-16 4 | ARG PROFILE=production 5 | ARG RUSTFLAGS 6 | # Workaround for https://github.com/rust-lang/cargo/issues/10583 7 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 8 | # Incremental compilation here isn't helpful 9 | ENV CARGO_INCREMENTAL=0 10 | 11 | WORKDIR /code 12 | 13 | RUN \ 14 | apt-get update && \ 15 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 16 | ca-certificates \ 17 | protobuf-compiler \ 18 | curl \ 19 | git \ 20 | llvm \ 21 | clang \ 22 | cmake \ 23 | make && \ 24 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain $RUSTC_VERSION 25 | 26 | RUN /root/.cargo/bin/rustup target add wasm32-unknown-unknown 27 | 28 | COPY Cargo.lock /code/Cargo.lock 29 | COPY Cargo.toml /code/Cargo.toml 30 | COPY rust-toolchain.toml /code/rust-toolchain.toml 31 | 32 | COPY crates /code/crates 33 | COPY domains /code/domains 34 | COPY orml /code/orml 35 | COPY test /code/test 36 | 37 | # Up until this line all Rust images in this repo should be the same to share the same layers 38 | 39 | RUN \ 40 | /root/.cargo/bin/cargo build \ 41 | --locked \ 42 | -Z build-std \ 43 | --profile $PROFILE \ 44 | --bin subspace-bootstrap-node \ 45 | --target $(uname -p)-unknown-linux-gnu && \ 46 | mv target/*/*/subspace-bootstrap-node subspace-bootstrap-node && \ 47 | rm -rf target 48 | 49 | FROM ubuntu:20.04 50 | 51 | COPY --from=0 /code/subspace-bootstrap-node /subspace-bootstrap-node 52 | 53 | USER nobody:nogroup 54 | 55 | ENTRYPOINT ["/subspace-bootstrap-node"] 56 | -------------------------------------------------------------------------------- /Dockerfile-bootstrap-node.aarch64: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG RUSTC_VERSION=nightly-2023-05-16 4 | ARG PROFILE=production 5 | ARG RUSTFLAGS 6 | # Workaround for https://github.com/rust-lang/cargo/issues/10583 7 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 8 | # Incremental compilation here isn't helpful 9 | ENV CARGO_INCREMENTAL=0 10 | 11 | WORKDIR /code 12 | 13 | RUN \ 14 | apt-get update && \ 15 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 16 | ca-certificates \ 17 | protobuf-compiler \ 18 | curl \ 19 | git \ 20 | llvm \ 21 | clang \ 22 | cmake \ 23 | make && \ 24 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain $RUSTC_VERSION 25 | 26 | RUN /root/.cargo/bin/rustup target add wasm32-unknown-unknown 27 | 28 | COPY Cargo.lock /code/Cargo.lock 29 | COPY Cargo.toml /code/Cargo.toml 30 | COPY rust-toolchain.toml /code/rust-toolchain.toml 31 | 32 | COPY crates /code/crates 33 | COPY domains /code/domains 34 | COPY orml /code/orml 35 | COPY test /code/test 36 | 37 | # Up until this line all Rust images in this repo should be the same to share the same layers 38 | 39 | ENV RUSTFLAGS="${RUSTFLAGS} -C linker=aarch64-linux-gnu-gcc" 40 | 41 | # Dependencies necessary for successful cross-compilation 42 | RUN \ 43 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 44 | g++-aarch64-linux-gnu \ 45 | gcc-aarch64-linux-gnu \ 46 | libc6-dev-arm64-cross 47 | 48 | # TODO: Following package is not necessary on Ubuntu 22.04, but RocksDb compilation fails otherwise on Ubuntu 20.04 49 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends g++-9-multilib 50 | 51 | RUN \ 52 | /root/.cargo/bin/cargo build \ 53 | --locked \ 54 | -Z build-std \ 55 | --profile $PROFILE \ 56 | --bin subspace-bootstrap-node \ 57 | --target aarch64-unknown-linux-gnu && \ 58 | mv target/*/*/subspace-bootstrap-node subspace-bootstrap-node && \ 59 | rm -rf target 60 | 61 | FROM arm64v8/ubuntu:20.04 62 | 63 | COPY --from=0 /code/subspace-bootstrap-node /subspace-bootstrap-node 64 | 65 | USER nobody:nogroup 66 | 67 | ENTRYPOINT ["/subspace-bootstrap-node"] 68 | -------------------------------------------------------------------------------- /Dockerfile-farmer: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG RUSTC_VERSION=nightly-2023-05-16 4 | ARG PROFILE=production 5 | ARG RUSTFLAGS 6 | # Workaround for https://github.com/rust-lang/cargo/issues/10583 7 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 8 | # Incremental compilation here isn't helpful 9 | ENV CARGO_INCREMENTAL=0 10 | 11 | WORKDIR /code 12 | 13 | RUN \ 14 | apt-get update && \ 15 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 16 | ca-certificates \ 17 | protobuf-compiler \ 18 | curl \ 19 | git \ 20 | llvm \ 21 | clang \ 22 | cmake \ 23 | make && \ 24 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain $RUSTC_VERSION 25 | 26 | RUN /root/.cargo/bin/rustup target add wasm32-unknown-unknown 27 | 28 | COPY Cargo.lock /code/Cargo.lock 29 | COPY Cargo.toml /code/Cargo.toml 30 | COPY rust-toolchain.toml /code/rust-toolchain.toml 31 | 32 | COPY crates /code/crates 33 | COPY domains /code/domains 34 | COPY orml /code/orml 35 | COPY test /code/test 36 | 37 | # Up until this line all Rust images in this repo should be the same to share the same layers 38 | 39 | RUN \ 40 | /root/.cargo/bin/cargo build \ 41 | --locked \ 42 | -Z build-std \ 43 | --profile $PROFILE \ 44 | --bin subspace-farmer \ 45 | --target $(uname -p)-unknown-linux-gnu && \ 46 | mv target/*/*/subspace-farmer subspace-farmer && \ 47 | rm -rf target 48 | 49 | FROM ubuntu:20.04 50 | 51 | COPY --from=0 /code/subspace-farmer /subspace-farmer 52 | 53 | RUN mkdir /var/subspace && chown nobody:nogroup /var/subspace 54 | 55 | VOLUME /var/subspace 56 | 57 | USER nobody:nogroup 58 | 59 | ENTRYPOINT ["/subspace-farmer"] 60 | -------------------------------------------------------------------------------- /Dockerfile-farmer.aarch64: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG RUSTC_VERSION=nightly-2023-05-16 4 | ARG PROFILE=production 5 | ARG RUSTFLAGS 6 | # Workaround for https://github.com/rust-lang/cargo/issues/10583 7 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 8 | # Incremental compilation here isn't helpful 9 | ENV CARGO_INCREMENTAL=0 10 | 11 | WORKDIR /code 12 | 13 | RUN \ 14 | apt-get update && \ 15 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 16 | ca-certificates \ 17 | protobuf-compiler \ 18 | curl \ 19 | git \ 20 | llvm \ 21 | clang \ 22 | cmake \ 23 | make && \ 24 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain $RUSTC_VERSION 25 | 26 | RUN /root/.cargo/bin/rustup target add wasm32-unknown-unknown 27 | 28 | COPY Cargo.lock /code/Cargo.lock 29 | COPY Cargo.toml /code/Cargo.toml 30 | COPY rust-toolchain.toml /code/rust-toolchain.toml 31 | 32 | COPY crates /code/crates 33 | COPY domains /code/domains 34 | COPY orml /code/orml 35 | COPY test /code/test 36 | 37 | # Up until this line all Rust images in this repo should be the same to share the same layers 38 | 39 | ENV RUSTFLAGS="${RUSTFLAGS} -C linker=aarch64-linux-gnu-gcc" 40 | 41 | # Dependencies necessary for successful cross-compilation 42 | RUN \ 43 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 44 | g++-aarch64-linux-gnu \ 45 | gcc-aarch64-linux-gnu \ 46 | libc6-dev-arm64-cross 47 | 48 | # TODO: Following package is not necessary on Ubuntu 22.04, but RocksDb compilation fails otherwise on Ubuntu 20.04 49 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends g++-9-multilib 50 | 51 | RUN \ 52 | /root/.cargo/bin/cargo build \ 53 | --locked \ 54 | -Z build-std \ 55 | --profile $PROFILE \ 56 | --bin subspace-farmer \ 57 | --target aarch64-unknown-linux-gnu && \ 58 | mv target/*/*/subspace-farmer subspace-farmer && \ 59 | rm -rf target 60 | 61 | FROM arm64v8/ubuntu:20.04 62 | 63 | COPY --from=0 /code/subspace-farmer /subspace-farmer 64 | 65 | RUN mkdir /var/subspace && chown nobody:nogroup /var/subspace 66 | 67 | VOLUME /var/subspace 68 | 69 | USER nobody:nogroup 70 | 71 | ENTRYPOINT ["/subspace-farmer"] 72 | -------------------------------------------------------------------------------- /Dockerfile-node: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG RUSTC_VERSION=nightly-2023-05-16 4 | ARG PROFILE=production 5 | ARG RUSTFLAGS 6 | # Workaround for https://github.com/rust-lang/cargo/issues/10583 7 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 8 | # Incremental compilation here isn't helpful 9 | ENV CARGO_INCREMENTAL=0 10 | 11 | WORKDIR /code 12 | 13 | RUN \ 14 | apt-get update && \ 15 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 16 | ca-certificates \ 17 | protobuf-compiler \ 18 | curl \ 19 | git \ 20 | llvm \ 21 | clang \ 22 | cmake \ 23 | make && \ 24 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain $RUSTC_VERSION 25 | 26 | RUN /root/.cargo/bin/rustup target add wasm32-unknown-unknown 27 | 28 | COPY Cargo.lock /code/Cargo.lock 29 | COPY Cargo.toml /code/Cargo.toml 30 | COPY rust-toolchain.toml /code/rust-toolchain.toml 31 | 32 | COPY crates /code/crates 33 | COPY domains /code/domains 34 | COPY orml /code/orml 35 | COPY test /code/test 36 | 37 | # Up until this line all Rust images in this repo should be the same to share the same layers 38 | 39 | ARG SUBSTRATE_CLI_GIT_COMMIT_HASH 40 | 41 | RUN \ 42 | /root/.cargo/bin/cargo build \ 43 | --locked \ 44 | -Z build-std \ 45 | --profile $PROFILE \ 46 | --bin subspace-node \ 47 | --target $(uname -p)-unknown-linux-gnu && \ 48 | mv target/*/*/subspace-node subspace-node && \ 49 | rm -rf target 50 | 51 | FROM ubuntu:20.04 52 | 53 | RUN \ 54 | apt-get update && \ 55 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates curl && \ 56 | apt-get clean && \ 57 | rm -rf /var/lib/apt/lists/* 58 | 59 | HEALTHCHECK CMD curl \ 60 | -H "Content-Type: application/json" \ 61 | -d '{ "id": 1, "jsonrpc": "2.0", "method": "system_health", "params": [] }' \ 62 | -f "http://localhost:9933" 63 | 64 | COPY --from=0 /code/subspace-node /subspace-node 65 | 66 | RUN mkdir /var/subspace && chown nobody:nogroup /var/subspace 67 | 68 | VOLUME /var/subspace 69 | 70 | USER nobody:nogroup 71 | 72 | ENTRYPOINT ["/subspace-node"] 73 | -------------------------------------------------------------------------------- /Dockerfile-node.aarch64: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG RUSTC_VERSION=nightly-2023-05-16 4 | ARG PROFILE=production 5 | ARG RUSTFLAGS 6 | # Workaround for https://github.com/rust-lang/cargo/issues/10583 7 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 8 | # Incremental compilation here isn't helpful 9 | ENV CARGO_INCREMENTAL=0 10 | 11 | WORKDIR /code 12 | 13 | RUN \ 14 | apt-get update && \ 15 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 16 | ca-certificates \ 17 | protobuf-compiler \ 18 | curl \ 19 | git \ 20 | llvm \ 21 | clang \ 22 | cmake \ 23 | make && \ 24 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain $RUSTC_VERSION 25 | 26 | RUN /root/.cargo/bin/rustup target add wasm32-unknown-unknown 27 | 28 | COPY Cargo.lock /code/Cargo.lock 29 | COPY Cargo.toml /code/Cargo.toml 30 | COPY rust-toolchain.toml /code/rust-toolchain.toml 31 | 32 | COPY crates /code/crates 33 | COPY domains /code/domains 34 | COPY orml /code/orml 35 | COPY test /code/test 36 | 37 | # Up until this line all Rust images in this repo should be the same to share the same layers 38 | 39 | ENV RUSTFLAGS="${RUSTFLAGS} -C linker=aarch64-linux-gnu-gcc" 40 | 41 | # Dependencies necessary for successful cross-compilation 42 | RUN \ 43 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 44 | g++-aarch64-linux-gnu \ 45 | gcc-aarch64-linux-gnu \ 46 | libc6-dev-arm64-cross 47 | 48 | RUN \ 49 | /root/.cargo/bin/cargo build \ 50 | --locked \ 51 | -Z build-std \ 52 | --profile $PROFILE \ 53 | --bin subspace-node \ 54 | --target aarch64-unknown-linux-gnu && \ 55 | mv target/*/*/subspace-node subspace-node && \ 56 | rm -rf target 57 | 58 | ARG SUBSTRATE_CLI_GIT_COMMIT_HASH 59 | 60 | FROM arm64v8/ubuntu:20.04 61 | 62 | RUN \ 63 | apt-get update && \ 64 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates curl && \ 65 | apt-get clean && \ 66 | rm -rf /var/lib/apt/lists/* 67 | 68 | HEALTHCHECK CMD curl \ 69 | -H "Content-Type: application/json" \ 70 | -d '{ "id": 1, "jsonrpc": "2.0", "method": "system_health", "params": [] }' \ 71 | -f "http://localhost:9933" 72 | 73 | COPY --from=0 /code/subspace-node /subspace-node 74 | 75 | RUN mkdir /var/subspace && chown nobody:nogroup /var/subspace 76 | 77 | VOLUME /var/subspace 78 | 79 | USER nobody:nogroup 80 | 81 | ENTRYPOINT ["/subspace-node"] 82 | -------------------------------------------------------------------------------- /Dockerfile-runtime: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG RUSTC_VERSION=nightly-2023-05-16 4 | ARG PROFILE=production 5 | ARG RUSTFLAGS 6 | # Workaround for https://github.com/rust-lang/cargo/issues/10583 7 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 8 | # Incremental compilation here isn't helpful 9 | ENV CARGO_INCREMENTAL=0 10 | 11 | WORKDIR /code 12 | 13 | RUN \ 14 | apt-get update && \ 15 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 16 | ca-certificates \ 17 | curl \ 18 | git \ 19 | llvm \ 20 | clang \ 21 | cmake \ 22 | make && \ 23 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain $RUSTC_VERSION 24 | 25 | RUN /root/.cargo/bin/rustup target add wasm32-unknown-unknown 26 | 27 | COPY Cargo.lock /code/Cargo.lock 28 | COPY Cargo.toml /code/Cargo.toml 29 | COPY rust-toolchain.toml /code/rust-toolchain.toml 30 | 31 | COPY crates /code/crates 32 | COPY domains /code/domains 33 | COPY orml /code/orml 34 | COPY test /code/test 35 | 36 | # Up until this line all Rust images in this repo should be the same to share the same layers 37 | 38 | # TODO: Re-enable cost of storage in future 39 | RUN \ 40 | /root/.cargo/bin/cargo build \ 41 | --locked \ 42 | -Z build-std \ 43 | --profile $PROFILE \ 44 | --package subspace-runtime \ 45 | --features=subspace-runtime/do-not-enforce-cost-of-storage \ 46 | --target x86_64-unknown-linux-gnu && \ 47 | mv \ 48 | target/*/*/wbuild/subspace-runtime/subspace_runtime.compact.compressed.wasm \ 49 | subspace_runtime.compact.compressed.wasm && \ 50 | rm -rf target 51 | 52 | ENTRYPOINT ["/usr/bin/cat", "subspace_runtime.compact.compressed.wasm"] 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Subspace Network Monorepo 2 | 3 | [![Latest Release](https://img.shields.io/github/v/release/subspace/subspace?display_name=tag&style=flat-square)](https://github.com/subspace/subspace/releases) 4 | [![Downloads Latest](https://img.shields.io/github/downloads/subspace/subspace/latest/total?style=flat-square)](https://github.com/subspace/subspace/releases/latest) 5 | [![Rust](https://img.shields.io/github/actions/workflow/status/subspace/subspace/rust.yml?branch=main)](https://github.com/subspace/subspace/actions/workflows/rust.yaml) 6 | [![Rust Docs](https://img.shields.io/github/actions/workflow/status/subspace/subspace/rustdoc.yml?branch=main)](https://subspace.github.io/subspace) 7 | 8 | This is a mono repository for [Subspace Network](https://subspace.network/) implementation, primarily containing 9 | Subspace node/client using Substrate framework and farmer app implementations. 10 | 11 | ## Repository structure 12 | 13 | The structure of this repository is the following: 14 | 15 | - `crates` contains Subspace-specific Rust crates used to build node and farmer, most are following Substrate naming conventions 16 | - `subspace-node` is an implementation of the node for Subspace protocol 17 | - `subspace-farmer` is a CLI farmer app 18 | - `domains` contains client and runtime code for decoupled execution and domains 19 | - `orml` contains a fork of orml vesting pallet with modified dependencies 20 | 21 | ## How to run 22 | 23 | Please refer to [farming.md](/docs/farming.md) on how to run farmer. 24 | 25 | If you are looking to farm offline, or build from source for development purposes please refer to [development.md](/docs/development.md). 26 | -------------------------------------------------------------------------------- /crates/pallet-feeds/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-feeds" 3 | version = "0.1.0" 4 | authors = ["Serge Kovbasiuk "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Subspace node pallet for interacting with storage" 10 | readme = "README.md" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["x86_64-unknown-linux-gnu"] 14 | 15 | [dependencies] 16 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 17 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | log = { version = "0.4.19", default-features = false } 20 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 21 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } 25 | 26 | [dev-dependencies] 27 | serde = "1.0.159" 28 | sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 29 | 30 | [features] 31 | default = ["std"] 32 | std = [ 33 | "codec/std", 34 | "frame-support/std", 35 | "frame-system/std", 36 | "log/std", 37 | "scale-info/std", 38 | "sp-core/std", 39 | "sp-runtime/std", 40 | "sp-std/std", 41 | "subspace-core-primitives/std", 42 | ] 43 | try-runtime = ["frame-support/try-runtime"] 44 | -------------------------------------------------------------------------------- /crates/pallet-feeds/README.md: -------------------------------------------------------------------------------- 1 | # Pallet Feeds 2 | 3 | License: Apache-2.0 4 | 5 | Pallet feeds provides the interactions with Subspace storage. The main design goal for Feeds is not only to push objects 6 | to the Storage but also to provide a way for the for feed owners to inject some verification logic through `FeedProcessor` 7 | impls. 8 | 9 | ## Calls 10 | 11 | The pallet provides following calls. 12 | 1. Create(permissionless): Creates a new Feed for the caller 13 | 2. Update: Updates the Feeds with some initial data. All the underlying FeedProcessors 14 | will be reinitialized. 15 | 3. Transfer: Transfers a feed from one owner to another 16 | 4. Close: Closes the feed and doesn't accept any new objects 17 | 5. Put: Puts a new object in the Feed. The object is passed to FeedProcessor for verification if any. 18 | 19 | -------------------------------------------------------------------------------- /crates/pallet-grandpa-finality-verifier/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-grandpa-finality-verifier" 3 | version = "0.1.0" 4 | authors = ["Vedhavyas Singareddi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Pallet to verify GRANDPA finality proofs for Substrate based chains" 10 | readme = "README.md" 11 | 12 | [dependencies] 13 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } 14 | finality-grandpa = { version = "0.16.1", default-features = false } 15 | log = { version = "0.4.19", default-features = false } 16 | num-traits = { version = "0.2.15", default-features = false } 17 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 18 | serde = { version = "1.0.159", optional = true } 19 | 20 | # Substrate Dependencies 21 | 22 | frame-support = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 23 | frame-system = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 24 | sp-consensus-grandpa = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 25 | sp-core = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 26 | sp-runtime = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 27 | sp-std = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 28 | sp-trie = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 29 | 30 | [dev-dependencies] 31 | ed25519-dalek = { version = "1.0", default-features = false, features = ["u64_backend"] } 32 | sp-io = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 33 | sp-application-crypto = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 34 | 35 | [features] 36 | default = ["std"] 37 | std = [ 38 | "codec/std", 39 | "finality-grandpa/std", 40 | "frame-support/std", 41 | "frame-system/std", 42 | "log/std", 43 | "num-traits/std", 44 | "scale-info/std", 45 | "serde", 46 | "sp-consensus-grandpa/std", 47 | "sp-core/std", 48 | "sp-runtime/std", 49 | "sp-std/std", 50 | "sp-trie/std", 51 | ] 52 | -------------------------------------------------------------------------------- /crates/pallet-grandpa-finality-verifier/README.md: -------------------------------------------------------------------------------- 1 | # pallet-grandpa-finality-verifier 2 | License: Apache-2.0 3 | 4 | GRANDPA finality verifier is used to verify the justifications provided within the substrate based Blocks indexing them on our DSN. 5 | 6 | The pallet provides the following functionality 7 | - provides a basic abstraction over any substrate based chains through `Chain` trait. 8 | - decodes the block and its components. 9 | - verifies the blocks and its justifications using the current authority set the block was produced in 10 | - imports any authority set changes from the header after the verification 11 | 12 | This pallet does not 13 | - verifies or recognizes the forks. So this is left for the admin to reinitialize the chain state after the fork 14 | -------------------------------------------------------------------------------- /crates/pallet-grandpa-finality-verifier/src/tests/mock.rs: -------------------------------------------------------------------------------- 1 | use frame_support::weights::Weight; 2 | use frame_support::{construct_runtime, parameter_types}; 3 | use sp_runtime::testing::{Header, H256}; 4 | use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; 5 | use sp_runtime::Perbill; 6 | 7 | type AccountId = u64; 8 | pub(crate) type ChainId = u64; 9 | type Block = frame_system::mocking::MockBlock; 10 | type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; 11 | 12 | use crate as grandpa; 13 | 14 | construct_runtime! { 15 | pub struct TestRuntime where 16 | Block = Block, 17 | NodeBlock = Block, 18 | UncheckedExtrinsic = UncheckedExtrinsic, 19 | { 20 | System: frame_system::{Pallet, Call, Config, Storage, Event}, 21 | Grandpa: grandpa::{Pallet}, 22 | } 23 | } 24 | 25 | parameter_types! { 26 | pub const BlockHashCount: u64 = 250; 27 | pub const MaximumBlockWeight: Weight = Weight::from_parts(1024, 0); 28 | pub const MaximumBlockLength: u32 = 2 * 1024; 29 | pub const AvailableBlockRatio: Perbill = Perbill::one(); 30 | } 31 | 32 | impl frame_system::Config for TestRuntime { 33 | type RuntimeOrigin = RuntimeOrigin; 34 | type Index = u64; 35 | type RuntimeCall = RuntimeCall; 36 | type BlockNumber = u64; 37 | type Hash = H256; 38 | type Hashing = BlakeTwo256; 39 | type AccountId = AccountId; 40 | type Lookup = IdentityLookup; 41 | type Header = Header; 42 | type RuntimeEvent = (); 43 | type BlockHashCount = BlockHashCount; 44 | type Version = (); 45 | type PalletInfo = PalletInfo; 46 | type AccountData = (); 47 | type OnNewAccount = (); 48 | type OnKilledAccount = (); 49 | type BaseCallFilter = frame_support::traits::Everything; 50 | type SystemWeightInfo = (); 51 | type DbWeight = (); 52 | type BlockWeights = (); 53 | type BlockLength = (); 54 | type SS58Prefix = (); 55 | type OnSetCode = (); 56 | type MaxConsumers = frame_support::traits::ConstU32<16>; 57 | } 58 | 59 | impl grandpa::Config for TestRuntime { 60 | type ChainId = ChainId; 61 | } 62 | 63 | pub fn run_test(test: impl FnOnce() -> T) -> T { 64 | sp_io::TestExternalities::new(Default::default()).execute_with(test) 65 | } 66 | -------------------------------------------------------------------------------- /crates/pallet-object-store/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-object-store" 3 | version = "0.1.0" 4 | authors = ["Nazar Mokrynskyi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Subspace node pallet for simple objects storage" 10 | readme = "README.md" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["x86_64-unknown-linux-gnu"] 14 | 15 | [dependencies] 16 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 17 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | hex = { version = "0.4.3", default-features = false, features = ["alloc"] } 20 | log = { version = "0.4.19", default-features = false } 21 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 22 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } 24 | 25 | [dev-dependencies] 26 | serde = "1.0.159" 27 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 28 | sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 29 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 30 | 31 | [features] 32 | default = ["std"] 33 | std = [ 34 | "codec/std", 35 | "frame-support/std", 36 | "frame-system/std", 37 | "hex/std", 38 | "log/std", 39 | "scale-info/std", 40 | "sp-std/std", 41 | "subspace-core-primitives/std", 42 | ] 43 | try-runtime = ["frame-support/try-runtime"] 44 | -------------------------------------------------------------------------------- /crates/pallet-object-store/README.md: -------------------------------------------------------------------------------- 1 | # Pallet Object Store 2 | 3 | Subspace node pallet for simple objects storage 4 | 5 | License: Apache-2.0 6 | -------------------------------------------------------------------------------- /crates/pallet-object-store/src/mock.rs: -------------------------------------------------------------------------------- 1 | use frame_support::parameter_types; 2 | use frame_support::traits::{ConstU16, ConstU32, ConstU64}; 3 | use sp_core::H256; 4 | use sp_runtime::testing::Header; 5 | use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; 6 | 7 | type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; 8 | type Block = frame_system::mocking::MockBlock; 9 | 10 | frame_support::construct_runtime!( 11 | pub struct Test where 12 | Block = Block, 13 | NodeBlock = Block, 14 | UncheckedExtrinsic = UncheckedExtrinsic, 15 | { 16 | System: frame_system::{Pallet, Call, Config, Storage, Event}, 17 | ObjectStore: crate::{Pallet, Call, Event} 18 | } 19 | ); 20 | 21 | impl frame_system::Config for Test { 22 | type BaseCallFilter = frame_support::traits::Everything; 23 | type BlockWeights = (); 24 | type BlockLength = (); 25 | type DbWeight = (); 26 | type RuntimeOrigin = RuntimeOrigin; 27 | type RuntimeCall = RuntimeCall; 28 | type Index = u64; 29 | type BlockNumber = u64; 30 | type Hash = H256; 31 | type Hashing = BlakeTwo256; 32 | type AccountId = u64; 33 | type Lookup = IdentityLookup; 34 | type Header = Header; 35 | type RuntimeEvent = RuntimeEvent; 36 | type BlockHashCount = ConstU64<250>; 37 | type Version = (); 38 | type PalletInfo = PalletInfo; 39 | type AccountData = (); 40 | type OnNewAccount = (); 41 | type OnKilledAccount = (); 42 | type SystemWeightInfo = (); 43 | type SS58Prefix = ConstU16<42>; 44 | type OnSetCode = (); 45 | type MaxConsumers = ConstU32<16>; 46 | } 47 | 48 | parameter_types! { 49 | pub const ExistentialDeposit: u64 = 1; 50 | } 51 | 52 | impl crate::Config for Test { 53 | type RuntimeEvent = RuntimeEvent; 54 | } 55 | 56 | pub fn new_test_ext() -> sp_io::TestExternalities { 57 | let t = frame_system::GenesisConfig::default() 58 | .build_storage::() 59 | .unwrap(); 60 | 61 | let mut t: sp_io::TestExternalities = t.into(); 62 | 63 | t.execute_with(|| System::set_block_number(1)); 64 | 65 | t 66 | } 67 | -------------------------------------------------------------------------------- /crates/pallet-object-store/src/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::mock::{new_test_ext, ObjectStore, RuntimeEvent, RuntimeOrigin, System, Test}; 2 | use frame_support::assert_ok; 3 | use subspace_core_primitives::crypto; 4 | 5 | const ACCOUNT_ID: u64 = 100; 6 | 7 | #[test] 8 | fn can_do_put() { 9 | new_test_ext().execute_with(|| { 10 | let object = vec![1, 2, 3, 4, 5]; 11 | let object_id = crypto::blake2b_256_hash(&object); 12 | let object_size = object.len() as u32; 13 | 14 | assert_ok!(ObjectStore::put(RuntimeOrigin::signed(ACCOUNT_ID), object)); 15 | 16 | System::assert_last_event(RuntimeEvent::ObjectStore( 17 | crate::Event::::ObjectSubmitted { 18 | who: ACCOUNT_ID, 19 | object_id, 20 | object_size, 21 | }, 22 | )); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /crates/pallet-offences-subspace/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-offences-subspace" 3 | version = "0.1.0" 4 | authors = ["Parity Technologies ", "Subspace Labs "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "offences-subspace pallet" 10 | readme = "README.md" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["x86_64-unknown-linux-gnu"] 14 | 15 | [dependencies] 16 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 17 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | log = { version = "0.4.19", default-features = false } 20 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 21 | sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } 22 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | 25 | [dev-dependencies] 26 | sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 27 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 28 | schnorrkel = "0.9.1" 29 | 30 | [features] 31 | default = ["std"] 32 | std = [ 33 | "codec/std", 34 | "frame-support/std", 35 | "frame-system/std", 36 | "log/std", 37 | "scale-info/std", 38 | "sp-consensus-subspace/std", 39 | "sp-runtime/std", 40 | "sp-std/std", 41 | ] 42 | try-runtime = ["frame-support/try-runtime"] 43 | -------------------------------------------------------------------------------- /crates/pallet-offences-subspace/README.md: -------------------------------------------------------------------------------- 1 | # Offences Module (Subspace variant) 2 | 3 | Tracks reported offences 4 | 5 | License: Apache-2.0 6 | -------------------------------------------------------------------------------- /crates/pallet-rewards/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-rewards" 3 | version = "0.1.0" 4 | authors = ["Nazar Mokrynskyi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Pallet for issuing rewards to block producers" 10 | readme = "README.md" 11 | include = [ 12 | "/src", 13 | "/Cargo.toml", 14 | "/README.md", 15 | ] 16 | 17 | [package.metadata.docs.rs] 18 | targets = ["x86_64-unknown-linux-gnu"] 19 | 20 | [dependencies] 21 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 22 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 25 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } 27 | 28 | [features] 29 | default = ["std"] 30 | std = [ 31 | "codec/std", 32 | "frame-support/std", 33 | "frame-system/std", 34 | "scale-info/std", 35 | "sp-std/std", 36 | "subspace-runtime-primitives/std", 37 | ] 38 | try-runtime = ["frame-support/try-runtime"] 39 | -------------------------------------------------------------------------------- /crates/pallet-rewards/README.md: -------------------------------------------------------------------------------- 1 | # Pallet Rewards 2 | 3 | Pallet for issuing rewards to block producers. 4 | 5 | License: Apache-2.0 6 | -------------------------------------------------------------------------------- /crates/pallet-rewards/src/default_weights.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Default weights for the Rewards Pallet 17 | //! This file was not auto-generated. 18 | 19 | use frame_support::weights::Weight; 20 | 21 | impl crate::WeightInfo for () { 22 | fn on_initialize() -> Weight { 23 | // TODO: Correct value 24 | Weight::from_parts(1, 0) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/pallet-runtime-configs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-runtime-configs" 3 | version = "0.1.0" 4 | authors = ["Liu-Cheng Xu "] 5 | edition = "2021" 6 | license = "GPL-3.0-or-later WITH Classpath-exception-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Pallet for tweaking the runtime configs for multiple network" 10 | include = [ 11 | "/src", 12 | "/Cargo.toml", 13 | ] 14 | 15 | [package.metadata.docs.rs] 16 | targets = ["x86_64-unknown-linux-gnu"] 17 | 18 | [dependencies] 19 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 20 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 23 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | 25 | [features] 26 | default = ["std"] 27 | std = [ 28 | "codec/std", 29 | "frame-support/std", 30 | "frame-system/std", 31 | "scale-info/std", 32 | "sp-runtime/std", 33 | ] 34 | try-runtime = ["frame-support/try-runtime"] 35 | -------------------------------------------------------------------------------- /crates/pallet-settlement/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-settlement" 3 | version = "0.1.0" 4 | authors = ["Subspace Labs "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Subspace receipts pallet" 10 | 11 | [package.metadata.docs.rs] 12 | targets = ["x86_64-unknown-linux-gnu"] 13 | 14 | [dependencies] 15 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 16 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 17 | frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | log = { version = "0.4.19", default-features = false } 19 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 20 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } 22 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | 25 | [features] 26 | default = ["std"] 27 | std = [ 28 | "frame-support/std", 29 | "frame-system/std", 30 | "log/std", 31 | "sp-core/std", 32 | "sp-domains/std", 33 | "sp-runtime/std", 34 | "sp-std/std", 35 | ] 36 | try-runtime = ["frame-support/try-runtime"] 37 | -------------------------------------------------------------------------------- /crates/pallet-subspace/README.md: -------------------------------------------------------------------------------- 1 | Subspace consensus pallet. 2 | 3 | This pallet is in many ways complementary to `sc-consensus-subspace`. 4 | 5 | Pallet maintains crucial state required for Subspace Proof-of-Archival-Storage consensus: 6 | * global randomness 7 | * based on c-correlation from 8 | * is used to later derive together with time slot a global challenge 9 | * solution range, which is a range of valid solution for Proof-of-Archival-Storage puzzle 10 | * conceptually similar to work difficulty in Proof-of-Work consensus 11 | * is updated every Era 12 | * inherents for: 13 | * storing segment headers and maintaining mapping from segment index to corresponding segment commitment such that 14 | validity of piece from solution can be checked later 15 | * handling of farmer equivocation (together with `pallet-offences-subspace`) and maintaining list of blocked farmers 16 | (effectively burned plots) 17 | 18 | Pallet also provides handy API for finding block author, block reward address, randomness and some others. 19 | 20 | License: Apache-2.0 21 | -------------------------------------------------------------------------------- /crates/pallet-transaction-fees/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-transaction-fees" 3 | version = "0.1.0" 4 | authors = ["Nazar Mokrynskyi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Pallet for charging and re-distributing transaction fees" 10 | readme = "README.md" 11 | include = [ 12 | "/src", 13 | "/Cargo.toml", 14 | "/README.md", 15 | ] 16 | 17 | [package.metadata.docs.rs] 18 | targets = ["x86_64-unknown-linux-gnu"] 19 | 20 | [dependencies] 21 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 22 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 25 | subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } 26 | 27 | [features] 28 | default = ["std"] 29 | std = [ 30 | "codec/std", 31 | "frame-support/std", 32 | "frame-system/std", 33 | "scale-info/std", 34 | "subspace-runtime-primitives/std", 35 | ] 36 | try-runtime = ["frame-support/try-runtime"] 37 | -------------------------------------------------------------------------------- /crates/pallet-transaction-fees/README.md: -------------------------------------------------------------------------------- 1 | # Pallet Transaction Fees 2 | 3 | Pallet for charging and re-distributing transaction fees. 4 | 5 | License: Apache-2.0 6 | -------------------------------------------------------------------------------- /crates/pallet-transaction-fees/src/default_weights.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Default weights for the Rewards Pallet 17 | //! This file was not auto-generated. 18 | 19 | use frame_support::weights::Weight; 20 | 21 | impl crate::WeightInfo for () { 22 | fn on_initialize() -> Weight { 23 | // TODO: Correct value 24 | Weight::from_parts(1, 0) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/sc-consensus-fraud-proof/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sc-consensus-fraud-proof" 3 | description = "Subspace fraud proof verification in consensus" 4 | license = "GPL-3.0-or-later WITH Classpath-exception-2.0" 5 | version = "0.1.0" 6 | authors = ["Liu-Cheng Xu "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | ] 12 | 13 | [dependencies] 14 | async-trait = "0.1.68" 15 | codec = { package = "parity-scale-codec", version = "3.4.0", features = ["derive"] } 16 | sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 17 | sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | sp-domains = { version = "0.1.0", path = "../sp-domains" } 20 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | sp-settlement = { version = "0.1.0", path = "../sp-settlement" } 22 | subspace-fraud-proof = { version = "0.1.0", path = "../subspace-fraud-proof" } 23 | -------------------------------------------------------------------------------- /crates/sc-consensus-subspace-rpc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sc-consensus-subspace-rpc" 3 | version = "0.1.0" 4 | authors = ["Parity Technologies ", "Subspace Labs "] 5 | description = "RPC extensions for the Subspace consensus algorithm" 6 | edition = "2021" 7 | license = "GPL-3.0-or-later WITH Classpath-exception-2.0" 8 | homepage = "https://subspace.network" 9 | repository = "https://github.com/subspace/subspace" 10 | readme = "README.md" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["x86_64-unknown-linux-gnu"] 14 | 15 | [dependencies] 16 | async-oneshot = "0.5.0" 17 | futures = "0.3.28" 18 | futures-timer = "3.0.2" 19 | jsonrpsee = { version = "0.16.2", features = ["server", "macros"] } 20 | parity-scale-codec = "3.4.0" 21 | parking_lot = "0.12.1" 22 | sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sc-consensus-subspace = { version = "0.1.0", path = "../sc-consensus-subspace" } 24 | sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 25 | sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 27 | sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } 28 | sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 29 | sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 30 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 31 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 32 | subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } 33 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } 34 | subspace-farmer-components = { version = "0.1.0", path = "../subspace-farmer-components" } 35 | subspace-networking = { version = "0.1.0", path = "../subspace-networking" } 36 | subspace-rpc-primitives = { version = "0.1.0", path = "../subspace-rpc-primitives" } 37 | tracing = "0.1.37" 38 | -------------------------------------------------------------------------------- /crates/sc-consensus-subspace-rpc/README.md: -------------------------------------------------------------------------------- 1 | RPC api for Subspace Consensus. 2 | 3 | License: GPL-3.0-or-later WITH Classpath-exception-2.0 4 | -------------------------------------------------------------------------------- /crates/sc-consensus-subspace/README.md: -------------------------------------------------------------------------------- 1 | # Subspace Proof-of-Archival-Storage consensus 2 | 3 | Subspace is a slot-based block production mechanism which uses a Proof-of-Archival-Storage to randomly perform the slot 4 | allocation. On every slot, all the farmers evaluate their disk-based plot. If they have a tag (reflecting a commitment 5 | to a valid encoding) that it is lower than a given threshold (which is proportional to the total space pledged by the 6 | network) they may produce a new block. 7 | 8 | Core inputs to the Proof-of-Archival-Storage, such as global randomness and solution range come from the runtime, 9 | see `pallet-subspace` for details. 10 | 11 | The fork choice rule is weight-based, where weight is derived from the distance between solution proposed in a block and 12 | the local challenge for particular farmer. The heaviest chain (represents a chain with more storage pledged to it) 13 | will be preferred over alternatives or longest chain is in case of a tie. 14 | 15 | For a more in-depth analysis of Subspace consensus can be found in our 16 | [consensus whitepaper](https://subspace.network/news/subspace-network-whitepaper). 17 | 18 | This crate contains following major components: 19 | * worker (`sc-consensus-slots`) for claiming slots (block production) 20 | * block verifier that stateless verification of signature and Proof-of-Space 21 | * block import that verifies Proof-of-Archival-Storage and triggers archiving of the history 22 | * archiver worker triggered by block import that ensures history is archived and segment headers are produced at precisely 23 | the right time before finishing block import 24 | 25 | License: GPL-3.0-or-later WITH Classpath-exception-2.0 26 | -------------------------------------------------------------------------------- /crates/sc-subspace-block-relay/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sc-subspace-block-relay" 3 | description = "Block relay implementation" 4 | license = "MIT OR Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Rahul Subramaniyam "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | ] 12 | 13 | [dependencies] 14 | async-channel = "1.8.0" 15 | async-trait = "0.1.68" 16 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 17 | futures = "0.3.28" 18 | lru = "0.10.0" 19 | parking_lot = "0.12.1" 20 | sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 25 | sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 27 | thiserror = "1.0.38" 28 | tracing = "0.1.37" 29 | 30 | -------------------------------------------------------------------------------- /crates/sc-subspace-block-relay/src/protocol.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod compact_block; 2 | -------------------------------------------------------------------------------- /crates/sc-subspace-chain-specs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sc-subspace-chain-specs" 3 | description = "Chain specification data structures tailored for Subspace" 4 | license = "GPL-3.0-or-later WITH Classpath-exception-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | "/README.md", 12 | ] 13 | 14 | [dependencies] 15 | sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 16 | sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 17 | sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | serde = "1.0.159" 19 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | -------------------------------------------------------------------------------- /crates/sc-subspace-chain-specs/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | //! Chain specification data structures tailored for Subspace. 18 | 19 | mod utils; 20 | 21 | pub use utils::SerializableChainSpec; 22 | 23 | use sc_chain_spec::{ChainSpecExtension, NoExtension, RuntimeGenesis}; 24 | use sc_service::ChainSpecExtension; 25 | use serde::de::DeserializeOwned; 26 | use serde::{Deserialize, Serialize}; 27 | 28 | /// The extensions for the [`ConsensusChainSpec`]. 29 | #[derive(Serialize, Deserialize, ChainSpecExtension)] 30 | #[serde(deny_unknown_fields, rename_all = "camelCase")] 31 | #[serde(bound = "")] 32 | pub struct ChainSpecExtensions 33 | where 34 | ExecutionGenesisConfig: RuntimeGenesis + 'static, 35 | Extensions: ChainSpecExtension + DeserializeOwned + Clone + Send + Sync + 'static, 36 | { 37 | /// Chain spec of execution chain. 38 | pub execution_chain_spec: ExecutionChainSpec, 39 | } 40 | 41 | impl Clone 42 | for ChainSpecExtensions 43 | where 44 | ExecutionGenesisConfig: RuntimeGenesis + 'static, 45 | Extensions: ChainSpecExtension + DeserializeOwned + Clone + Send + Sync + 'static, 46 | { 47 | fn clone(&self) -> Self { 48 | Self { 49 | execution_chain_spec: self.execution_chain_spec.clone(), 50 | } 51 | } 52 | } 53 | 54 | /// Specialized `ChainSpec` for the consensus runtime. 55 | pub type ConsensusChainSpec = 56 | SerializableChainSpec>; 57 | 58 | /// Specialized `ChainSpec` for the execution runtime. 59 | pub type ExecutionChainSpec = 60 | SerializableChainSpec; 61 | -------------------------------------------------------------------------------- /crates/sp-consensus-subspace/README.md: -------------------------------------------------------------------------------- 1 | Primitives for Subspace Consensus. Based on a fork of `sp_consensus_babe` 2 | 3 | License: Apache-2.0 4 | -------------------------------------------------------------------------------- /crates/sp-domains/src/merkle_tree.rs: -------------------------------------------------------------------------------- 1 | use crate::ExecutorPublicKey; 2 | use blake2::digest::typenum::U32; 3 | use blake2::digest::FixedOutput; 4 | use blake2::{Blake2b, Digest}; 5 | use parity_scale_codec::{Decode, Encode}; 6 | use rs_merkle::Hasher; 7 | use scale_info::TypeInfo; 8 | use sp_runtime::traits::{BlakeTwo256, Hash}; 9 | use sp_std::vec::Vec; 10 | use subspace_core_primitives::Blake2b256Hash; 11 | 12 | /// Merkle tree using [`Blake2b256Algorithm`]. 13 | pub type MerkleTree = rs_merkle::MerkleTree; 14 | 15 | /// Merkle proof using [`Blake2b256Algorithm`]. 16 | pub type MerkleProof = rs_merkle::MerkleProof; 17 | 18 | /// Merke proof based Witness. 19 | #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone, Default)] 20 | pub struct Witness { 21 | /// Index of the leaf the proof is for. 22 | pub leaf_index: u32, 23 | /// Merkle proof in bytes. 24 | pub proof: Vec, 25 | /// Number of leaves in the original tree. 26 | pub number_of_leaves: u32, 27 | } 28 | 29 | #[derive(Clone)] 30 | pub struct Blake2b256Algorithm(Blake2b); 31 | 32 | impl Default for Blake2b256Algorithm { 33 | #[inline] 34 | fn default() -> Self { 35 | Self(Blake2b::new()) 36 | } 37 | } 38 | 39 | impl Hasher for Blake2b256Algorithm { 40 | type Hash = Blake2b256Hash; 41 | 42 | fn hash(data: &[u8]) -> Blake2b256Hash { 43 | let mut hasher = Blake2b::new(); 44 | hasher.update(data); 45 | hasher.finalize_fixed().into() 46 | } 47 | } 48 | 49 | /// Constructs a merkle tree from given authorities. 50 | pub fn authorities_merkle_tree( 51 | authorities: &[(ExecutorPublicKey, StakeWeight)], 52 | ) -> MerkleTree { 53 | let leaves = authorities 54 | .iter() 55 | .map(|x| BlakeTwo256::hash_of(&x.encode()).to_fixed_bytes()) 56 | .collect::>(); 57 | MerkleTree::from_leaves(&leaves) 58 | } 59 | 60 | #[cfg(test)] 61 | mod tests { 62 | use super::MerkleTree; 63 | 64 | #[test] 65 | fn test_merkle_tree() { 66 | let leaves = [[1u8; 32], [2u8; 32], [3u8; 32], [4u8; 32], [5u8; 32]]; 67 | 68 | let merkle_tree = MerkleTree::from_leaves(&leaves); 69 | 70 | let indices_to_prove = (0..leaves.len()).collect::>(); 71 | let leaves_to_prove = leaves 72 | .get(0..leaves.len()) 73 | .expect("can't get leaves to prove"); 74 | 75 | let proof = merkle_tree.proof(&indices_to_prove); 76 | let root = merkle_tree.root().expect("couldn't get the merkle root"); 77 | 78 | assert!(proof.verify(root, &indices_to_prove, leaves_to_prove, leaves.len())); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /crates/sp-domains/src/transaction.rs: -------------------------------------------------------------------------------- 1 | use crate::fraud_proof::FraudProof; 2 | use crate::OpaqueBundle; 3 | use parity_scale_codec::{Decode, Encode}; 4 | use scale_info::TypeInfo; 5 | use sp_runtime::traits::{Block as BlockT, NumberFor}; 6 | use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity}; 7 | 8 | /// Custom invalid validity code for the extrinsics in pallet-domains. 9 | #[repr(u8)] 10 | pub enum InvalidTransactionCode { 11 | BundleEquivicationProof = 101, 12 | TrasactionProof = 102, 13 | ExecutionReceipt = 103, 14 | Bundle = 104, 15 | FraudProof = 105, 16 | } 17 | 18 | impl From for InvalidTransaction { 19 | #[inline] 20 | fn from(invalid_code: InvalidTransactionCode) -> Self { 21 | InvalidTransaction::Custom(invalid_code as u8) 22 | } 23 | } 24 | 25 | impl From for TransactionValidity { 26 | #[inline] 27 | fn from(invalid_code: InvalidTransactionCode) -> Self { 28 | InvalidTransaction::Custom(invalid_code as u8).into() 29 | } 30 | } 31 | 32 | /// Object for performing the pre-validation in the transaction pool 33 | /// before calling into the regular `validate_transaction` runtime api. 34 | #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] 35 | pub enum PreValidationObject 36 | where 37 | Block: BlockT, 38 | { 39 | Null, 40 | FraudProof(FraudProof, Block::Hash>), 41 | Bundle(OpaqueBundle, Block::Hash, DomainHash>), 42 | } 43 | 44 | sp_api::decl_runtime_apis! { 45 | /// API for extracting the pre-validation objects in the primary chain transaction pool wrapper. 46 | pub trait PreValidationObjectApi { 47 | /// Extract the pre-validation object from the given extrinsic. 48 | fn extract_pre_validation_object(extrinsics: Block::Extrinsic) -> PreValidationObject; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /crates/sp-lightclient/README.md: -------------------------------------------------------------------------------- 1 | # Light client substrate primitives for Subspace 2 | -------------------------------------------------------------------------------- /crates/sp-objects/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sp-objects" 3 | version = "0.1.0" 4 | authors = ["Vedhavyas Singareddi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Primitives for Objects" 10 | readme = "README.md" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["x86_64-unknown-linux-gnu"] 14 | 15 | [dependencies] 16 | sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 17 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } 19 | subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } 20 | 21 | [features] 22 | default = ["std"] 23 | std = [ 24 | "sp-api/std", 25 | "sp-std/std", 26 | "subspace-core-primitives/std", 27 | "subspace-runtime-primitives/std", 28 | ] 29 | -------------------------------------------------------------------------------- /crates/sp-objects/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Primitives for Objects. 17 | 18 | #![cfg_attr(not(feature = "std"), no_std)] 19 | 20 | use sp_std::vec::Vec; 21 | use subspace_core_primitives::objects::BlockObjectMapping; 22 | use subspace_runtime_primitives::Hash; 23 | 24 | sp_api::decl_runtime_apis! { 25 | pub trait ObjectsApi { 26 | /// Returns all the validated object call hashes for a given block 27 | fn validated_object_call_hashes() -> Vec; 28 | 29 | /// Extract block object mapping for a given block 30 | fn extract_block_object_mapping(block: Block, validated_object_calls: Vec) -> BlockObjectMapping; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /crates/sp-settlement/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sp-settlement" 3 | version = "0.1.0" 4 | authors = ["Liu-Cheng Xu "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Primitives for Receipts" 10 | 11 | [package.metadata.docs.rs] 12 | targets = ["x86_64-unknown-linux-gnu"] 13 | 14 | [dependencies] 15 | codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false } 16 | sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 17 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } 19 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | 22 | [features] 23 | default = ["std"] 24 | std = [ 25 | "codec/std", 26 | "sp-api/std", 27 | "sp-core/std", 28 | "sp-domains/std", 29 | "sp-runtime/std", 30 | "sp-std/std", 31 | ] 32 | -------------------------------------------------------------------------------- /crates/subspace-archiving/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-archiving" 3 | description = "Collection of modules used for dealing with archived state of Subspace Network" 4 | license = "Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/benches", 10 | "/src", 11 | "/Cargo.toml", 12 | "/README.md", 13 | ] 14 | 15 | [lib] 16 | # Necessary for CLI options to work on benches 17 | bench = false 18 | 19 | [dependencies] 20 | parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } 21 | rayon = { version = "1.7.0", optional = true } 22 | serde = { version = "1.0.159", optional = true, features = ["derive"] } 23 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } 24 | subspace-erasure-coding = { version = "0.1.0", path = "../subspace-erasure-coding", default-features = false } 25 | thiserror = { version = "1.0.38", optional = true } 26 | 27 | [dev-dependencies] 28 | criterion = "0.5.1" 29 | rand = { version = "0.8.5", features = ["min_const_gen"] } 30 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } 31 | 32 | [features] 33 | default = ["std"] 34 | parallel = [ 35 | "dep:rayon", 36 | "subspace-core-primitives/parallel", 37 | ] 38 | serde = [ 39 | "dep:serde", 40 | "subspace-core-primitives/serde", 41 | ] 42 | std = [ 43 | "parity-scale-codec/std", 44 | "parallel", 45 | "serde", 46 | "subspace-core-primitives/std", 47 | "subspace-erasure-coding/std", 48 | "thiserror", 49 | ] 50 | 51 | [[bench]] 52 | name = "archiving" 53 | harness = false 54 | -------------------------------------------------------------------------------- /crates/subspace-archiving/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxbulava/subspace/065dc94762db7e2531594b284daac6bd9f2d7b6e/crates/subspace-archiving/README.md -------------------------------------------------------------------------------- /crates/subspace-archiving/benches/archiving.rs: -------------------------------------------------------------------------------- 1 | use criterion::{criterion_group, criterion_main, Criterion}; 2 | use rand::{thread_rng, Rng}; 3 | use subspace_archiving::archiver::Archiver; 4 | use subspace_core_primitives::crypto::kzg; 5 | use subspace_core_primitives::crypto::kzg::Kzg; 6 | use subspace_core_primitives::RecordedHistorySegment; 7 | 8 | fn criterion_benchmark(c: &mut Criterion) { 9 | let mut input = RecordedHistorySegment::new_boxed(); 10 | thread_rng().fill(AsMut::<[u8]>::as_mut(input.as_mut())); 11 | let kzg = Kzg::new(kzg::embedded_kzg_settings()); 12 | let mut archiver = Archiver::new(kzg).unwrap(); 13 | 14 | c.bench_function("segment-archiving", |b| { 15 | b.iter(|| { 16 | archiver.add_block( 17 | AsRef::<[u8]>::as_ref(input.as_ref()).to_vec(), 18 | Default::default(), 19 | ); 20 | }) 21 | }); 22 | } 23 | 24 | criterion_group!(benches, criterion_benchmark); 25 | criterion_main!(benches); 26 | -------------------------------------------------------------------------------- /crates/subspace-archiving/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Collection of modules used for dealing with archived state of Subspace Network. 17 | #![cfg_attr(not(feature = "std"), no_std)] 18 | #![feature(array_chunks, drain_filter, iter_collect_into, slice_flatten)] 19 | 20 | pub mod archiver; 21 | pub mod piece_reconstructor; 22 | pub mod reconstructor; 23 | -------------------------------------------------------------------------------- /crates/subspace-archiving/tests/integration/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(assert_matches)] 2 | 3 | mod archiver; 4 | mod piece_reconstruction; 5 | mod reconstructor; 6 | -------------------------------------------------------------------------------- /crates/subspace-core-primitives/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxbulava/subspace/065dc94762db7e2531594b284daac6bd9f2d7b6e/crates/subspace-core-primitives/README.md -------------------------------------------------------------------------------- /crates/subspace-core-primitives/benches/kzg.rs: -------------------------------------------------------------------------------- 1 | use criterion::{black_box, criterion_group, criterion_main, Criterion}; 2 | use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; 3 | use subspace_core_primitives::crypto::Scalar; 4 | use subspace_core_primitives::RawRecord; 5 | 6 | fn criterion_benchmark(c: &mut Criterion) { 7 | let values = (0..RawRecord::SIZE / Scalar::SAFE_BYTES) 8 | .map(|_| Scalar::from(rand::random::<[u8; Scalar::SAFE_BYTES]>())) 9 | .collect::>(); 10 | 11 | let kzg = Kzg::new(embedded_kzg_settings()); 12 | 13 | c.bench_function("create-polynomial", |b| { 14 | b.iter(|| { 15 | kzg.poly(black_box(&values)).unwrap(); 16 | }) 17 | }); 18 | 19 | c.bench_function("commit", |b| { 20 | let polynomial = kzg.poly(&values).unwrap(); 21 | b.iter(|| { 22 | kzg.commit(black_box(&polynomial)).unwrap(); 23 | }) 24 | }); 25 | 26 | let num_values = values.len(); 27 | 28 | c.bench_function("create-witness", |b| { 29 | let polynomial = kzg.poly(&values).unwrap(); 30 | 31 | b.iter(|| { 32 | kzg.create_witness(black_box(&polynomial), black_box(num_values), black_box(0)) 33 | .unwrap(); 34 | }) 35 | }); 36 | 37 | c.bench_function("verify", |b| { 38 | let polynomial = kzg.poly(&values).unwrap(); 39 | let commitment = kzg.commit(&polynomial).unwrap(); 40 | let index = 0; 41 | let witness = kzg.create_witness(&polynomial, num_values, index).unwrap(); 42 | let value = values.first().unwrap(); 43 | 44 | b.iter(|| { 45 | kzg.verify( 46 | black_box(&commitment), 47 | black_box(num_values), 48 | black_box(index), 49 | black_box(value), 50 | black_box(&witness), 51 | ); 52 | }) 53 | }); 54 | } 55 | 56 | criterion_group!(benches, criterion_benchmark); 57 | criterion_main!(benches); 58 | -------------------------------------------------------------------------------- /crates/subspace-core-primitives/src/crypto/kzg/eth-public-parameters.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxbulava/subspace/065dc94762db7e2531594b284daac6bd9f2d7b6e/crates/subspace-core-primitives/src/crypto/kzg/eth-public-parameters.bin -------------------------------------------------------------------------------- /crates/subspace-core-primitives/src/crypto/kzg/serde.rs: -------------------------------------------------------------------------------- 1 | use serde::de::Error; 2 | use serde::{Deserialize, Deserializer, Serialize, Serializer}; 3 | 4 | // Custom wrapper so we don't have to write serialization/deserialization code manually 5 | #[derive(Serialize, Deserialize)] 6 | struct Commitment(#[serde(with = "hex::serde")] pub(super) [u8; 48]); 7 | 8 | impl Serialize for super::Commitment { 9 | fn serialize(&self, serializer: S) -> Result 10 | where 11 | S: Serializer, 12 | { 13 | Commitment(self.to_bytes()).serialize(serializer) 14 | } 15 | } 16 | 17 | impl<'de> Deserialize<'de> for super::Commitment { 18 | fn deserialize(deserializer: D) -> Result 19 | where 20 | D: Deserializer<'de>, 21 | { 22 | let Commitment(bytes) = Commitment::deserialize(deserializer)?; 23 | Self::try_from_bytes(&bytes).map_err(|error| D::Error::custom(format!("{error:?}"))) 24 | } 25 | } 26 | 27 | // Custom wrapper so we don't have to write serialization/deserialization code manually 28 | #[derive(Serialize, Deserialize)] 29 | struct Witness(#[serde(with = "hex::serde")] pub(super) [u8; 48]); 30 | 31 | impl Serialize for super::Witness { 32 | fn serialize(&self, serializer: S) -> Result 33 | where 34 | S: Serializer, 35 | { 36 | Witness(self.to_bytes()).serialize(serializer) 37 | } 38 | } 39 | 40 | impl<'de> Deserialize<'de> for super::Witness { 41 | fn deserialize(deserializer: D) -> Result 42 | where 43 | D: Deserializer<'de>, 44 | { 45 | let Witness(bytes) = Witness::deserialize(deserializer)?; 46 | Self::try_from_bytes(&bytes).map_err(|error| D::Error::custom(format!("{error:?}"))) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /crates/subspace-core-primitives/src/crypto/kzg/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::crypto::kzg::{embedded_kzg_settings, Kzg}; 2 | use crate::crypto::Scalar; 3 | 4 | #[test] 5 | fn basic() { 6 | let values = (0..8) 7 | .map(|_| Scalar::from(rand::random::<[u8; Scalar::SAFE_BYTES]>())) 8 | .collect::>(); 9 | 10 | let kzg = Kzg::new(embedded_kzg_settings()); 11 | let polynomial = kzg.poly(&values).unwrap(); 12 | let commitment = kzg.commit(&polynomial).unwrap(); 13 | 14 | let num_values = values.len(); 15 | 16 | for (index, value) in values.iter().enumerate() { 17 | let index = index.try_into().unwrap(); 18 | 19 | let witness = kzg.create_witness(&polynomial, num_values, index).unwrap(); 20 | 21 | assert!( 22 | kzg.verify(&commitment, num_values, index, value, &witness), 23 | "failed on index {index}" 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /crates/subspace-core-primitives/src/pieces/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::pieces::SBucket; 2 | use crate::Record; 3 | 4 | // Statically validate that we can store all possible s-buckets in SBucket data structure 5 | #[test] 6 | fn s_buckets_fit_into_data_structure() { 7 | assert!((SBucket::ZERO..=SBucket(u16::MAX)).count() <= Record::NUM_S_BUCKETS); 8 | } 9 | -------------------------------------------------------------------------------- /crates/subspace-core-primitives/src/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::crypto::Scalar; 2 | use crate::U256; 3 | use rand::thread_rng; 4 | use rand_core::RngCore; 5 | 6 | #[test] 7 | fn piece_distance_middle() { 8 | assert_eq!(U256::MIDDLE, U256::MAX / 2); 9 | } 10 | 11 | #[test] 12 | fn bytes_scalars_conversion() { 13 | { 14 | let mut bytes = vec![0u8; Scalar::SAFE_BYTES * 16]; 15 | thread_rng().fill_bytes(&mut bytes); 16 | 17 | let scalars = bytes 18 | .chunks_exact(Scalar::SAFE_BYTES) 19 | .map(|bytes| { 20 | Scalar::from( 21 | <&[u8; Scalar::SAFE_BYTES]>::try_from(bytes) 22 | .expect("Chunked into correct size; qed"), 23 | ) 24 | }) 25 | .collect::>(); 26 | 27 | { 28 | let mut decoded_bytes = vec![0u8; bytes.len()]; 29 | decoded_bytes 30 | .chunks_exact_mut(Scalar::SAFE_BYTES) 31 | .zip(scalars.iter()) 32 | .for_each(|(bytes, scalar)| { 33 | bytes.copy_from_slice(&scalar.to_bytes()[..Scalar::SAFE_BYTES]); 34 | }); 35 | 36 | assert_eq!(bytes, decoded_bytes); 37 | } 38 | 39 | { 40 | let mut decoded_bytes = vec![0u8; bytes.len()]; 41 | decoded_bytes 42 | .chunks_exact_mut(Scalar::SAFE_BYTES) 43 | .zip(scalars.iter()) 44 | .for_each(|(bytes, scalar)| { 45 | bytes.copy_from_slice(&scalar.to_bytes()[..Scalar::SAFE_BYTES]); 46 | }); 47 | 48 | assert_eq!(bytes, decoded_bytes); 49 | } 50 | } 51 | 52 | { 53 | let bytes = { 54 | let mut bytes = [0u8; Scalar::FULL_BYTES]; 55 | bytes[..Scalar::SAFE_BYTES] 56 | .copy_from_slice(&rand::random::<[u8; Scalar::SAFE_BYTES]>()); 57 | bytes 58 | }; 59 | 60 | { 61 | let scalar = Scalar::try_from(&bytes).unwrap(); 62 | 63 | assert_eq!(bytes, scalar.to_bytes()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /crates/subspace-erasure-coding/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-erasure-coding" 3 | description = "Polynomial erasure coding implementation used in Subspace Network" 4 | license = "Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | ] 12 | 13 | [lib] 14 | # Necessary for CLI options to work on benches 15 | bench = false 16 | 17 | [dependencies] 18 | # TODO: Switch to upstream `main` once https://github.com/sifraitech/rust-kzg/pull/204 is merged and blst has upstream no_std support 19 | blst_rust = { git = "https://github.com/subspace/rust-kzg", rev = "1058cc8c8af8461b490dc212c41d7d506a746577", default-features = false } 20 | # TODO: Switch to upstream `main` once https://github.com/sifraitech/rust-kzg/pull/204 is merged and blst has upstream no_std support 21 | kzg = { git = "https://github.com/subspace/rust-kzg", rev = "1058cc8c8af8461b490dc212c41d7d506a746577", default-features = false } 22 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } 23 | 24 | [dev-dependencies] 25 | # TODO: Switch to upstream `main` once https://github.com/sifraitech/rust-kzg/pull/204 is merged and blst has upstream no_std support 26 | blst_rust = { git = "https://github.com/subspace/rust-kzg", rev = "1058cc8c8af8461b490dc212c41d7d506a746577" } 27 | criterion = "0.5.1" 28 | rand = "0.8.5" 29 | 30 | [features] 31 | default = ["std", "parallel"] 32 | std = [ 33 | "blst_rust/std", 34 | "kzg/std", 35 | "subspace-core-primitives/std", 36 | ] 37 | parallel = ["blst_rust/parallel"] 38 | 39 | [[bench]] 40 | name = "commitments" 41 | harness = false 42 | -------------------------------------------------------------------------------- /crates/subspace-erasure-coding/benches/commitments.rs: -------------------------------------------------------------------------------- 1 | use blst_rust::types::g1::FsG1; 2 | use criterion::{black_box, criterion_group, criterion_main, Criterion}; 3 | use kzg::G1; 4 | use std::num::NonZeroUsize; 5 | use subspace_core_primitives::crypto::kzg::Commitment; 6 | use subspace_core_primitives::ArchivedHistorySegment; 7 | use subspace_erasure_coding::ErasureCoding; 8 | 9 | fn criterion_benchmark(c: &mut Criterion) { 10 | let num_shards = ArchivedHistorySegment::NUM_PIECES; 11 | let scale = NonZeroUsize::new(num_shards.ilog2() as usize) 12 | .expect("Recorded history segment contains at very least one record; qed"); 13 | let ec = ErasureCoding::new(scale).unwrap(); 14 | 15 | let source_commitments = (0..num_shards / 2) 16 | .map(|_| Commitment::from(FsG1::rand())) 17 | .collect::>(); 18 | 19 | c.bench_function("extend", |b| { 20 | b.iter(|| { 21 | ec.extend_commitments(black_box(&source_commitments)) 22 | .unwrap() 23 | }) 24 | }); 25 | } 26 | 27 | criterion_group!(benches, criterion_benchmark); 28 | criterion_main!(benches); 29 | -------------------------------------------------------------------------------- /crates/subspace-farmer-components/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-farmer-components" 3 | description = "Farmer for the Subspace Network Blockchain" 4 | license = "MIT OR Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | "/README.md", 12 | ] 13 | 14 | [lib] 15 | # Necessary for CLI options to work on benches 16 | bench = false 17 | 18 | [dependencies] 19 | async-trait = "0.1.68" 20 | backoff = { version = "0.4.0", features = ["futures", "tokio"] } 21 | bitvec = "1.0.1" 22 | fs2 = "0.4.3" 23 | futures = "0.3.28" 24 | libc = "0.2.146" 25 | lru = "0.10.0" 26 | parity-scale-codec = "3.4.0" 27 | parking_lot = "0.12.1" 28 | rand = "0.8.5" 29 | rayon = "1.7.0" 30 | schnorrkel = "0.9.1" 31 | serde = { version = "1.0.159", features = ["derive"] } 32 | static_assertions = "1.1.0" 33 | subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } 34 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } 35 | subspace-erasure-coding = { version = "0.1.0", path = "../subspace-erasure-coding" } 36 | subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-space", features = ["parallel"] } 37 | subspace-verification = { version = "0.1.0", path = "../subspace-verification" } 38 | thiserror = "1.0.38" 39 | tokio = { version = "1.28.2", features = ["macros", "parking_lot", "rt-multi-thread", "signal", "sync"] } 40 | tracing = "0.1.37" 41 | 42 | [dev-dependencies] 43 | criterion = "0.5.1" 44 | futures = "0.3.28" 45 | memmap2 = "0.7.0" 46 | subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } 47 | subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-space", features = ["chia"] } 48 | 49 | [[bench]] 50 | name = "plotting" 51 | harness = false 52 | 53 | [[bench]] 54 | name = "reading" 55 | harness = false 56 | 57 | [[bench]] 58 | name = "auditing" 59 | harness = false 60 | 61 | [[bench]] 62 | name = "proving" 63 | harness = false 64 | -------------------------------------------------------------------------------- /crates/subspace-farmer-components/README.md: -------------------------------------------------------------------------------- 1 | # Subspace Farmer Components 2 | 3 | Components of the reference implementation of Subspace Farmer for Subspace Network Blockchain. 4 | 5 | These components are used to implement farmer itself, but can also be used independently if necessary. 6 | -------------------------------------------------------------------------------- /crates/subspace-farmer-components/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature( 2 | array_chunks, 3 | const_option, 4 | const_trait_impl, 5 | int_roundings, 6 | iter_collect_into, 7 | new_uninit, 8 | portable_simd, 9 | slice_flatten, 10 | try_blocks 11 | )] 12 | 13 | //! Components of the reference implementation of Subspace Farmer for Subspace Network Blockchain. 14 | //! 15 | //! These components are used to implement farmer itself, but can also be used independently if necessary. 16 | 17 | pub mod auditing; 18 | pub mod file_ext; 19 | pub mod piece_caching; 20 | pub mod plotting; 21 | pub mod proving; 22 | pub mod reading; 23 | pub mod sector; 24 | mod segment_reconstruction; 25 | 26 | use serde::{Deserialize, Serialize}; 27 | use static_assertions::const_assert; 28 | use subspace_core_primitives::{HistorySize, SegmentIndex}; 29 | 30 | // Refuse to compile on non-64-bit platforms, offsets may fail on those when converting from u64 to 31 | // usize depending on chain parameters 32 | const_assert!(std::mem::size_of::() >= std::mem::size_of::()); 33 | 34 | /// Information about the protocol necessary for farmer operation 35 | #[derive(Debug, Copy, Clone, Serialize, Deserialize)] 36 | #[serde(rename_all = "camelCase")] 37 | pub struct FarmerProtocolInfo { 38 | /// Size of the blockchain history 39 | pub history_size: HistorySize, 40 | /// How many pieces one sector is supposed to contain (max) 41 | pub max_pieces_in_sector: u16, 42 | /// Number of segments after which sector expires 43 | pub sector_expiration: SegmentIndex, 44 | } 45 | -------------------------------------------------------------------------------- /crates/subspace-farmer-components/src/piece_caching.rs: -------------------------------------------------------------------------------- 1 | use lru::LruCache; 2 | use parking_lot::Mutex; 3 | use std::num::NonZeroUsize; 4 | use std::sync::Arc; 5 | use subspace_core_primitives::{Piece, PieceIndexHash}; 6 | use tracing::trace; 7 | 8 | // TODO: Re-think this number 9 | const CACHE_ITEMS_LIMIT: NonZeroUsize = 10 | NonZeroUsize::new(100).expect("Archived history segment contains at very least one piece; qed"); 11 | 12 | #[derive(Clone)] 13 | pub struct PieceMemoryCache { 14 | cache: Arc>>, 15 | } 16 | impl Default for PieceMemoryCache { 17 | #[inline] 18 | fn default() -> Self { 19 | Self::new(CACHE_ITEMS_LIMIT) 20 | } 21 | } 22 | 23 | impl PieceMemoryCache { 24 | pub fn new(items_limit: NonZeroUsize) -> Self { 25 | Self { 26 | cache: Arc::new(Mutex::new(LruCache::new(items_limit))), 27 | } 28 | } 29 | 30 | pub fn add_piece(&self, piece_index_hash: PieceIndexHash, piece: Piece) { 31 | self.cache.lock().put(piece_index_hash, piece); 32 | } 33 | 34 | pub fn add_pieces(&self, pieces: Vec<(PieceIndexHash, Piece)>) { 35 | let mut cache = self.cache.lock(); 36 | 37 | for (piece_index_hash, piece) in pieces { 38 | cache.put(piece_index_hash, piece); 39 | } 40 | } 41 | 42 | pub fn get_piece(&self, piece_index_hash: &PieceIndexHash) -> Option { 43 | let piece = self.cache.lock().get(piece_index_hash).cloned(); 44 | 45 | if piece.is_some() { 46 | trace!(?piece_index_hash, "Piece memory cache hit."); 47 | } 48 | 49 | piece 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /crates/subspace-farmer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-farmer" 3 | description = "Farmer for the Subspace Network Blockchain" 4 | license = "MIT OR Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | "/README.md", 12 | ] 13 | 14 | [dependencies] 15 | anyhow = "1.0.71" 16 | async-trait = "0.1.68" 17 | backoff = { version = "0.4.0", features = ["futures", "tokio"] } 18 | base58 = "0.2.0" 19 | blake2 = "0.10.6" 20 | bytesize = "1.2.0" 21 | clap = { version = "4.2.1", features = ["color", "derive"] } 22 | derive_more = "0.99.17" 23 | dirs = "5.0.1" 24 | event-listener-primitives = "2.0.1" 25 | fdlimit = "0.2" 26 | futures = "0.3.28" 27 | hex = { version = "0.4.3", features = ["serde"] } 28 | jsonrpsee = { version = "0.16.2", features = ["client", "macros", "server"] } 29 | lru = "0.10.0" 30 | memmap2 = "0.7.0" 31 | num-traits = "0.2.15" 32 | parity-db = "0.4.6" 33 | parity-scale-codec = "3.4.0" 34 | parking_lot = "0.12.1" 35 | rand = "0.8.5" 36 | schnorrkel = "0.9.1" 37 | serde = { version = "1.0.159", features = ["derive"] } 38 | serde_json = "1.0.95" 39 | static_assertions = "1.1.0" 40 | std-semaphore = "0.1.0" 41 | ss58-registry = "1.40.0" 42 | subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } 43 | subspace-erasure-coding = { version = "0.1.0", path = "../subspace-erasure-coding" } 44 | subspace-farmer-components = { version = "0.1.0", path = "../subspace-farmer-components" } 45 | subspace-solving = { version = "0.1.0", path = "../subspace-solving" } 46 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } 47 | subspace-networking = { version = "0.1.0", path = "../subspace-networking" } 48 | subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-space", features = ["chia"] } 49 | subspace-rpc-primitives = { version = "0.1.0", path = "../subspace-rpc-primitives" } 50 | substrate-bip39 = "0.4.4" 51 | tempfile = "3.4.0" 52 | thiserror = "1.0.38" 53 | tokio = { version = "1.28.2", features = ["macros", "parking_lot", "rt-multi-thread", "signal"] } 54 | tracing = "0.1.37" 55 | tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } 56 | ulid = { version = "1.0.0", features = ["serde"] } 57 | zeroize = "1.6.0" 58 | 59 | # The only triple tested and confirmed as working in `jemallocator` crate is `x86_64-unknown-linux-gnu` 60 | [target.'cfg(all(target_arch = "x86_64", target_vendor = "unknown", target_os = "linux", target_env = "gnu"))'.dependencies] 61 | jemallocator = "0.5.0" 62 | 63 | [dev-dependencies] 64 | rayon = "1.7.0" 65 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/bin/subspace-farmer/commands.rs: -------------------------------------------------------------------------------- 1 | mod farm; 2 | mod info; 3 | mod shared; 4 | 5 | pub(crate) use farm::farm_multi_disk; 6 | pub(crate) use info::info; 7 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/bin/subspace-farmer/commands/info.rs: -------------------------------------------------------------------------------- 1 | use crate::commands::shared::print_disk_farm_info; 2 | use crate::DiskFarm; 3 | 4 | pub(crate) fn info(disk_farms: Vec) { 5 | for (disk_farm_index, disk_farm) in disk_farms.into_iter().enumerate() { 6 | if disk_farm_index > 0 { 7 | println!(); 8 | } 9 | 10 | let DiskFarm { directory, .. } = disk_farm; 11 | 12 | print_disk_farm_info(directory, disk_farm_index); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/bin/subspace-farmer/commands/shared.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use subspace_farmer::single_disk_plot::{SingleDiskPlot, SingleDiskPlotSummary}; 3 | 4 | pub(crate) fn print_disk_farm_info(directory: PathBuf, disk_farm_index: usize) { 5 | println!("Single disk farm {disk_farm_index}:"); 6 | match SingleDiskPlot::collect_summary(directory) { 7 | SingleDiskPlotSummary::Found { info, directory } => { 8 | println!(" ID: {}", info.id()); 9 | println!(" Genesis hash: 0x{}", hex::encode(info.genesis_hash())); 10 | println!(" Public key: 0x{}", hex::encode(info.public_key())); 11 | println!(" First sector index: {}", info.first_sector_index()); 12 | println!( 13 | " Allocated space: {} ({})", 14 | bytesize::to_string(info.allocated_space(), true), 15 | bytesize::to_string(info.allocated_space(), false) 16 | ); 17 | println!(" Directory: {}", directory.display()); 18 | } 19 | SingleDiskPlotSummary::NotFound { directory } => { 20 | println!(" Plot directory: {}", directory.display()); 21 | println!(" No farm found here yet"); 22 | } 23 | SingleDiskPlotSummary::Error { directory, error } => { 24 | println!(" Directory: {}", directory.display()); 25 | println!(" Failed to open farm info: {error}"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature( 2 | const_option, 3 | drain_filter, 4 | hash_drain_filter, 5 | impl_trait_in_assoc_type, 6 | io_error_other, 7 | iter_collect_into, 8 | let_chains, 9 | trait_alias, 10 | try_blocks, 11 | type_alias_impl_trait, 12 | type_changing_struct_update 13 | )] 14 | 15 | //! # `subspace-farmer` library implementation overview 16 | //! 17 | //! This library provides droppable/interruptable instances of two processes that can be run in 18 | //! parallel: `plotting` and `farming`. 19 | //! 20 | //! During plotting we create: 21 | //! * a binary plot file, which contains subspace-encoded pieces one after another 22 | //! * a RocksDB commitments database, where key is a tag (first 8 bytes of `hmac(encoding, salt)`) 23 | //! and value is an offset of corresponding encoded piece in the plot (we can do this because all 24 | //! pieces have the same size). 25 | //! 26 | //! In short, for every piece we also store a record with 8-bytes tag and 8-bytes index (+some 27 | //! overhead of RocksDB itself). 28 | //! 29 | //! During farming we receive a global challenge and need to find a solution based on *target* and 30 | //! *solution range*. In order to find solution, we derive *local challenge* and use first 8 bytes 31 | //! (the same as tag size) as our *target* and do range query in RocksDB. For that we interpret 32 | //! *target* as 64-bit big-endian unsigned integer and find all of the keys in tags database that 33 | //! are `target ± ½ * solution range` (while also handing overflow/underflow) when interpreted as 34 | //! 64-bit unsigned integers. 35 | 36 | pub(crate) mod identity; 37 | pub mod node_client; 38 | pub(crate) mod object_mappings; 39 | pub mod reward_signing; 40 | pub mod single_disk_plot; 41 | pub mod utils; 42 | pub mod ws_rpc_server; 43 | 44 | pub use identity::Identity; 45 | pub use jsonrpsee; 46 | pub use node_client::node_rpc_client::NodeRpcClient; 47 | pub use node_client::{Error as RpcClientError, NodeClient}; 48 | pub use object_mappings::{ObjectMappingError, ObjectMappings}; 49 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/node_client.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod node_rpc_client; 2 | 3 | use async_trait::async_trait; 4 | use futures::Stream; 5 | use std::pin::Pin; 6 | use subspace_core_primitives::{Piece, PieceIndex, SegmentCommitment, SegmentHeader, SegmentIndex}; 7 | use subspace_rpc_primitives::{ 8 | FarmerAppInfo, RewardSignatureResponse, RewardSigningInfo, SlotInfo, SolutionResponse, 9 | }; 10 | 11 | /// To become error type agnostic 12 | pub type Error = Box; 13 | 14 | /// Abstraction of the Node Client 15 | #[async_trait] 16 | pub trait NodeClient: Clone + Send + Sync + 'static { 17 | /// Get farmer app info 18 | async fn farmer_app_info(&self) -> Result; 19 | 20 | /// Subscribe to slot 21 | async fn subscribe_slot_info( 22 | &self, 23 | ) -> Result + Send + 'static>>, Error>; 24 | 25 | /// Submit a slot solution 26 | async fn submit_solution_response( 27 | &self, 28 | solution_response: SolutionResponse, 29 | ) -> Result<(), Error>; 30 | 31 | /// Subscribe to block signing request 32 | async fn subscribe_reward_signing( 33 | &self, 34 | ) -> Result + Send + 'static>>, Error>; 35 | 36 | /// Submit a block signature 37 | async fn submit_reward_signature( 38 | &self, 39 | reward_signature: RewardSignatureResponse, 40 | ) -> Result<(), Error>; 41 | 42 | /// Subscribe to archived segment headers 43 | async fn subscribe_archived_segment_headers( 44 | &self, 45 | ) -> Result + Send + 'static>>, Error>; 46 | 47 | /// Get segment commitments for the segments 48 | async fn segment_commitments( 49 | &self, 50 | segment_indexes: Vec, 51 | ) -> Result>, Error>; 52 | 53 | /// Get segment headers for the segments 54 | async fn segment_headers( 55 | &self, 56 | segment_indexes: Vec, 57 | ) -> Result>, Error>; 58 | 59 | /// Get piece by index. 60 | async fn piece(&self, piece_index: PieceIndex) -> Result, Error>; 61 | 62 | /// Acknowledge segment header. 63 | async fn acknowledge_archived_segment_header( 64 | &self, 65 | segment_index: SegmentIndex, 66 | ) -> Result<(), Error>; 67 | } 68 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/reward_signing.rs: -------------------------------------------------------------------------------- 1 | use crate::identity::Identity; 2 | use crate::node_client::NodeClient; 3 | use futures::StreamExt; 4 | use std::future::Future; 5 | use subspace_rpc_primitives::{RewardSignatureResponse, RewardSigningInfo}; 6 | use tracing::{info, warn}; 7 | 8 | pub async fn reward_signing( 9 | node_client: NC, 10 | identity: Identity, 11 | ) -> Result, Box> 12 | where 13 | NC: NodeClient, 14 | { 15 | info!("Subscribing to reward signing notifications"); 16 | 17 | let mut reward_signing_info_notifications = node_client.subscribe_reward_signing().await?; 18 | 19 | let reward_signing_fut = async move { 20 | while let Some(RewardSigningInfo { hash, public_key }) = 21 | reward_signing_info_notifications.next().await 22 | { 23 | // Multiple plots might have solved, only sign with correct one 24 | if identity.public_key().to_bytes() != public_key { 25 | continue; 26 | } 27 | 28 | let signature = identity.sign_reward_hash(&hash); 29 | 30 | match node_client 31 | .submit_reward_signature(RewardSignatureResponse { 32 | hash, 33 | signature: Some(signature.to_bytes().into()), 34 | }) 35 | .await 36 | { 37 | Ok(_) => { 38 | info!("Successfully signed reward hash 0x{}", hex::encode(hash)); 39 | } 40 | Err(error) => { 41 | warn!( 42 | %error, 43 | "Failed to send signature for reward hash 0x{}", 44 | hex::encode(hash), 45 | ); 46 | } 47 | } 48 | } 49 | }; 50 | 51 | Ok(reward_signing_fut) 52 | } 53 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/utils/farmer_piece_getter.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::piece_cache::PieceCache; 2 | use async_trait::async_trait; 3 | use std::error::Error; 4 | use std::sync::Arc; 5 | use subspace_core_primitives::{Piece, PieceIndex}; 6 | use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy}; 7 | use subspace_networking::utils::multihash::ToMultihash; 8 | 9 | pub struct FarmerPieceGetter { 10 | base_piece_getter: PG, 11 | piece_cache: Arc>, 12 | } 13 | 14 | impl FarmerPieceGetter { 15 | pub fn new(base_piece_getter: PG, piece_cache: Arc>) -> Self { 16 | Self { 17 | base_piece_getter, 18 | piece_cache, 19 | } 20 | } 21 | } 22 | 23 | #[async_trait] 24 | impl PieceGetter for FarmerPieceGetter 25 | where 26 | PG: PieceGetter + Send + Sync, 27 | PC: PieceCache + Send + 'static, 28 | { 29 | async fn get_piece( 30 | &self, 31 | piece_index: PieceIndex, 32 | retry_policy: PieceGetterRetryPolicy, 33 | ) -> Result, Box> { 34 | let piece_index_hash = piece_index.hash(); 35 | let key = piece_index_hash.to_multihash().into(); 36 | 37 | if let Some(piece) = self.piece_cache.lock().await.get_piece(&key) { 38 | return Ok(Some(piece)); 39 | } 40 | 41 | let maybe_piece = self 42 | .base_piece_getter 43 | .get_piece(piece_index, retry_policy) 44 | .await?; 45 | 46 | Ok(maybe_piece) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/utils/node_piece_getter.rs: -------------------------------------------------------------------------------- 1 | use async_trait::async_trait; 2 | use std::error::Error; 3 | use subspace_core_primitives::{Piece, PieceIndex}; 4 | use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy}; 5 | use subspace_networking::utils::piece_provider::{PieceProvider, PieceValidator, RetryPolicy}; 6 | 7 | pub struct NodePieceGetter { 8 | piece_provider: PieceProvider, 9 | } 10 | 11 | impl NodePieceGetter { 12 | pub fn new(piece_provider: PieceProvider) -> Self { 13 | Self { piece_provider } 14 | } 15 | } 16 | 17 | fn convert_retry_policies(retry_policy: PieceGetterRetryPolicy) -> RetryPolicy { 18 | match retry_policy { 19 | PieceGetterRetryPolicy::Limited(retries) => RetryPolicy::Limited(retries), 20 | PieceGetterRetryPolicy::Unlimited => RetryPolicy::Unlimited, 21 | } 22 | } 23 | 24 | #[async_trait] 25 | impl PieceGetter for NodePieceGetter 26 | where 27 | PV: PieceValidator, 28 | { 29 | async fn get_piece( 30 | &self, 31 | piece_index: PieceIndex, 32 | retry_policy: PieceGetterRetryPolicy, 33 | ) -> Result, Box> { 34 | self.piece_provider 35 | .get_piece(piece_index, convert_retry_policies(retry_policy)) 36 | .await 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/utils/piece_cache.rs: -------------------------------------------------------------------------------- 1 | use subspace_core_primitives::Piece; 2 | use subspace_networking::libp2p::kad::record::Key; 3 | 4 | /// Defines persistent piece cache interface. 5 | // TODO: This should be elsewhere, like in `subspace-dsn` 6 | pub trait PieceCache: Sync + Send + 'static { 7 | type KeysIterator: IntoIterator; 8 | 9 | /// Check whether key should be cached based on current cache size and key-to-peer-id distance. 10 | fn should_cache(&self, key: &Key) -> bool; 11 | 12 | /// Add piece to the cache. 13 | fn add_piece(&mut self, key: Key, piece: Piece); 14 | 15 | /// Get piece from the cache. 16 | fn get_piece(&self, key: &Key) -> Option; 17 | 18 | /// Iterator over pieces in cache 19 | fn keys(&self) -> Self::KeysIterator; 20 | } 21 | -------------------------------------------------------------------------------- /crates/subspace-farmer/src/utils/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::run_future_in_dedicated_thread; 2 | use std::future; 3 | 4 | #[tokio::test] 5 | async fn run_future_in_dedicated_thread_ready() { 6 | let value = run_future_in_dedicated_thread( 7 | Box::pin(async { future::ready(1).await }), 8 | "ready".to_string(), 9 | ) 10 | .unwrap() 11 | .await 12 | .unwrap(); 13 | 14 | assert_eq!(value, 1); 15 | } 16 | 17 | #[tokio::test] 18 | async fn run_future_in_dedicated_thread_cancellation() { 19 | // This may hang if not implemented correctly 20 | drop( 21 | run_future_in_dedicated_thread( 22 | Box::pin(async { future::pending::<()>().await }), 23 | "cancellation".to_string(), 24 | ) 25 | .unwrap(), 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /crates/subspace-fraud-proof/src/domain_runtime_code.rs: -------------------------------------------------------------------------------- 1 | use codec::{Decode, Encode}; 2 | use sp_api::ProvideRuntimeApi; 3 | use sp_core::traits::FetchRuntimeCode; 4 | use sp_domains::fraud_proof::VerificationError; 5 | use sp_domains::{DomainId, ExecutorApi}; 6 | use sp_runtime::traits::Block as BlockT; 7 | use std::borrow::Cow; 8 | use std::sync::Arc; 9 | 10 | pub(crate) struct RuntimeCodeFetcher<'a> { 11 | pub(crate) wasm_bundle: &'a [u8], 12 | } 13 | 14 | impl<'a> FetchRuntimeCode for RuntimeCodeFetcher<'a> { 15 | fn fetch_runtime_code(&self) -> Option> { 16 | Some(self.wasm_bundle.into()) 17 | } 18 | } 19 | 20 | pub(crate) struct DomainRuntimeCode { 21 | pub(crate) wasm_bundle: Cow<'static, [u8]>, 22 | } 23 | 24 | impl DomainRuntimeCode { 25 | pub(crate) fn as_runtime_code_fetcher(&self) -> RuntimeCodeFetcher { 26 | RuntimeCodeFetcher { 27 | wasm_bundle: &self.wasm_bundle, 28 | } 29 | } 30 | } 31 | 32 | pub(crate) fn retrieve_domain_runtime_code( 33 | domain_id: DomainId, 34 | at: PBlock::Hash, 35 | primary_chain_client: &Arc, 36 | ) -> Result 37 | where 38 | PBlock: BlockT, 39 | Hash: Encode + Decode, 40 | PClient: ProvideRuntimeApi, 41 | PClient::Api: ExecutorApi, 42 | { 43 | let system_wasm_bundle = primary_chain_client 44 | .runtime_api() 45 | .system_domain_wasm_bundle(at) 46 | .map_err(VerificationError::RuntimeApi)?; 47 | 48 | let wasm_bundle = { 49 | if domain_id.is_system() { 50 | system_wasm_bundle 51 | } else { 52 | return Err(VerificationError::RuntimeCode(format!( 53 | "No runtime code for {domain_id:?}" 54 | ))); 55 | } 56 | }; 57 | 58 | Ok(DomainRuntimeCode { wasm_bundle }) 59 | } 60 | -------------------------------------------------------------------------------- /crates/subspace-networking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-networking" 3 | version = "0.1.0" 4 | authors = [ 5 | "Nazar Mokrynskyi ", 6 | "Shamil Gadelshin " 7 | ] 8 | description = "Networking functionality of Subspace Network, primarily used for DSN (Distributed Storage Network)" 9 | edition = "2021" 10 | license = "Apache-2.0" 11 | homepage = "https://subspace.network" 12 | repository = "https://github.com/subspace/subspace" 13 | include = [ 14 | "/src", 15 | "/Cargo.toml", 16 | ] 17 | 18 | [dependencies] 19 | actix-web = "4.3.1" 20 | anyhow = "1.0.71" 21 | async-trait = "0.1.68" 22 | backoff = { version = "0.4.0", features = ["futures", "tokio"] } 23 | bytes = "1.4.0" 24 | bytesize = "1.2.0" 25 | chrono = {version = "0.4.26", features = ["clock", "serde", "std",]} 26 | clap = { version = "4.2.1", features = ["color", "derive"] } 27 | derive_more = "0.99.17" 28 | either = "1.8.1" 29 | event-listener-primitives = "2.0.1" 30 | futures = "0.3.28" 31 | hex = "0.4.3" 32 | lru = "0.10.0" 33 | nohash-hasher = "0.2.0" 34 | parity-db = "0.4.6" 35 | parity-scale-codec = "3.4.0" 36 | parking_lot = "0.12.1" 37 | pin-project = "1.1.0" 38 | prometheus-client = "0.19.0" 39 | serde = { version = "1.0.159", features = ["derive"] } 40 | serde_json = "1.0.97" 41 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } 42 | tempfile = "3.4.0" 43 | thiserror = "1.0.38" 44 | tokio = { version = "1.28.2", features = ["macros", "parking_lot", "rt-multi-thread", "sync", "time"] } 45 | tracing = "0.1.37" 46 | tracing-subscriber = { version = "0.3.17", features = ["env-filter"]} 47 | unsigned-varint = { version = "0.7.1", features = ["futures", "asynchronous_codec"] } 48 | void = "1.0.2" 49 | 50 | [dependencies.libp2p] 51 | version = "0.51.3" 52 | default-features = false 53 | features = [ 54 | "dns", 55 | "gossipsub", 56 | "identify", 57 | "kad", 58 | "macros", 59 | "metrics", 60 | "noise", 61 | "ping", 62 | "quic", 63 | "request-response", 64 | "serde", 65 | "tcp", 66 | "tokio", 67 | "websocket", 68 | "yamux", 69 | ] 70 | 71 | [dev-dependencies] 72 | rand = "0.8.5" 73 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/behavior/provider_storage.rs: -------------------------------------------------------------------------------- 1 | mod providers; 2 | 3 | use libp2p::kad::record::Key; 4 | use libp2p::kad::{store, ProviderRecord}; 5 | use libp2p::PeerId; 6 | #[cfg(test)] 7 | pub(crate) use providers::{instant_to_micros, micros_to_instant}; 8 | pub use providers::{MemoryProviderStorage, ParityDbProviderStorage, VoidProviderStorage}; 9 | use std::borrow::Cow; 10 | 11 | /// A trait for providers storages - wrapper around `provider` functions of the libp2p RecordStore. 12 | pub trait ProviderStorage { 13 | /// Provider record iterator. 14 | type ProvidedIter<'a>: Iterator> 15 | where 16 | Self: 'a; 17 | 18 | /// Adds a provider record to the store. 19 | /// 20 | /// A record store only needs to store a number of provider records 21 | /// for a key corresponding to the replication factor and should 22 | /// store those records whose providers are closest to the key. 23 | fn add_provider(&self, record: ProviderRecord) -> store::Result<()>; 24 | 25 | /// Gets a copy of the stored provider records for the given key. 26 | fn providers(&self, key: &Key) -> Vec; 27 | 28 | /// Gets an iterator over all stored provider records for which the 29 | /// node owning the store is itself the provider. 30 | fn provided(&self) -> Self::ProvidedIter<'_>; 31 | 32 | /// Removes a provider record from the store. 33 | fn remove_provider(&self, k: &Key, p: &PeerId); 34 | } 35 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/behavior/provider_storage/providers/tests.rs: -------------------------------------------------------------------------------- 1 | use super::MemoryProviderStorage; 2 | use crate::ProviderStorage; 3 | use libp2p::kad::record::Key; 4 | use libp2p::kad::ProviderRecord; 5 | use libp2p::PeerId; 6 | use std::collections::HashSet; 7 | 8 | #[allow(clippy::mutable_key_type)] // we use hash set for sorting to compare collections 9 | #[test] 10 | fn memory_storage_provider() { 11 | let local_peer_id = PeerId::random(); 12 | let store = MemoryProviderStorage::new(local_peer_id); 13 | 14 | let key1: Key = b"key1".to_vec().into(); 15 | let provider1 = PeerId::random(); 16 | let rec1 = ProviderRecord { 17 | provider: provider1, 18 | key: key1, 19 | expires: None, 20 | addresses: Vec::new(), 21 | }; 22 | 23 | let key2: Key = b"key2".to_vec().into(); 24 | let provider2 = local_peer_id; 25 | let rec2 = ProviderRecord { 26 | provider: provider2, 27 | key: key2.clone(), 28 | expires: None, 29 | addresses: Vec::new(), 30 | }; 31 | 32 | let provider3 = PeerId::random(); 33 | let rec3 = ProviderRecord { 34 | provider: provider3, 35 | key: key2.clone(), 36 | expires: None, 37 | addresses: Vec::new(), 38 | }; 39 | 40 | // Check adding 41 | store.add_provider(rec1).unwrap(); 42 | store.add_provider(rec2.clone()).unwrap(); 43 | store.add_provider(rec3.clone()).unwrap(); 44 | 45 | // Check local providers retrieval 46 | let provided_collection: HashSet = 47 | HashSet::from_iter(store.provided().map(|i| i.into_owned())); 48 | 49 | println!("{:?}", store.provided()); 50 | 51 | assert_eq!( 52 | HashSet::from_iter(vec![rec2.clone()].into_iter()), 53 | provided_collection 54 | ); 55 | 56 | // Check single provider retrieval 57 | let provided_collection: HashSet = 58 | HashSet::from_iter(store.providers(&key2).into_iter()); 59 | 60 | assert_eq!( 61 | HashSet::from_iter(vec![rec2.clone(), rec3].into_iter()), 62 | provided_collection 63 | ); 64 | 65 | // Remove provider 66 | store.remove_provider(&key2, &provider3); 67 | let provided_collection: HashSet = 68 | HashSet::from_iter(store.providers(&key2).into_iter()); 69 | 70 | assert_eq!( 71 | HashSet::from_iter(vec![rec2].into_iter()), 72 | provided_collection 73 | ); 74 | } 75 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/request_handlers.rs: -------------------------------------------------------------------------------- 1 | pub mod generic_request_handler; 2 | pub mod object_mappings; 3 | pub mod peer_info; 4 | pub mod piece_announcement; 5 | pub mod piece_by_key; 6 | pub mod pieces_by_range; 7 | pub mod segment_header; 8 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/request_handlers/object_mappings.rs: -------------------------------------------------------------------------------- 1 | //! Helper for incoming object mappings requests. 2 | //! 3 | //! Handle (i.e. answer) incoming object mappings requests from a remote peer received via 4 | //! `RequestResponsesBehaviour` with generic [`GenericRequestHandler`]. 5 | 6 | use crate::request_handlers::generic_request_handler::{GenericRequest, GenericRequestHandler}; 7 | use parity_scale_codec::{Decode, Encode}; 8 | use subspace_core_primitives::objects::GlobalObject; 9 | use subspace_core_primitives::Blake2b256Hash; 10 | 11 | /// Object-mapping protocol request. 12 | #[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)] 13 | pub struct ObjectMappingsRequest { 14 | /// Object hash (32-bytes) 15 | pub object_hash: Blake2b256Hash, 16 | } 17 | 18 | impl GenericRequest for ObjectMappingsRequest { 19 | const PROTOCOL_NAME: &'static str = "/subspace/object-mappings/0.1.0"; 20 | const LOG_TARGET: &'static str = "object-mappings-request-response-handler"; 21 | type Response = ObjectMappingsResponse; 22 | } 23 | 24 | /// Object-mapping protocol request. 25 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 26 | pub struct ObjectMappingsResponse { 27 | /// Returned data. 28 | pub object_mapping: Option, 29 | } 30 | 31 | /// Create a new object-mappings request handler. 32 | pub type ObjectMappingsRequestHandler = GenericRequestHandler; 33 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/request_handlers/peer_info.rs: -------------------------------------------------------------------------------- 1 | use crate::{GenericRequest, GenericRequestHandler}; 2 | use parity_scale_codec::{Decode, Encode}; 3 | 4 | /// Peer-info protocol request. 5 | #[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)] 6 | pub struct PeerInfoRequest; 7 | 8 | /// Defines peer synchronization status. 9 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 10 | pub enum PeerSyncStatus { 11 | /// Special status for starting peer. Receiving it in the running mode means an error. 12 | Unknown, 13 | /// Synchronization is not supported for this peer. 14 | NotSupported, 15 | /// Peer is ready to provide data for synchronization. 16 | Ready, 17 | /// Peer is synchronizing. 18 | Syncing, 19 | } 20 | 21 | /// Defines peer current state. 22 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 23 | pub struct PeerInfo { 24 | /// Synchronization status. 25 | pub status: PeerSyncStatus, 26 | } 27 | 28 | impl GenericRequest for PeerInfoRequest { 29 | const PROTOCOL_NAME: &'static str = "/subspace/sync/peer-info/0.1.0"; 30 | const LOG_TARGET: &'static str = "peer-info-request-response-handler"; 31 | type Response = PeerInfoResponse; 32 | } 33 | 34 | /// Peer-info protocol response. 35 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 36 | pub struct PeerInfoResponse { 37 | /// Returned data. 38 | pub peer_info: PeerInfo, 39 | } 40 | 41 | /// Create a new peer-info request handler. 42 | pub type PeerInfoRequestHandler = GenericRequestHandler; 43 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/request_handlers/piece_by_key.rs: -------------------------------------------------------------------------------- 1 | //! Helper for incoming pieces requests. 2 | //! 3 | //! Handle (i.e. answer) incoming pieces requests from a remote peer received via 4 | //! `RequestResponsesBehaviour` with generic [`GenericRequestHandler`]. 5 | 6 | use crate::request_handlers::generic_request_handler::{GenericRequest, GenericRequestHandler}; 7 | use parity_scale_codec::{Decode, Encode}; 8 | use subspace_core_primitives::{Piece, PieceIndexHash}; 9 | 10 | /// Piece-by-hash protocol request. 11 | #[derive(Debug, Clone, Copy, Eq, PartialEq, Encode, Decode)] 12 | pub struct PieceByHashRequest { 13 | /// Request key - piece index hash 14 | pub piece_index_hash: PieceIndexHash, 15 | } 16 | 17 | impl GenericRequest for PieceByHashRequest { 18 | const PROTOCOL_NAME: &'static str = "/subspace/piece-by-hash/0.1.0"; 19 | const LOG_TARGET: &'static str = "piece-by-hash-request-response-handler"; 20 | type Response = PieceByHashResponse; 21 | } 22 | 23 | /// Piece-by-hash protocol response. 24 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 25 | pub struct PieceByHashResponse { 26 | /// Returned data. 27 | pub piece: Option, 28 | } 29 | 30 | //TODO: remove attribute on the first usage 31 | #[allow(dead_code)] 32 | /// Create a new piece-by-hash request handler. 33 | pub type PieceByHashRequestHandler = GenericRequestHandler; 34 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/request_handlers/pieces_by_range.rs: -------------------------------------------------------------------------------- 1 | use parity_scale_codec::{Decode, Encode}; 2 | use subspace_core_primitives::{FlatPieces, PieceIndex, PieceIndexHash}; 3 | 4 | use crate::{GenericRequest, GenericRequestHandler}; 5 | 6 | //TODO: A candidate for migrating to a separate crate. 7 | /// Collection of pieces that potentially need to be plotted 8 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 9 | pub struct PiecesToPlot { 10 | /// Piece indexes for each of the `pieces` 11 | pub piece_indexes: Vec, 12 | /// Pieces themselves 13 | pub pieces: FlatPieces, 14 | } 15 | 16 | /// Pieces-by-range protocol request. Assumes requests with paging. 17 | #[derive(Debug, Clone, Copy, Eq, PartialEq, Encode, Decode)] 18 | pub struct PiecesByRangeRequest { 19 | /// Start of the requested range 20 | pub start: PieceIndexHash, 21 | /// End of the requested range 22 | pub end: PieceIndexHash, 23 | } 24 | 25 | impl GenericRequest for PiecesByRangeRequest { 26 | const PROTOCOL_NAME: &'static str = "/subspace/sync/pieces-by-range/0.1.0"; 27 | const LOG_TARGET: &'static str = "pieces-by-range-request-response-handler"; 28 | type Response = PiecesByRangeResponse; 29 | } 30 | 31 | /// Pieces-by-range protocol response. Assumes requests with paging. 32 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 33 | pub struct PiecesByRangeResponse { 34 | /// Returned data. 35 | pub pieces: PiecesToPlot, 36 | /// Defines starting point (cursor) of the next request. 37 | /// None means no further data available. 38 | pub next_piece_index_hash: Option, 39 | } 40 | 41 | /// Create a new pieces-by-range request handler. 42 | pub type PiecesByRangeRequestHandler = GenericRequestHandler; 43 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/request_handlers/segment_header.rs: -------------------------------------------------------------------------------- 1 | //! Helper for incoming segment header requests. 2 | //! 3 | //! Handle (i.e. answer) incoming segment headers requests from a remote peer received via 4 | //! `RequestResponsesBehaviour` with generic [`GenericRequestHandler`]. 5 | 6 | use crate::request_handlers::generic_request_handler::{GenericRequest, GenericRequestHandler}; 7 | use parity_scale_codec::{Decode, Encode}; 8 | use subspace_core_primitives::{SegmentHeader, SegmentIndex}; 9 | 10 | /// Segment header by segment indexes protocol request. 11 | #[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)] 12 | pub enum SegmentHeaderRequest { 13 | /// Segment headers by segment indexes. 14 | SegmentIndexes { 15 | /// Segment indexes to get. 16 | segment_indexes: Vec, 17 | }, 18 | /// Defines how many segment headers to return. 19 | LastSegmentHeaders { 20 | /// Number of segment headers to return. 21 | segment_header_number: u64, 22 | }, 23 | } 24 | 25 | impl GenericRequest for SegmentHeaderRequest { 26 | const PROTOCOL_NAME: &'static str = "/subspace/segment-headers-by-indexes/0.1.0"; 27 | const LOG_TARGET: &'static str = "segment-headers-by-indexes-request-response-handler"; 28 | type Response = SegmentHeaderResponse; 29 | } 30 | 31 | /// Segment header by segment indexes protocol response. 32 | #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] 33 | pub struct SegmentHeaderResponse { 34 | /// Returned data. 35 | pub segment_headers: Vec, 36 | } 37 | 38 | //TODO: remove attribute on the first usage 39 | #[allow(dead_code)] 40 | /// Create a new segment-header-by-segment-indexes request handler. 41 | pub type SegmentHeaderBySegmentIndexesRequestHandler = GenericRequestHandler; 42 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/utils/multihash.rs: -------------------------------------------------------------------------------- 1 | //! Defines multihash codes for Subspace DSN. 2 | 3 | use libp2p::multihash::Multihash; 4 | use std::error::Error; 5 | use subspace_core_primitives::PieceIndexHash; 6 | 7 | /// Start of Subspace Network multicodec namespace (+1000 to distinguish from future stable values): 8 | /// https://github.com/multiformats/multicodec/blob/master/table.csv 9 | const SUBSPACE_MULTICODEC_NAMESPACE_START: u64 = 0xb39910 + 1000; 10 | 11 | /// Subspace Network multihash codes. 12 | #[derive(Debug, Clone, PartialEq)] 13 | #[repr(u64)] 14 | pub enum MultihashCode { 15 | /// Piece index hash code. 16 | PieceIndexHash = SUBSPACE_MULTICODEC_NAMESPACE_START, 17 | } 18 | 19 | impl From for u64 { 20 | #[inline] 21 | fn from(code: MultihashCode) -> Self { 22 | code as u64 23 | } 24 | } 25 | 26 | impl TryFrom for MultihashCode { 27 | type Error = Box; 28 | 29 | #[inline] 30 | fn try_from(value: u64) -> Result { 31 | match value { 32 | x if x == MultihashCode::PieceIndexHash as u64 => Ok(MultihashCode::PieceIndexHash), 33 | _ => Err("Unexpected multihash code".into()), 34 | } 35 | } 36 | } 37 | 38 | /// Helper trait for converting to multihash. 39 | pub trait ToMultihash { 40 | /// Convert to multihash by the default multihash code. 41 | fn to_multihash(&self) -> Multihash; 42 | /// Convert to multihash by the specified multihash code. 43 | fn to_multihash_by_code(&self, code: MultihashCode) -> Multihash; 44 | } 45 | 46 | impl ToMultihash for PieceIndexHash { 47 | fn to_multihash(&self) -> Multihash { 48 | self.to_multihash_by_code(MultihashCode::PieceIndexHash) 49 | } 50 | 51 | fn to_multihash_by_code(&self, code: MultihashCode) -> Multihash { 52 | Multihash::wrap(u64::from(code), self.as_ref()) 53 | .expect("Input never exceeds allocated size; qed") 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /crates/subspace-networking/src/utils/prometheus.rs: -------------------------------------------------------------------------------- 1 | use actix_web::http::StatusCode; 2 | use actix_web::web::Data; 3 | use actix_web::{get, App, HttpResponse, HttpServer}; 4 | use parking_lot::Mutex; 5 | use prometheus_client::encoding::text::encode; 6 | use prometheus_client::registry::Registry; 7 | use std::error::Error; 8 | use std::net::SocketAddr; 9 | use std::sync::Arc; 10 | use std::thread; 11 | use tracing::{error, info}; 12 | 13 | type SharedRegistry = Arc>; 14 | 15 | #[get("/metrics")] 16 | async fn metrics(registry: Data) -> Result> { 17 | let mut encoded = String::new(); 18 | encode(&mut encoded, ®istry.lock())?; 19 | 20 | let resp = HttpResponse::build(StatusCode::OK).body(encoded); 21 | 22 | Ok(resp) 23 | } 24 | 25 | /// Start prometheus metrics server on the provided address. 26 | pub async fn start_prometheus_metrics_server( 27 | address: SocketAddr, 28 | registry: Registry, 29 | ) -> std::io::Result<()> { 30 | let shared_registry = Arc::new(Mutex::new(registry)); 31 | let data = Data::new(shared_registry); 32 | 33 | info!("Starting metrics server on {} ...", address); 34 | 35 | let server = HttpServer::new(move || App::new().app_data(data.clone()).service(metrics)) 36 | .bind(address)? 37 | .run(); 38 | 39 | // Actix-web will reuse existing tokio runtime. 40 | let runtime = tokio::runtime::Runtime::new()?; 41 | 42 | // We need a dedicated thread because actix-web App is !Send and won't work with tokio. 43 | // TODO: This is not cancellable, it should be though 44 | thread::spawn(move || { 45 | if let Err(err) = runtime.block_on(server) { 46 | error!( 47 | ?err, 48 | "block_on returns an error for prometheus metrics server" 49 | ) 50 | } 51 | }); 52 | 53 | Ok(()) 54 | } 55 | -------------------------------------------------------------------------------- /crates/subspace-node/README.md: -------------------------------------------------------------------------------- 1 | # Subspace Node 2 | 3 | Reference Node implementation for Subspace Network Blockchain using [Substrate](https://docs.substrate.io/) framework. 4 | 5 | ## Getting Started 6 | 7 | Follow these steps to get started with the Subspace Node :hammer_and_wrench: 8 | 9 | ## Running 10 | 11 | It is recommended to follow general farming instructions that explain how to run both farmer and node together. 12 | 13 | ## Build from source 14 | 15 | Rust toolchain is expected to be installed for anything in this repository to compile, but there are some extra dependencies for farmer specifically. 16 | 17 | Prost library from libp2p dependency needs CMake: 18 | ```bash 19 | sudo apt-get install cmake 20 | ``` 21 | 22 | Then build the farmer using Cargo: 23 | ``` 24 | cargo build --profile production subspace-node 25 | target/production/subspace-node --version 26 | ``` 27 | 28 | #### Start the node 29 | 30 | Start a single node development chain: 31 | ```bash 32 | target/production/subspace-node \ 33 | --dev \ 34 | --rpc-external \ 35 | --node-key 0000000000000000000000000000000000000000000000000000000000000001 36 | ``` 37 | 38 | By default, node data are written to `subspace-node` subdirectory of the OS-specific users local data directory. 39 | 40 | ``` 41 | Linux 42 | $XDG_DATA_HOME or /home/alice/.local/share 43 | $HOME/.local/share 44 | 45 | macOS 46 | $HOME/Library/Application Support /Users/Alice/Library/Application Support 47 | 48 | Windows 49 | {FOLDERID_LocalAppData} C:\Users\Alice\AppData\Local 50 | ``` 51 | 52 | #### Start full node 53 | 54 | You can now run another full node and sync the chain from the node started earlier: 55 | ```bash 56 | target/production/subspace-node \ 57 | --dev \ 58 | --rpc-external \ 59 | --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp 60 | ``` 61 | 62 | ### Embedded Docs 63 | 64 | Once the project has been built, the following command can be used to explore all parameters and subcommands: 65 | 66 | ```bash 67 | target/production/subspace-node --help 68 | ``` 69 | -------------------------------------------------------------------------------- /crates/subspace-node/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; 18 | 19 | fn main() { 20 | generate_cargo_keys(); 21 | 22 | rerun_if_git_head_changed(); 23 | } 24 | -------------------------------------------------------------------------------- /crates/subspace-node/src/chain_spec_utils.rs: -------------------------------------------------------------------------------- 1 | use frame_support::traits::Get; 2 | use sc_service::Properties; 3 | use sp_core::crypto::AccountId32; 4 | use sp_core::{sr25519, Pair, Public}; 5 | use sp_runtime::traits::IdentifyAccount; 6 | use sp_runtime::MultiSigner; 7 | use subspace_runtime::SS58Prefix; 8 | use subspace_runtime_primitives::DECIMAL_PLACES; 9 | 10 | /// Shared chain spec properties related to the coin. 11 | pub(crate) fn chain_spec_properties() -> Properties { 12 | let mut properties = Properties::new(); 13 | 14 | properties.insert("ss58Format".into(), >::get().into()); 15 | properties.insert("tokenDecimals".into(), DECIMAL_PLACES.into()); 16 | properties.insert("tokenSymbol".into(), "tSSC".into()); 17 | 18 | properties 19 | } 20 | 21 | /// Get public key from keypair seed. 22 | pub(crate) fn get_public_key_from_seed( 23 | seed: &'static str, 24 | ) -> ::Public { 25 | TPublic::Pair::from_string(&format!("//{seed}"), None) 26 | .expect("Static values are valid; qed") 27 | .public() 28 | } 29 | 30 | /// Generate an account ID from seed. 31 | pub(crate) fn get_account_id_from_seed(seed: &'static str) -> AccountId32 { 32 | MultiSigner::from(get_public_key_from_seed::(seed)).into_account() 33 | } 34 | -------------------------------------------------------------------------------- /crates/subspace-node/src/core_domain.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod core_evm_chain_spec; 2 | 3 | use core_evm_runtime::AccountId as AccountId20; 4 | use sp_core::crypto::AccountId32; 5 | use sp_core::{ByteArray, H160}; 6 | use sp_runtime::traits::Convert; 7 | 8 | pub struct AccountId32ToAccountId20Converter; 9 | 10 | impl Convert for AccountId32ToAccountId20Converter { 11 | fn convert(acc: AccountId32) -> AccountId20 { 12 | // Using the full hex key, truncating to the first 20 bytes (the first 40 hex chars) 13 | H160::from_slice(&acc.as_slice()[0..20]).into() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /crates/subspace-node/src/system_domain.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | pub(crate) mod chain_spec; 18 | pub(crate) mod cli; 19 | -------------------------------------------------------------------------------- /crates/subspace-proof-of-space/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-proof-of-space" 3 | description = "Subspace proof of space implementation based on Chia" 4 | license = "Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/benches", 10 | "/src", 11 | "/Cargo.toml", 12 | ] 13 | 14 | [lib] 15 | # Necessary for CLI options to work on benches 16 | bench = false 17 | 18 | [dependencies] 19 | bitvec = { version = "1.0.1", default-features = false, features = ["alloc", "atomic"], optional = true } 20 | blake3 = { version = "1.4.0", default-features = false, optional = true } 21 | chacha20 = { version = "0.9.1", default-features = false, optional = true } 22 | rayon = { version = "1.7.0", optional = true } 23 | sha2 = { version = "0.10.7", optional = true } 24 | subspace-chiapos = { git = "https://github.com/subspace/chiapos", rev = "3b1ab3ca24764d25da30e0c8243e0bf304b776a5", optional = true } 25 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } 26 | 27 | [dev-dependencies] 28 | criterion = "0.5.1" 29 | rand = "0.8.5" 30 | subspace-chiapos = { git = "https://github.com/subspace/chiapos", rev = "3b1ab3ca24764d25da30e0c8243e0bf304b776a5" } 31 | 32 | [[bench]] 33 | name = "pos" 34 | harness = false 35 | 36 | [features] 37 | default = ["std"] 38 | std = [ 39 | "bitvec?/std", 40 | "blake3?/std", 41 | "chacha20?/std", 42 | "subspace-core-primitives/std", 43 | ] 44 | parallel = [ 45 | "dep:rayon", 46 | ] 47 | # Enable Chia proof of space support (legacy implementation uses C++ chiapos), only works in `std` environment for now 48 | chia-legacy = [ 49 | "std", 50 | "subspace-chiapos", 51 | ] 52 | # Enable Chia proof of space support, using alternative implementation, works in no-std environment as well 53 | chia = [ 54 | "bitvec", 55 | "blake3", 56 | "chacha20", 57 | "sha2", 58 | ] 59 | # Enable support for all possible K for chia: from smallest to insanely large as well as not popular in general 60 | all-chia-k = [] 61 | # Enables shim proof of space that works much faster than original and can be used for testing purposes to reduce memory 62 | # and CPU usage 63 | shim = [] 64 | -------------------------------------------------------------------------------- /crates/subspace-proof-of-space/src/chia_legacy.rs: -------------------------------------------------------------------------------- 1 | //! Chia proof of space implementation 2 | 3 | use crate::{PosTableType, Quality, Table}; 4 | use subspace_core_primitives::{PosProof, PosQualityBytes, PosSeed}; 5 | 6 | /// Abstraction that represents quality of the solution in the table. 7 | /// 8 | /// Chia implementation. 9 | #[derive(Debug)] 10 | #[must_use] 11 | pub struct ChiaQuality<'a> { 12 | quality: subspace_chiapos::Quality<'a>, 13 | } 14 | 15 | impl<'a> Quality for ChiaQuality<'a> { 16 | fn to_bytes(&self) -> PosQualityBytes { 17 | PosQualityBytes::from(self.quality.to_bytes()) 18 | } 19 | 20 | fn create_proof(&self) -> PosProof { 21 | PosProof::from(self.quality.create_proof()) 22 | } 23 | } 24 | 25 | /// Subspace proof of space table 26 | /// 27 | /// Chia implementation. 28 | #[derive(Debug)] 29 | pub struct ChiaTable { 30 | table: subspace_chiapos::Table, 31 | } 32 | 33 | impl Table for ChiaTable { 34 | const TABLE_TYPE: PosTableType = PosTableType::ChiaLegacy; 35 | 36 | type Quality<'a> = ChiaQuality<'a>; 37 | 38 | fn generate(seed: &PosSeed) -> ChiaTable { 39 | Self { 40 | table: subspace_chiapos::Table::generate(seed), 41 | } 42 | } 43 | 44 | fn find_quality(&self, challenge_index: u32) -> Option> { 45 | self.table 46 | .find_quality(challenge_index) 47 | .map(|quality| ChiaQuality { quality }) 48 | } 49 | 50 | fn is_proof_valid( 51 | seed: &PosSeed, 52 | challenge_index: u32, 53 | proof: &PosProof, 54 | ) -> Option { 55 | subspace_chiapos::is_proof_valid(seed, challenge_index, proof).map(PosQualityBytes::from) 56 | } 57 | } 58 | 59 | #[cfg(test)] 60 | mod tests { 61 | use super::*; 62 | 63 | const SEED: PosSeed = PosSeed::from([ 64 | 35, 2, 52, 4, 51, 55, 23, 84, 91, 10, 111, 12, 13, 222, 151, 16, 228, 211, 254, 45, 92, 65 | 198, 204, 10, 9, 10, 11, 129, 139, 171, 15, 23, 66 | ]); 67 | 68 | #[test] 69 | fn basic() { 70 | let table = ChiaTable::generate(&SEED); 71 | 72 | assert!(table.find_quality(0).is_none()); 73 | 74 | { 75 | let challenge_index = 1; 76 | let quality = table.find_quality(challenge_index).unwrap(); 77 | let proof = quality.create_proof(); 78 | let maybe_quality = ChiaTable::is_proof_valid(&SEED, challenge_index, &proof); 79 | assert_eq!(maybe_quality, Some(quality.to_bytes())); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /crates/subspace-proof-of-space/src/chiapos/constants.rs: -------------------------------------------------------------------------------- 1 | /// PRNG extension parameter to avoid collisions 2 | pub(super) const PARAM_EXT: u8 = 6; 3 | pub(super) const PARAM_M: u16 = 1 << PARAM_EXT; 4 | pub(super) const PARAM_B: u16 = 119; 5 | pub(super) const PARAM_C: u16 = 127; 6 | pub(super) const PARAM_BC: u16 = PARAM_B * PARAM_C; 7 | -------------------------------------------------------------------------------- /crates/subspace-proof-of-space/src/chiapos/tables/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::chiapos::{Tables, TablesCache}; 2 | use std::mem; 3 | 4 | const K: u8 = 17; 5 | 6 | #[test] 7 | fn self_verification() { 8 | let seed = [1; 32]; 9 | let tables = Tables::::create_simple(seed); 10 | let tables_parallel = Tables::::create_parallel(seed, &mut TablesCache::default()); 11 | 12 | for challenge_index in 0..1000_u32 { 13 | let mut challenge = [0; 32]; 14 | challenge[..mem::size_of::()].copy_from_slice(&challenge_index.to_le_bytes()); 15 | let qualities = tables.find_quality(&challenge).collect::>(); 16 | assert_eq!( 17 | qualities, 18 | tables_parallel.find_quality(&challenge).collect::>() 19 | ); 20 | let proofs = tables.find_proof(&challenge).collect::>(); 21 | assert_eq!( 22 | proofs, 23 | tables_parallel.find_proof(&challenge).collect::>() 24 | ); 25 | 26 | assert_eq!(qualities.len(), proofs.len()); 27 | 28 | for (quality, proof) in qualities.into_iter().zip(&proofs) { 29 | assert_eq!( 30 | Some(quality), 31 | Tables::::verify(seed, &challenge, proof), 32 | "challenge index {challenge_index}" 33 | ); 34 | let mut bad_challenge = [0; 32]; 35 | bad_challenge[..mem::size_of::()] 36 | .copy_from_slice(&(challenge_index + 1).to_le_bytes()); 37 | assert!( 38 | Tables::::verify(seed, &bad_challenge, proof).is_none(), 39 | "challenge index {challenge_index}" 40 | ); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /crates/subspace-proof-of-space/src/chiapos/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::chiapos::{Seed, Tables}; 2 | use std::mem; 3 | 4 | const K: u8 = 17; 5 | 6 | /// Chia does this for some reason 🤷‍ 7 | fn to_chia_seed(seed: &Seed) -> Seed { 8 | let mut chia_seed = [1u8; 32]; 9 | chia_seed[1..].copy_from_slice(&seed[..31]); 10 | chia_seed 11 | } 12 | 13 | #[test] 14 | fn test_against_chiapos() { 15 | let seed = [1; 32]; 16 | let original_table = subspace_chiapos::Table::generate(&seed); 17 | let chia_seed = to_chia_seed(&seed); 18 | let tables = Tables::::create_simple(chia_seed); 19 | 20 | for challenge_index in (0..1u32 << 16).map(|_| rand::random::()) { 21 | let mut challenge = [0; 32]; 22 | challenge[..mem::size_of::()].copy_from_slice(&challenge_index.to_le_bytes()); 23 | 24 | let maybe_original_proof = original_table 25 | .find_quality(challenge_index) 26 | .map(|quality| quality.create_proof()); 27 | 28 | let found_proofs = tables.find_proof(&challenge).collect::>(); 29 | 30 | // Due to bugs (https://github.com/Chia-Network/chiapos/issues/352) in C++ chiapos doesn't 31 | // find as many proofs and they are in different order due to compression, so we just verify 32 | // reference proofs with our verification function 33 | if let Some(original_proof) = maybe_original_proof { 34 | assert!(Tables::::verify(chia_seed, &challenge, &original_proof).is_some()); 35 | 36 | assert!(!found_proofs.is_empty()); 37 | } 38 | 39 | // All the proofs we produce must be valid according to C++ chiapos as well, even those that 40 | // C++ chiapos can't find after compression 41 | for proof in &found_proofs { 42 | assert!(subspace_chiapos::is_proof_valid(&seed, challenge_index, proof).is_some()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /crates/subspace-proof-of-space/src/chiapos/utils.rs: -------------------------------------------------------------------------------- 1 | /// TODO: Workaround for "unconstrained generic constant" suggested in 2 | /// https://github.com/rust-lang/rust/issues/82509#issuecomment-1165533546 3 | #[derive(Debug)] 4 | pub struct EvaluatableUsize; 5 | -------------------------------------------------------------------------------- /crates/subspace-rpc-primitives/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-rpc-primitives" 3 | version = "0.1.0" 4 | authors = ["Subspace Labs "] 5 | description = "RPC primitives for Subspace Network" 6 | edition = "2021" 7 | license = "Apache-2.0" 8 | homepage = "https://subspace.network" 9 | repository = "https://github.com/subspace/subspace" 10 | include = [ 11 | "/src", 12 | "/Cargo.toml", 13 | ] 14 | 15 | [dependencies] 16 | hex = { version = "0.4.3", features = ["serde"] } 17 | serde = { version = "1.0.159", features = ["derive"] } 18 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } 19 | subspace-farmer-components = { version = "0.1.0", path = "../subspace-farmer-components" } 20 | subspace-networking = { version = "0.1.0", path = "../subspace-networking" } 21 | -------------------------------------------------------------------------------- /crates/subspace-runtime-primitives/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-runtime-primitives" 3 | description = "Runtime primitives for Subspace Network" 4 | license = "GPL-3.0-or-later" 5 | version = "0.1.0" 6 | authors = ["Subspace Labs "] 7 | edition = "2021" 8 | homepage = "https://subspace.network" 9 | repository = "https://github.com/subspace/subspace" 10 | include = [ 11 | "/src", 12 | "/Cargo.toml", 13 | ] 14 | 15 | [package.metadata.docs.rs] 16 | targets = ["x86_64-unknown-linux-gnu"] 17 | 18 | [dependencies] 19 | parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } 20 | # TODO: Should, idealy, be optional, but `sp-runtime`'s `serde` feature is enabled unconditiionally by something in 21 | # Substrate and as the result our custom `Block` implementation has to derive `serde` traits essentially 22 | # unconditionally or else it doesn't compile 23 | serde = { version = "1.0.159", default-features = false, features = ["alloc", "derive"] } 24 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 25 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 27 | subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } 28 | 29 | [features] 30 | default = ["std"] 31 | std = [ 32 | "parity-scale-codec/std", 33 | "serde/std", 34 | "sp-core/std", 35 | "sp-runtime/std", 36 | "sp-std/std", 37 | "subspace-core-primitives/std", 38 | ] 39 | -------------------------------------------------------------------------------- /crates/subspace-runtime/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | fn main() { 18 | subspace_wasm_tools::create_runtime_bundle_inclusion_file( 19 | "system-domain-runtime", 20 | "SYSTEM_DOMAIN_WASM_BUNDLE", 21 | None, 22 | "system_domain_wasm_bundle.rs", 23 | ); 24 | 25 | #[cfg(feature = "std")] 26 | { 27 | substrate_wasm_builder::WasmBuilder::new() 28 | .with_current_project() 29 | .export_heap_base() 30 | .import_memory() 31 | .build(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /crates/subspace-runtime/src/weights.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod subspace; 2 | -------------------------------------------------------------------------------- /crates/subspace-runtime/tests/integration/main.rs: -------------------------------------------------------------------------------- 1 | mod object_mapping; 2 | -------------------------------------------------------------------------------- /crates/subspace-service/src/dsn/import_blocks/piece_validator.rs: -------------------------------------------------------------------------------- 1 | use async_trait::async_trait; 2 | use subspace_archiving::archiver::is_piece_valid; 3 | use subspace_core_primitives::crypto::kzg::Kzg; 4 | use subspace_core_primitives::{Piece, PieceIndex, SegmentCommitment}; 5 | use subspace_networking::libp2p::PeerId; 6 | use subspace_networking::utils::piece_provider::PieceValidator; 7 | use subspace_networking::Node; 8 | use tracing::{error, warn}; 9 | 10 | pub struct SegmentCommitmentPieceValidator { 11 | dsn_node: Node, 12 | kzg: Kzg, 13 | segment_commitment_cache: Vec, 14 | } 15 | 16 | impl SegmentCommitmentPieceValidator { 17 | /// Segment headers must be in order from 0 to the last one that exists 18 | pub fn new(dsn_node: Node, kzg: Kzg, segment_commitment_cache: Vec) -> Self { 19 | Self { 20 | dsn_node, 21 | kzg, 22 | segment_commitment_cache, 23 | } 24 | } 25 | } 26 | 27 | #[async_trait] 28 | impl PieceValidator for SegmentCommitmentPieceValidator { 29 | async fn validate_piece( 30 | &self, 31 | source_peer_id: PeerId, 32 | piece_index: PieceIndex, 33 | piece: Piece, 34 | ) -> Option { 35 | if source_peer_id != self.dsn_node.id() { 36 | let segment_index = piece_index.segment_index(); 37 | 38 | // TODO: Needs to statically require 64-bit environment or else u64->usize may cause 39 | // problems in the future 40 | let maybe_segment_commitment = self 41 | .segment_commitment_cache 42 | .get(u64::from(segment_index) as usize); 43 | let segment_commitment = match maybe_segment_commitment { 44 | Some(segment_commitment) => *segment_commitment, 45 | None => { 46 | error!(%segment_index, "No segment commitment in the cache."); 47 | 48 | return None; 49 | } 50 | }; 51 | 52 | if !is_piece_valid( 53 | &self.kzg, 54 | &piece, 55 | &segment_commitment, 56 | piece_index.position(), 57 | ) { 58 | warn!( 59 | %piece_index, 60 | %source_peer_id, 61 | "Received invalid piece from peer" 62 | ); 63 | 64 | // We don't care about result here 65 | let _ = self.dsn_node.ban_peer(source_peer_id).await; 66 | return None; 67 | } 68 | } 69 | 70 | Some(piece) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /crates/subspace-service/src/metrics.rs: -------------------------------------------------------------------------------- 1 | //! Node metrics 2 | 3 | use futures::StreamExt; 4 | use parity_scale_codec::Encode; 5 | use sc_client_api::{BlockBackend, BlockImportNotification, ImportNotifications}; 6 | use sp_runtime::traits::Block as BlockT; 7 | use std::sync::Arc; 8 | use substrate_prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64}; 9 | 10 | pub struct NodeMetrics { 11 | client: Arc, 12 | block_import: ImportNotifications, 13 | blocks: Counter, 14 | extrinsics: Counter, 15 | extrinsics_size: Counter, 16 | _p: std::marker::PhantomData, 17 | } 18 | 19 | impl NodeMetrics 20 | where 21 | Block: BlockT, 22 | Client: BlockBackend + 'static, 23 | { 24 | pub fn new( 25 | client: Arc, 26 | block_import: ImportNotifications, 27 | registry: &Registry, 28 | ) -> Result { 29 | Ok(Self { 30 | client, 31 | block_import, 32 | blocks: register( 33 | Counter::new("subspace_node_blocks", "Total number of imported blocks")?, 34 | registry, 35 | )?, 36 | extrinsics: register( 37 | Counter::new( 38 | "subspace_node_extrinsics", 39 | "Total number of extrinsics in the imported blocks", 40 | )?, 41 | registry, 42 | )?, 43 | extrinsics_size: register( 44 | Counter::new( 45 | "subspace_node_extrinsics_size", 46 | "Total extrinsic bytes in the imported blocks", 47 | )?, 48 | registry, 49 | )?, 50 | _p: Default::default(), 51 | }) 52 | } 53 | 54 | pub async fn run(mut self) { 55 | while let Some(incoming_block) = self.block_import.next().await { 56 | self.update_block_metrics(incoming_block); 57 | } 58 | } 59 | 60 | fn update_block_metrics(&mut self, incoming_block: BlockImportNotification) { 61 | let extrinsics = self 62 | .client 63 | .block_body(incoming_block.hash) 64 | .ok() 65 | .flatten() 66 | .unwrap_or(vec![]); 67 | self.blocks.inc(); 68 | self.extrinsics.inc_by(extrinsics.len() as u64); 69 | let total_size: usize = extrinsics 70 | .iter() 71 | .map(|extrinsic| extrinsic.encoded_size()) 72 | .sum(); 73 | self.extrinsics_size.inc_by(total_size as u64); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /crates/subspace-solving/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-solving" 3 | description = "Encoder for the Subspace Network Blockchain based on the SLOTH permutation" 4 | license = "Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | "/README.md", 12 | ] 13 | -------------------------------------------------------------------------------- /crates/subspace-solving/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxbulava/subspace/065dc94762db7e2531594b284daac6bd9f2d7b6e/crates/subspace-solving/README.md -------------------------------------------------------------------------------- /crates/subspace-solving/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Set of modules that implement utilities for solving and verifying of solutions in 17 | //! [Subspace Network Blockchain](https://subspace.network). 18 | 19 | #![forbid(unsafe_code)] 20 | #![warn(rust_2018_idioms, missing_debug_implementations, missing_docs)] 21 | #![cfg_attr(not(feature = "std"), no_std)] 22 | 23 | /// Signing context used for creating reward signatures by farmers. 24 | pub const REWARD_SIGNING_CONTEXT: &[u8] = b"subspace_reward"; 25 | -------------------------------------------------------------------------------- /crates/subspace-transaction-pool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-transaction-pool" 3 | version = "0.1.0" 4 | authors = ["Subspace Labs "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Subspace transaction pool" 10 | 11 | [dependencies] 12 | async-trait = "0.1.68" 13 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 14 | domain-runtime-primitives = { version = "0.1.0", path = "../../domains/primitives/runtime" } 15 | futures = "0.3.28" 16 | jsonrpsee = { version = "0.16.2", features = ["server"] } 17 | parking_lot = "0.12.1" 18 | sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | sc-consensus-subspace = { version = "0.1.0", path = "../sc-consensus-subspace" } 20 | sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 21 | sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 25 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } 27 | sp-domains = { version = "0.1.0", path = "../sp-domains" } 28 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 29 | sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 30 | substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 31 | tracing = "0.1.37" 32 | -------------------------------------------------------------------------------- /crates/subspace-verification/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-verification" 3 | version = "0.1.0" 4 | authors = ["Vedhavyas Singareddi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Verification primitives for Subspace" 10 | include = [ 11 | "/src", 12 | "/Cargo.toml", 13 | "/README.md", 14 | ] 15 | 16 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 17 | 18 | [dependencies] 19 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } 20 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 21 | schnorrkel = { version = "0.9.1", default-features = false, features = ["u64_backend"] } 22 | sp-arithmetic = { version = "16.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | subspace-archiving = { version = "0.1.0", path = "../subspace-archiving", default-features = false } 25 | subspace-solving = { version = "0.1.0", path = "../subspace-solving", default-features = false } 26 | subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } 27 | subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-space", default-features = false } 28 | thiserror = { version = "1.0.38", optional = true } 29 | 30 | [features] 31 | default = ["std"] 32 | std = [ 33 | "codec/std", 34 | "scale-info/std", 35 | "schnorrkel/std", 36 | "sp-arithmetic/std", 37 | "sp-std/std", 38 | "subspace-archiving/std", 39 | "subspace-core-primitives/std", 40 | "thiserror" 41 | ] 42 | -------------------------------------------------------------------------------- /crates/subspace-verification/README.md: -------------------------------------------------------------------------------- 1 | # Verification primitives for Subspace 2 | -------------------------------------------------------------------------------- /crates/subspace-wasm-tools/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-wasm-tools" 3 | description = "Utilities for building WASM bundles" 4 | license = "Apache-2.0" 5 | version = "0.1.0" 6 | authors = ["Nazar Mokrynskyi "] 7 | edition = "2021" 8 | include = [ 9 | "/src", 10 | "/Cargo.toml", 11 | ] 12 | -------------------------------------------------------------------------------- /docs/development.md: -------------------------------------------------------------------------------- 1 | ## Pre-requisites 2 | 3 | You'll have to have [Rust toolchain](https://rustup.rs/) installed as well as LLVM, Clang and CMake in addition to usual developer tooling (Ubuntu example): 4 | ```bash 5 | sudo apt-get install llvm clang cmake 6 | ``` 7 | 8 | ## To Farm By Yourself (Offline) 9 | 10 | 1. Download the executables for your operating system 11 | 2. Open your favourite terminal, and go to the folder where you download the executables 12 | 13 | **Linux/MacOS:** 14 | 1. Make them executable: `chmod +x subspace-farmer-x86_64-*-snapshot subspace-node-x86_64-*-snapshot` 15 | 2. Run the node: `./subspace-node-x86_64-*-snapshot --dev --tmp` 16 | 3. In macOS, it may prompt that this app is not verified. Click on `cancel` instead of moving it to trash. 17 | To allow execution, go to `System Preferences -> Security & Privacy -> General`, and click on `allow`. 18 | After this, simply repeat step 4. This time, there will be `Open` button in the prompt, click it to run node. 19 | 4. Run the farmer (do this in another terminal): `./subspace-farmer-x86_64-*-snapshot farm` 20 | 5. In macOS, it may prompt that this app is not verified. Click on `cancel` instead of moving it to trash. 21 | To allow execution, go to `System Preferences -> Security & Privacy -> General`, and click on `allow`. 22 | After this, simply repeat step 4. This time, there will be `Open` button in the prompt, click it to run node. 23 | 24 | **Windows** 25 | 1. Run the node: `subspace-node-x86_64-*-snapshot --dev --tmp` 26 | 2. After running this command, Windows may ask you for permissions related to firewall, select `allow` in this case. 27 | 3. Run the farmer (do this in another terminal): `subspace-farmer-x86_64-*-snapshot farm` 28 | 29 | ## To Run From The Source (primarily for developers) 30 | 31 | This is a monorepo with multiple binaries and the workflow is typical for Rust projects: 32 | 33 | - `cargo run --release --bin subspace-node -- --dev --tmp` to run [a node](/crates/subspace-node) 34 | - `cargo run --release --bin subspace-farmer farm --reward-address REWARD-ADDRESS --plot-size PLOT-SIZE` to [start farming](/crates/subspace-farmer) 35 | 36 | NOTE 1: You need to have `nightly` version of Rust toolchain with `wasm32-unknown-unknown` target available or else you'll get a compilation error. 37 | NOTE 2: Following the commands above, you will be farming in an offline setting (by yourself). 38 | NOTE 3: To farm in online setting, you can modify the command accordingly. 39 | 40 | You can find readme files in corresponding crates for requirements, multi-node setup and other details. 41 | -------------------------------------------------------------------------------- /domains/README.md: -------------------------------------------------------------------------------- 1 | # Cumulus fork 2 | 3 | This is a fork of [cumulus](https://github.com/paritytech/cumulus/commit/520012619e5428be50f47917aacd54e47860f43e), an experiment of the groundwork of Subspace secondary chains framework. 4 | 5 | - `client` 6 | - `cirrus-executor` 7 | - `cirrus-service` 8 | - `cli` 9 | - `consensus` 10 | - `common` 11 | - `relay-chain` 12 | - `parachain-template` 13 | - `node` 14 | - `runtime` 15 | 16 | The binary `parachain-collator` was renamed to `subspace-executor`. 17 | -------------------------------------------------------------------------------- /domains/client/block-builder/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "domain-block-builder" 3 | version = "0.1.0" 4 | authors = ["Parity Technologies "] 5 | edition = "2021" 6 | license = "GPL-3.0-or-later WITH Classpath-exception-2.0" 7 | homepage = "https://substrate.io" 8 | repository = "https://github.com/paritytech/substrate/" 9 | description = "Substrate block builder" 10 | readme = "README.md" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["x86_64-unknown-linux-gnu"] 14 | 15 | [dependencies] 16 | codec = { package = "parity-scale-codec", version = "3.4.0", features = ["derive"] } 17 | sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 25 | tracing = "0.1.37" 26 | 27 | [dev-dependencies] 28 | substrate-test-runtime-client = { version = "2.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 29 | -------------------------------------------------------------------------------- /domains/client/block-builder/README.md: -------------------------------------------------------------------------------- 1 | Substrate block builder 2 | 3 | This crate provides the [`BlockBuilder`] utility and the corresponding runtime api 4 | [`BlockBuilder`](https://docs.rs/sc-block-builder/latest/sc_block_builder/struct.BlockBuilder.html).Error 5 | 6 | The block builder utility is used in the node as an abstraction over the runtime api to 7 | initialize a block, to push extrinsics and to finalize a block. 8 | 9 | License: GPL-3.0-or-later WITH Classpath-exception-2.0 -------------------------------------------------------------------------------- /domains/client/block-preprocessor/src/inherents.rs: -------------------------------------------------------------------------------- 1 | //! Provides functionality of adding inherent extrinsics to the Domain. 2 | //! Unlike Primary chain where inherent data is first derived the block author 3 | //! and the data is verified by the on primary runtime, domains inherents 4 | //! short circuit the derivation and verification of inherent data 5 | //! as the inherent data is directly taken from the primary block from which 6 | //! domain block is being built. 7 | //! 8 | //! One of the first use case for this is passing Timestamp data. Before building a 9 | //! domain block using a primary block, we take the current time from the primary runtime 10 | //! and then create an unsigned extrinsic that is put on top the bundle extrinsics. 11 | //! 12 | //! Deriving these extrinsics during fraud proof verification should be possible since 13 | //! verification environment will have access to primary chain. 14 | 15 | use crate::runtime_api::InherentExtrinsicConstructor; 16 | use sp_api::ProvideRuntimeApi; 17 | use sp_domains::ExecutorApi; 18 | use sp_runtime::traits::Block as BlockT; 19 | use std::sync::Arc; 20 | 21 | /// Returns required inherent extrinsics for the domain block based on the primary block. 22 | /// Note: primary block hash must be used to construct domain block. 23 | // TODO: Remove once evm domain is supported. 24 | #[allow(dead_code)] 25 | pub fn construct_inherent_extrinsics( 26 | primary_client: &Arc, 27 | domain_runtime_api: &DomainRuntimeApi, 28 | primary_block_hash: PBlock::Hash, 29 | domain_parent_hash: Block::Hash, 30 | ) -> Result, sp_blockchain::Error> 31 | where 32 | Block: BlockT, 33 | PBlock: BlockT, 34 | PClient: ProvideRuntimeApi, 35 | PClient::Api: ExecutorApi, 36 | DomainRuntimeApi: InherentExtrinsicConstructor, 37 | { 38 | let primary_api = primary_client.runtime_api(); 39 | let moment = primary_api.timestamp(primary_block_hash)?; 40 | 41 | let mut inherent_exts = vec![]; 42 | if let Some(inherent_timestamp) = 43 | domain_runtime_api.construct_timestamp_inherent_extrinsic(domain_parent_hash, moment)? 44 | { 45 | inherent_exts.push(inherent_timestamp) 46 | } 47 | 48 | Ok(inherent_exts) 49 | } 50 | -------------------------------------------------------------------------------- /domains/client/block-preprocessor/src/runtime_api.rs: -------------------------------------------------------------------------------- 1 | use domain_runtime_primitives::opaque::AccountId; 2 | use sp_api::{ApiError, BlockT}; 3 | use sp_domains::OpaqueBundle; 4 | use sp_messenger::messages::ExtractedStateRootsFromProof; 5 | use sp_runtime::traits::NumberFor; 6 | 7 | pub type ExtractedStateRoots = ExtractedStateRootsFromProof< 8 | NumberFor, 9 | ::Hash, 10 | ::Hash, 11 | >; 12 | 13 | /// Trait to extract XDM state roots from the Extrinsic. 14 | pub trait StateRootExtractor { 15 | /// Extracts the state roots from the extrinsic. 16 | fn extract_state_roots( 17 | &self, 18 | at: Block::Hash, 19 | ext: &Block::Extrinsic, 20 | ) -> Result, ApiError>; 21 | } 22 | 23 | /// Trait to extract core domain bundles from the given set of core domain extrinsics. 24 | pub trait CoreBundleConstructor { 25 | fn construct_submit_core_bundle_extrinsics( 26 | &self, 27 | at: Block::Hash, 28 | opaque_bundles: Vec, PBlock::Hash, Block::Hash>>, 29 | ) -> Result>, ApiError>; 30 | } 31 | 32 | /// Trait to construct inherent extrinsics 33 | pub trait InherentExtrinsicConstructor { 34 | /// Returns Inherent timestamp extrinsic if the Runtime implements the API. 35 | fn construct_timestamp_inherent_extrinsic( 36 | &self, 37 | at: Block::Hash, 38 | moment: subspace_runtime_primitives::Moment, 39 | ) -> Result, ApiError>; 40 | } 41 | 42 | /// Trait to wrap the new domain runtime as an extrinsic of 43 | /// `domain_pallet_executive::Call::sudo_unchecked_weight_unsigned`. 44 | pub trait SetCodeConstructor { 45 | fn construct_set_code_extrinsic( 46 | &self, 47 | at: Block::Hash, 48 | runtime_code: Vec, 49 | ) -> Result, ApiError>; 50 | } 51 | 52 | pub type ExtractSignerResult = Vec<(Option, ::Extrinsic)>; 53 | 54 | /// Trait to extract the signer of the extrinsic. 55 | pub trait SignerExtractor { 56 | fn extract_signer( 57 | &self, 58 | at: Block::Hash, 59 | extrinsics: Vec<::Extrinsic>, 60 | ) -> Result, ApiError>; 61 | } 62 | -------------------------------------------------------------------------------- /domains/client/consensus-relay-chain/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "domain-client-consensus-relay-chain" 3 | description = "The relay-chain provided consensus algorithm" 4 | version = "0.1.0" 5 | authors = ["Parity Technologies "] 6 | edition = "2021" 7 | 8 | [dependencies] 9 | async-trait = "0.1.68" 10 | futures = "0.3.28" 11 | parking_lot = "0.12.1" 12 | sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 13 | sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 14 | sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 15 | sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 16 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 17 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | -------------------------------------------------------------------------------- /domains/client/consensus-relay-chain/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Parity Technologies (UK) Ltd. 2 | // This file is part of Cumulus. 3 | 4 | // Cumulus is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // Cumulus is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with Cumulus. If not, see . 16 | 17 | //! The relay-chain provided consensus algoritm for parachains. 18 | //! 19 | //! This is the simplest consensus algorithm you can use when developing a parachain. It is a 20 | //! permission-less consensus algorithm that doesn't require any staking or similar to join as a 21 | //! collator. In this algorithm the consensus is provided by the relay-chain. This works in the 22 | //! following way. 23 | //! 24 | //! 1. Each node that sees itself as a collator is free to build a parachain candidate. 25 | //! 26 | //! 2. This parachain candidate is send to the parachain validators that are part of the relay chain. 27 | //! 28 | //! 3. The parachain validators validate at most X different parachain candidates, where X is the 29 | //! total number of parachain validators. 30 | //! 31 | //! 4. The parachain candidate that is backed by the most validators is choosen by the relay-chain 32 | //! block producer to be added as backed candidate on chain. 33 | //! 34 | //! 5. After the parachain candidate got backed and included, all collators start at 1. 35 | 36 | mod import_queue; 37 | 38 | pub use import_queue::{import_queue, DomainBlockImport, Verifier}; 39 | -------------------------------------------------------------------------------- /domains/client/cross-domain-message-gossip/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cross-domain-message-gossip" 3 | version = "0.1.0" 4 | authors = ["Vedhavyas Singareddi "] 5 | edition = "2021" 6 | homepage = "https://subspace.network" 7 | repository = "https://github.com/subspace/subspace" 8 | description = "Subspace message relayer." 9 | include = [ 10 | "/src", 11 | "/Cargo.toml", 12 | ] 13 | 14 | [dependencies] 15 | futures = "0.3.28" 16 | parity-scale-codec = { version = "3.4.0", features = ["derive"] } 17 | parking_lot = "0.12.1" 18 | sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } 25 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | tracing = "0.1.37" 27 | -------------------------------------------------------------------------------- /domains/client/cross-domain-message-gossip/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(rust_2018_idioms)] 2 | 3 | mod gossip_worker; 4 | mod message_listener; 5 | 6 | pub use gossip_worker::{ 7 | cdm_gossip_peers_set_config, DomainTxPoolSink, GossipWorker, GossipWorkerBuilder, Message, 8 | }; 9 | pub use message_listener::start_domain_message_listener; 10 | -------------------------------------------------------------------------------- /domains/client/cross-domain-message-gossip/src/message_listener.rs: -------------------------------------------------------------------------------- 1 | use futures::{Stream, StreamExt}; 2 | use sc_transaction_pool_api::{TransactionPool, TransactionSource}; 3 | use sp_blockchain::HeaderBackend; 4 | use sp_domains::DomainId; 5 | use sp_runtime::codec::Decode; 6 | use sp_runtime::generic::BlockId; 7 | use sp_runtime::traits::Block as BlockT; 8 | use std::sync::Arc; 9 | 10 | const LOG_TARGET: &str = "domain_message_listener"; 11 | 12 | type DomainBlockOf = ::Block; 13 | type DomainExtrinsicOf = <::Block as BlockT>::Extrinsic; 14 | 15 | pub async fn start_domain_message_listener( 16 | domain_id: DomainId, 17 | client: Arc, 18 | tx_pool: Arc, 19 | mut listener: TxnListener, 20 | ) where 21 | TxPool: TransactionPool + 'static, 22 | Client: HeaderBackend>, 23 | TxnListener: Stream> + Unpin, 24 | { 25 | tracing::info!( 26 | target: LOG_TARGET, 27 | "Starting transaction listener for domain: {:?}", 28 | domain_id 29 | ); 30 | 31 | while let Some(encoded_ext) = listener.next().await { 32 | tracing::debug!( 33 | target: LOG_TARGET, 34 | "Extrinsic received for domain: {:?}", 35 | domain_id, 36 | ); 37 | 38 | let ext = match DomainExtrinsicOf::::decode(&mut encoded_ext.as_ref()) { 39 | Ok(ext) => ext, 40 | Err(_) => { 41 | tracing::error!( 42 | target: LOG_TARGET, 43 | "Failed to decode extrinsic: {:?}", 44 | encoded_ext 45 | ); 46 | continue; 47 | } 48 | }; 49 | 50 | let at = BlockId::Hash(client.info().best_hash); 51 | tracing::debug!( 52 | target: LOG_TARGET, 53 | "Submitting extrinsic to tx pool at block: {:?}", 54 | at 55 | ); 56 | 57 | let tx_pool_res = tx_pool 58 | .submit_one(&at, TransactionSource::External, ext) 59 | .await; 60 | 61 | if let Err(err) = tx_pool_res { 62 | tracing::error!( 63 | target: LOG_TARGET, 64 | "Failed to submit extrinsic to tx pool for domain {:?} with error: {:?}", 65 | domain_id, 66 | err 67 | ); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /domains/client/domain-executor/src/utils.rs: -------------------------------------------------------------------------------- 1 | use codec::{Decode, Encode}; 2 | use parking_lot::Mutex; 3 | use sc_utils::mpsc::{TracingUnboundedReceiver, TracingUnboundedSender}; 4 | use sp_consensus_slots::Slot; 5 | use sp_runtime::traits::{Block as BlockT, NumberFor}; 6 | use std::convert::TryInto; 7 | use std::sync::Arc; 8 | use subspace_core_primitives::{Blake2b256Hash, BlockNumber}; 9 | 10 | /// Data required to produce bundles on executor node. 11 | #[derive(PartialEq, Clone, Debug)] 12 | pub(super) struct ExecutorSlotInfo { 13 | /// Slot 14 | pub(super) slot: Slot, 15 | /// Global challenge 16 | pub(super) global_challenge: Blake2b256Hash, 17 | } 18 | 19 | #[derive(Debug, Clone)] 20 | pub(crate) struct BlockInfo 21 | where 22 | Block: BlockT, 23 | { 24 | /// hash of the block. 25 | pub hash: Block::Hash, 26 | /// hash of the parent block. 27 | pub parent_hash: Block::Hash, 28 | /// block's number. 29 | pub number: NumberFor, 30 | } 31 | 32 | // TODO: unify this with trait bounds set directly on block traits. 33 | // Maybe we dont need these translations.? 34 | /// Converts the block number from the generic type `N1` to `N2`. 35 | pub(crate) fn translate_number_type(block_number: N1) -> N2 36 | where 37 | N1: TryInto, 38 | N2: From, 39 | { 40 | N2::from(to_number_primitive(block_number)) 41 | } 42 | 43 | /// Converts a generic block number to a concrete primitive block number. 44 | pub(crate) fn to_number_primitive(block_number: N) -> BlockNumber 45 | where 46 | N: TryInto, 47 | { 48 | block_number 49 | .try_into() 50 | .unwrap_or_else(|_| panic!("Block number must fit into u32; qed")) 51 | } 52 | 53 | /// Converts the block hash from the generic type `B1::Hash` to `B2::Hash`. 54 | pub(crate) fn translate_block_hash_type(block_hash: B1::Hash) -> B2::Hash 55 | where 56 | B1: BlockT, 57 | B2: BlockT, 58 | { 59 | B2::Hash::decode(&mut block_hash.encode().as_slice()).unwrap() 60 | } 61 | 62 | pub type DomainImportNotificationSinks = 63 | Arc>>>>; 64 | 65 | pub type DomainImportNotifications = 66 | TracingUnboundedReceiver>; 67 | 68 | #[derive(Clone, Debug)] 69 | pub struct DomainBlockImportNotification { 70 | pub domain_block_hash: Block::Hash, 71 | pub primary_block_hash: PBlock::Hash, 72 | } 73 | -------------------------------------------------------------------------------- /domains/client/eth-service/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(rust_2018_idioms)] 2 | 3 | pub mod provider; 4 | pub(crate) mod rpc; 5 | mod service; 6 | 7 | pub use rpc::DefaultEthConfig; 8 | pub use service::EthConfiguration; 9 | -------------------------------------------------------------------------------- /domains/client/executor-gossip/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "domain-client-executor-gossip" 3 | version = "0.1.0" 4 | authors = ["Liu-Cheng Xu "] 5 | edition = "2021" 6 | 7 | [dependencies] 8 | futures = "0.3.28" 9 | parity-scale-codec = { version = "3.4.0", features = ["derive"] } 10 | parking_lot = "0.12.1" 11 | sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 12 | sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 13 | sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 14 | sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 15 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 16 | sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } 17 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | tracing = "0.1.37" 19 | -------------------------------------------------------------------------------- /domains/client/relayer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "domain-client-message-relayer" 3 | version = "0.1.0" 4 | authors = ["Vedhavyas Singareddi "] 5 | edition = "2021" 6 | homepage = "https://subspace.network" 7 | repository = "https://github.com/subspace/subspace" 8 | description = "Subspace message relayer." 9 | include = [ 10 | "/src", 11 | "/Cargo.toml", 12 | ] 13 | 14 | [dependencies] 15 | async-channel = "1.8.0" 16 | cross-domain-message-gossip = { path = "../../client/cross-domain-message-gossip" } 17 | domain-runtime-primitives = { path = "../../primitives/runtime" } 18 | futures = "0.3.28" 19 | parity-scale-codec = { version = "3.4.0", features = ["derive"] } 20 | parking_lot = "0.12.1" 21 | sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 25 | sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 27 | sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 28 | sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 29 | sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 30 | sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } 31 | sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" } 32 | sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 33 | sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement" } 34 | system-runtime-primitives = { version = "0.1.0", path = "../../primitives/system-runtime" } 35 | tracing = "0.1.37" 36 | -------------------------------------------------------------------------------- /domains/pallets/messenger/README.md: -------------------------------------------------------------------------------- 1 | # Pallet Messenger 2 | 3 | Subspace node pallet for cross domain and cross chain messaging 4 | 5 | License: Apache-2.0 6 | -------------------------------------------------------------------------------- /domains/pallets/transporter/README.md: -------------------------------------------------------------------------------- 1 | # Pallet Transporter 2 | 3 | Subspace node pallet for moving funds between domains. 4 | 5 | License: Apache-2.0 6 | -------------------------------------------------------------------------------- /domains/primitives/digests/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sp-domain-digests" 3 | version = "0.1.0" 4 | authors = ["Vedhavyas Singareddi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Primitives of domain related digests" 10 | include = [ 11 | "/src", 12 | "/Cargo.toml", 13 | "/README.md", 14 | ] 15 | 16 | [dependencies] 17 | codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } 18 | sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } 21 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | 23 | [features] 24 | default = ["std"] 25 | std = [ 26 | "codec/std", 27 | "sp-api/std", 28 | "sp-core/std", 29 | "sp-domains/std", 30 | "sp-runtime/std", 31 | ] 32 | -------------------------------------------------------------------------------- /domains/primitives/digests/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | 3 | use codec::{Decode, Encode}; 4 | use sp_runtime::{ConsensusEngineId, DigestItem}; 5 | 6 | const DOMAIN_REGISTRY_ENGINE_ID: ConsensusEngineId = *b"RGTR"; 7 | 8 | /// Trait to provide simpler abstractions to create predigests for runtime. 9 | pub trait AsPredigest { 10 | /// Return a pair of (primary_block_number, primary_block_hash). 11 | fn as_primary_block_info(&self) -> Option<(Number, Hash)>; 12 | 13 | /// Creates a new digest of primary block info for system domain. 14 | fn primary_block_info(info: (Number, Hash)) -> Self; 15 | } 16 | 17 | impl AsPredigest for DigestItem { 18 | /// Return a pair of (primary_block_number, primary_block_hash). 19 | fn as_primary_block_info(&self) -> Option<(Number, Hash)> { 20 | self.pre_runtime_try_to(&DOMAIN_REGISTRY_ENGINE_ID) 21 | } 22 | 23 | fn primary_block_info(info: (Number, Hash)) -> Self { 24 | DigestItem::PreRuntime(DOMAIN_REGISTRY_ENGINE_ID, info.encode()) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /domains/primitives/executor-registry/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sp-executor-registry" 3 | version = "0.1.0" 4 | authors = ["Liu-Cheng Xu "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Primitives of executor registry" 10 | 11 | [package.metadata.docs.rs] 12 | targets = ["x86_64-unknown-linux-gnu"] 13 | 14 | [dependencies] 15 | parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } 16 | sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } 17 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | 19 | [features] 20 | default = ["std"] 21 | std = [ 22 | "parity-scale-codec/std", 23 | "sp-domains/std", 24 | "sp-std/std", 25 | ] 26 | runtime-benchmarks = [] 27 | -------------------------------------------------------------------------------- /domains/primitives/messenger/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sp-messenger" 3 | version = "0.1.0" 4 | authors = ["Vedhavyas Singareddi "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Primitives for Messenger" 10 | include = [ 11 | "/src", 12 | "/Cargo.toml", 13 | "/README.md", 14 | ] 15 | 16 | [dependencies] 17 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } 18 | frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | hash-db = { version = "0.16.0", default-features = false } 20 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 21 | sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } 24 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 25 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 27 | 28 | [features] 29 | default = ["std"] 30 | std = [ 31 | "codec/std", 32 | "frame-support/std", 33 | "hash-db/std", 34 | "scale-info/std", 35 | "sp-api/std", 36 | "sp-core/std", 37 | "sp-domains/std", 38 | "sp-runtime/std", 39 | "sp-std/std", 40 | "sp-trie/std" 41 | ] 42 | 43 | runtime-benchmarks = [] 44 | -------------------------------------------------------------------------------- /domains/primitives/messenger/src/verification.rs: -------------------------------------------------------------------------------- 1 | use codec::{Decode, Encode}; 2 | use frame_support::PalletError; 3 | use hash_db::Hasher; 4 | use scale_info::TypeInfo; 5 | use sp_core::storage::StorageKey; 6 | use sp_std::marker::PhantomData; 7 | use sp_trie::{read_trie_value, LayoutV1, StorageProof}; 8 | 9 | /// Verification error. 10 | #[derive(Debug, PartialEq, Eq, Encode, Decode, PalletError, TypeInfo)] 11 | pub enum VerificationError { 12 | /// Emits when the expected state root doesn't exist 13 | InvalidStateRoot, 14 | /// Emits when the given storage proof is invalid. 15 | InvalidProof, 16 | /// Value doesn't exist in the Db for the given key. 17 | MissingValue, 18 | /// Failed to decode value. 19 | FailedToDecode, 20 | } 21 | 22 | pub struct StorageProofVerifier(PhantomData); 23 | 24 | impl StorageProofVerifier { 25 | pub fn verify_and_get_value( 26 | state_root: &H::Out, 27 | proof: StorageProof, 28 | key: StorageKey, 29 | ) -> Result { 30 | let db = proof.into_memory_db::(); 31 | let val = read_trie_value::, _>(&db, state_root, key.as_ref(), None, None) 32 | .map_err(|_| VerificationError::InvalidProof)? 33 | .ok_or(VerificationError::MissingValue)?; 34 | 35 | let decoded = V::decode(&mut &val[..]).map_err(|_| VerificationError::FailedToDecode)?; 36 | 37 | Ok(decoded) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /domains/primitives/runtime/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "domain-runtime-primitives" 3 | version = "0.1.0" 4 | authors = ["Subspace Labs "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Common primitives of subspace domain runtime" 10 | 11 | [package.metadata.docs.rs] 12 | targets = ["x86_64-unknown-linux-gnu"] 13 | 14 | [dependencies] 15 | parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } 16 | scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } 17 | sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives", default-features = false } 22 | 23 | [features] 24 | default = ["std"] 25 | std = [ 26 | "parity-scale-codec/std", 27 | "scale-info/std", 28 | "sp-api/std", 29 | "sp-core/std", 30 | "sp-runtime/std", 31 | "sp-std/std", 32 | "subspace-runtime-primitives/std", 33 | ] 34 | -------------------------------------------------------------------------------- /domains/primitives/system-runtime/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "system-runtime-primitives" 3 | version = "0.1.0" 4 | authors = ["Subspace Labs "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | description = "Primitives of system domain runtime" 10 | 11 | [package.metadata.docs.rs] 12 | targets = ["x86_64-unknown-linux-gnu"] 13 | 14 | [dependencies] 15 | parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } 16 | sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 17 | sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } 19 | sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | 22 | [features] 23 | default = ["std"] 24 | std = [ 25 | "parity-scale-codec/std", 26 | "sp-api/std", 27 | "sp-core/std", 28 | "sp-domains/std", 29 | "sp-runtime/std", 30 | "sp-std/std", 31 | ] 32 | -------------------------------------------------------------------------------- /domains/primitives/system-runtime/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Primitives for system domain runtime. 17 | 18 | #![cfg_attr(not(feature = "std"), no_std)] 19 | 20 | use parity_scale_codec::{Decode, Encode}; 21 | use sp_domains::bundle_election::BundleElectionSolverParams; 22 | use sp_domains::{DomainId, ExecutorPublicKey, OpaqueBundle}; 23 | use sp_runtime::traits::Block as BlockT; 24 | use sp_std::vec::Vec; 25 | 26 | sp_api::decl_runtime_apis! { 27 | /// API necessary for system domain. 28 | pub trait SystemDomainApi { 29 | /// Wrap the core domain bundles into extrinsics. 30 | fn construct_submit_core_bundle_extrinsics( 31 | opaque_bundles: Vec::Hash>>, 32 | ) -> Vec>; 33 | 34 | /// Returns the parameters for solving the bundle election. 35 | fn bundle_election_solver_params(domain_id: DomainId) -> BundleElectionSolverParams; 36 | 37 | fn core_bundle_election_storage_keys( 38 | domain_id: DomainId, 39 | executor_public_key: ExecutorPublicKey, 40 | ) -> Option>>; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /domains/runtime/core-evm/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | #[cfg(feature = "std")] 3 | { 4 | substrate_wasm_builder::WasmBuilder::new() 5 | .with_current_project() 6 | .enable_feature("wasm-builder") 7 | .export_heap_base() 8 | .import_memory() 9 | .build(); 10 | } 11 | 12 | subspace_wasm_tools::export_wasm_bundle_path(); 13 | } 14 | -------------------------------------------------------------------------------- /domains/runtime/core-evm/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. 3 | #![recursion_limit = "256"] 4 | 5 | // Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported 6 | // functions 7 | #[cfg(any(feature = "wasm-builder", feature = "std"))] 8 | mod precompiles; 9 | #[cfg(any(feature = "wasm-builder", feature = "std"))] 10 | mod runtime; 11 | 12 | // Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported 13 | // functions 14 | #[cfg(any(feature = "wasm-builder", feature = "std"))] 15 | pub use runtime::*; 16 | 17 | // Make the WASM binary available. 18 | #[cfg(feature = "std")] 19 | include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); 20 | -------------------------------------------------------------------------------- /domains/runtime/core-evm/src/precompiles.rs: -------------------------------------------------------------------------------- 1 | use pallet_evm::{ 2 | IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, 3 | }; 4 | use sp_core::H160; 5 | use sp_std::marker::PhantomData; 6 | 7 | use pallet_evm_precompile_modexp::Modexp; 8 | use pallet_evm_precompile_sha3fips::Sha3FIPS256; 9 | use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; 10 | 11 | pub struct Precompiles(PhantomData); 12 | 13 | impl Precompiles 14 | where 15 | R: pallet_evm::Config, 16 | { 17 | pub fn used_addresses() -> [H160; 7] { 18 | [ 19 | hash(1), 20 | hash(2), 21 | hash(3), 22 | hash(4), 23 | hash(5), 24 | hash(1024), 25 | hash(1025), 26 | ] 27 | } 28 | } 29 | 30 | impl Default for Precompiles { 31 | #[inline] 32 | fn default() -> Self { 33 | Self(PhantomData) 34 | } 35 | } 36 | 37 | impl PrecompileSet for Precompiles 38 | where 39 | R: pallet_evm::Config, 40 | { 41 | fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { 42 | match handle.code_address() { 43 | // Ethereum precompiles : 44 | a if a == hash(1) => Some(ECRecover::execute(handle)), 45 | a if a == hash(2) => Some(Sha256::execute(handle)), 46 | a if a == hash(3) => Some(Ripemd160::execute(handle)), 47 | a if a == hash(4) => Some(Identity::execute(handle)), 48 | a if a == hash(5) => Some(Modexp::execute(handle)), 49 | // Non-Frontier specific nor Ethereum precompiles : 50 | a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), 51 | a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), 52 | _ => None, 53 | } 54 | } 55 | 56 | fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { 57 | IsPrecompileResult::Answer { 58 | is_precompile: Self::used_addresses().contains(&address), 59 | extra_cost: 0, 60 | } 61 | } 62 | } 63 | 64 | fn hash(a: u64) -> H160 { 65 | H160::from_low_u64_be(a) 66 | } 67 | -------------------------------------------------------------------------------- /domains/runtime/system/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | #[cfg(feature = "std")] 3 | { 4 | substrate_wasm_builder::WasmBuilder::new() 5 | .with_current_project() 6 | .enable_feature("wasm-builder") 7 | .export_heap_base() 8 | .import_memory() 9 | .build(); 10 | } 11 | 12 | subspace_wasm_tools::export_wasm_bundle_path(); 13 | } 14 | -------------------------------------------------------------------------------- /domains/runtime/system/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. 3 | #![recursion_limit = "256"] 4 | 5 | // Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported 6 | // functions 7 | #[cfg(any(feature = "wasm-builder", feature = "std"))] 8 | mod runtime; 9 | 10 | // Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported 11 | // functions 12 | #[cfg(any(feature = "wasm-builder", feature = "std"))] 13 | pub use runtime::*; 14 | 15 | // Make the WASM binary available. 16 | #[cfg(feature = "std")] 17 | include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); 18 | 19 | #[cfg(feature = "runtime-benchmarks")] 20 | #[macro_use] 21 | extern crate frame_benchmarking; 22 | -------------------------------------------------------------------------------- /domains/service/build.rs: -------------------------------------------------------------------------------- 1 | use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; 2 | 3 | fn main() { 4 | generate_cargo_keys(); 5 | 6 | rerun_if_git_head_changed(); 7 | } 8 | -------------------------------------------------------------------------------- /domains/test/primitives/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "domain-test-primitives" 3 | version = "0.1.0" 4 | authors = ["Subspace Labs "] 5 | edition = "2021" 6 | license = "GPL-3.0-or-later" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | include = [ 10 | "/src", 11 | "/Cargo.toml", 12 | ] 13 | 14 | [dependencies] 15 | codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"]} 16 | sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 17 | sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } 18 | sp-messenger = { version = "0.1.0", default-features = false, path = "../../primitives/messenger" } 19 | subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives", default-features = false } 20 | 21 | [features] 22 | default = ["std"] 23 | std = [ 24 | "sp-api/std", 25 | "subspace-runtime-primitives/std", 26 | ] 27 | -------------------------------------------------------------------------------- /domains/test/primitives/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | //! Test primitive crates that expose necessary extensions that are used in tests. 3 | 4 | use codec::{Decode, Encode}; 5 | use sp_domains::DomainId; 6 | use sp_messenger::messages::ChannelId; 7 | use subspace_runtime_primitives::Moment; 8 | 9 | sp_api::decl_runtime_apis! { 10 | /// Api that returns the timestamp 11 | pub trait TimestampApi { 12 | /// Api to construct inherent timestamp extrinsic from given time 13 | fn timestamp() -> Moment; 14 | } 15 | } 16 | 17 | sp_api::decl_runtime_apis! { 18 | /// Api for querying onchain state in the test 19 | pub trait OnchainStateApi 20 | where 21 | AccountId: Encode + Decode, 22 | Balance: Encode + Decode 23 | { 24 | /// Api to get the free balance of the given account 25 | fn free_balance(account_id: AccountId) -> Balance; 26 | 27 | /// Returns the last open channel for a given domain. 28 | fn get_open_channel_for_domain(dst_domain_id: DomainId) -> Option; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /domains/test/runtime/system/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | #[cfg(feature = "std")] 3 | { 4 | substrate_wasm_builder::WasmBuilder::new() 5 | .with_current_project() 6 | .enable_feature("wasm-builder") 7 | .export_heap_base() 8 | .import_memory() 9 | .build(); 10 | } 11 | 12 | subspace_wasm_tools::export_wasm_bundle_path(); 13 | } 14 | -------------------------------------------------------------------------------- /domains/test/runtime/system/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. 3 | #![recursion_limit = "256"] 4 | 5 | // Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported 6 | // functions 7 | #[cfg(any(feature = "wasm-builder", feature = "std"))] 8 | mod runtime; 9 | 10 | // Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported 11 | // functions 12 | #[cfg(any(feature = "wasm-builder", feature = "std"))] 13 | pub use runtime::*; 14 | 15 | // Make the WASM binary available. 16 | #[cfg(feature = "std")] 17 | include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); 18 | -------------------------------------------------------------------------------- /orml/README.md: -------------------------------------------------------------------------------- 1 | This directory contains forks of crates from [orml](https://github.com/subspace/open-runtime-module-library) to simplify Substrate upgrades for Subspace. 2 | 3 | The only changes are paths to dependencies. 4 | -------------------------------------------------------------------------------- /orml/vesting/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "orml-vesting" 3 | description = "Provides scheduled balance locking mechanism, in a *graded vesting* way." 4 | repository = "https://github.com/open-web3-stack/open-runtime-module-library/tree/master/vesting" 5 | license = "Apache-2.0" 6 | version = "0.4.1-dev" 7 | authors = ["Laminar Developers "] 8 | edition = "2021" 9 | 10 | [dependencies] 11 | codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["max-encoded-len"] } 12 | scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } 13 | serde = { version = "1.0.136", optional = true } 14 | 15 | frame-support = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 16 | frame-system = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 17 | sp-io = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 18 | sp-runtime = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 19 | sp-std = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 20 | 21 | [dev-dependencies] 22 | pallet-balances = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 23 | sp-core = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | 25 | [features] 26 | default = ["std"] 27 | std = [ 28 | "serde", 29 | 30 | "codec/std", 31 | "frame-support/std", 32 | "frame-system/std", 33 | "scale-info/std", 34 | "sp-io/std", 35 | "sp-runtime/std", 36 | "sp-std/std", 37 | ] 38 | runtime-benchmarks = [ 39 | "frame-support/runtime-benchmarks", 40 | "frame-system/runtime-benchmarks", 41 | "sp-runtime/runtime-benchmarks", 42 | ] 43 | try-runtime = [ 44 | "frame-support/try-runtime", 45 | "frame-system/try-runtime", 46 | ] 47 | -------------------------------------------------------------------------------- /orml/vesting/README.md: -------------------------------------------------------------------------------- 1 | # Vesting Module 2 | 3 | ## Overview 4 | 5 | Vesting module provides a means of scheduled balance lock on an account. It uses the *graded vesting* way, which unlocks a specific amount of balance every period of time, until all balance unlocked. 6 | 7 | ### Vesting Schedule 8 | 9 | The schedule of a vesting is described by data structure `VestingSchedule`: from the block number of `start`, for every `period` amount of blocks, `per_period` amount of balance would unlocked, until number of periods `period_count` reached. Note in vesting schedules, *time* is measured by block number. All `VestingSchedule`s under an account could be queried in chain state. 10 | -------------------------------------------------------------------------------- /orml/vesting/src/default_weight.rs: -------------------------------------------------------------------------------- 1 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 2 | 3 | #![allow(unused_parens)] 4 | #![allow(unused_imports)] 5 | #![allow(clippy::unnecessary_cast)] 6 | 7 | use frame_support::weights::{constants::RocksDbWeight as DbWeight, Weight}; 8 | 9 | impl crate::WeightInfo for () { 10 | fn vested_transfer() -> Weight { 11 | Weight::from_parts(310_862_000, 0) 12 | .saturating_add(DbWeight::get().reads(4 as u64)) 13 | .saturating_add(DbWeight::get().writes(4 as u64)) 14 | } 15 | fn claim(i: u32) -> Weight { 16 | Weight::from_parts(158_614_000, 0) 17 | .saturating_add(Weight::from_parts(958_000, 0).saturating_mul(i as u64)) 18 | .saturating_add(DbWeight::get().reads(3 as u64)) 19 | .saturating_add(DbWeight::get().writes(3 as u64)) 20 | } 21 | fn update_vesting_schedules(i: u32) -> Weight { 22 | Weight::from_parts(119_811_000, 0) 23 | .saturating_add(Weight::from_parts(2_320_000, 0).saturating_mul(i as u64)) 24 | .saturating_add(DbWeight::get().reads(2 as u64)) 25 | .saturating_add(DbWeight::get().writes(3 as u64)) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /orml/vesting/src/weights.rs: -------------------------------------------------------------------------------- 1 | //! Autogenerated weights for orml_vesting 2 | //! 3 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 4 | //! DATE: 2021-05-04, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] 5 | //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 6 | 7 | // Executed Command: 8 | // /Users/xiliangchen/projects/acala/target/release/acala 9 | // benchmark 10 | // --chain=dev 11 | // --steps=50 12 | // --repeat=20 13 | // --pallet=orml_vesting 14 | // --extrinsic=* 15 | // --execution=wasm 16 | // --wasm-execution=compiled 17 | // --heap-pages=4096 18 | // --output=./vesting/src/weights.rs 19 | // --template 20 | // ../templates/orml-weight-template.hbs 21 | 22 | 23 | #![cfg_attr(rustfmt, rustfmt_skip)] 24 | #![allow(unused_parens)] 25 | #![allow(unused_imports)] 26 | #![allow(clippy::unnecessary_cast)] 27 | 28 | use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; 29 | use sp_std::marker::PhantomData; 30 | 31 | /// Weight functions needed for orml_vesting. 32 | pub trait WeightInfo { 33 | fn vested_transfer() -> Weight; 34 | fn claim(i: u32, ) -> Weight; 35 | fn update_vesting_schedules(i: u32, ) -> Weight; 36 | } 37 | 38 | /// Default weights. 39 | impl WeightInfo for () { 40 | fn vested_transfer() -> Weight { 41 | Weight::from_parts(69_000_000, 0) 42 | .saturating_add(RocksDbWeight::get().reads(4 as u64)) 43 | .saturating_add(RocksDbWeight::get().writes(4 as u64)) 44 | } 45 | fn claim(i: u32, ) -> Weight { 46 | Weight::from_parts(31_747_000, 0) 47 | // Standard Error: 4_000 48 | .saturating_add(Weight::from_parts(63_000, 0).saturating_mul(i as u64)) 49 | .saturating_add(RocksDbWeight::get().reads(2 as u64)) 50 | .saturating_add(RocksDbWeight::get().writes(2 as u64)) 51 | } 52 | fn update_vesting_schedules(i: u32, ) -> Weight { 53 | Weight::from_parts(29_457_000, 0) 54 | // Standard Error: 4_000 55 | .saturating_add(Weight::from_parts(117_000, 0).saturating_mul(i as u64)) 56 | .saturating_add(RocksDbWeight::get().reads(2 as u64)) 57 | .saturating_add(RocksDbWeight::get().writes(3 as u64)) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2023-05-16" 3 | components = ["rust-src"] 4 | targets = ["wasm32-unknown-unknown"] 5 | profile = "default" 6 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | ignore = [ 3 | # This is where Substrate sources with custom formatting are, don't touch them 4 | "/orml", 5 | ] 6 | imports_granularity = "Module" 7 | -------------------------------------------------------------------------------- /test/subspace-test-client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "subspace-test-client" 3 | version = "0.1.0" 4 | authors = ["Subspace Labs "] 5 | edition = "2021" 6 | license = "GPL-3.0-or-later" 7 | homepage = "https://subspace.network" 8 | repository = "https://github.com/subspace/subspace" 9 | include = [ 10 | "/src", 11 | "/Cargo.toml", 12 | ] 13 | 14 | [package.metadata.docs.rs] 15 | targets = ["x86_64-unknown-linux-gnu"] 16 | 17 | [dependencies] 18 | futures = "0.3.28" 19 | schnorrkel = "0.9.1" 20 | sc-chain-spec = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 21 | sc-client-api = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 22 | sc-consensus-subspace = { version = "0.1.0", path = "../../crates/sc-consensus-subspace" } 23 | sc-executor = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 24 | sc-service = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } 25 | sp-api = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 26 | sp-consensus-subspace = { version = "0.1.0", path = "../../crates/sp-consensus-subspace" } 27 | sp-core = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 28 | sp-runtime = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } 29 | subspace-archiving = { path = "../../crates/subspace-archiving" } 30 | subspace-core-primitives = { path = "../../crates/subspace-core-primitives" } 31 | subspace-erasure-coding = { path = "../../crates/subspace-erasure-coding" } 32 | subspace-runtime-primitives = { path = "../../crates/subspace-runtime-primitives" } 33 | subspace-farmer-components = { path = "../../crates/subspace-farmer-components" } 34 | subspace-proof-of-space = { path = "../../crates/subspace-proof-of-space" } 35 | subspace-service = { path = "../../crates/subspace-service" } 36 | subspace-solving = { path = "../../crates/subspace-solving" } 37 | subspace-test-runtime = { version = "0.1.0", features = ["do-not-enforce-cost-of-storage"], path = "../subspace-test-runtime" } 38 | subspace-transaction-pool = { version = "0.1.0", path = "../../crates/subspace-transaction-pool" } 39 | zeroize = "1.6.0" 40 | -------------------------------------------------------------------------------- /test/subspace-test-runtime/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 Subspace Labs, Inc. 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | fn main() { 18 | subspace_wasm_tools::create_runtime_bundle_inclusion_file( 19 | "system-domain-test-runtime", 20 | "TEST_DOMAIN_WASM_BUNDLE", 21 | None, 22 | "test_system_domain_wasm_bundle.rs", 23 | ); 24 | 25 | #[cfg(feature = "std")] 26 | { 27 | substrate_wasm_builder::WasmBuilder::new() 28 | .with_current_project() 29 | .export_heap_base() 30 | .import_memory() 31 | .build(); 32 | } 33 | } 34 | --------------------------------------------------------------------------------