├── .changelog ├── config.toml ├── epilogue.md ├── unreleased │ └── .gitkeep ├── v0.2.0-beta.1 │ ├── breaking-changes │ │ ├── 1270-correct-receipts-root.md │ │ ├── 1302-save-genesis-receipts.md │ │ ├── 1316-change-signature-hash-in-interoperation.md │ │ ├── 1319-add-version.md │ │ ├── 1338-merge-rocks-db.md │ │ ├── 1339-remove-header-fields.md │ │ ├── 1382-change-hex-rlp.md │ │ ├── 1454-insert-metadata-directly.md │ │ └── 1471-split-private-key.md │ ├── bug-fixes │ │ ├── 1269-require-cli-sub-command.md │ │ ├── 1281-rename-subscribe-api.md │ │ ├── 1299-modexp-sub-overflow.md │ │ ├── 1303-no-unrwap-or-default.md │ │ ├── 1344-gas-limit-convert.md │ │ ├── 1348-disable-prometheus.md │ │ ├── 1353-fix-genesis-hash.md │ │ ├── 1370-same-trie.md │ │ ├── 1396-deserialize-hex.md │ │ ├── 1400-fix-genesis-generator.md │ │ ├── 1404-return-null-receipt.md │ │ ├── 1431-display-sig-v.md │ │ ├── 1459-cors-accept-any.md │ │ └── 1468-genesis-default-value.md │ ├── code-refactor │ │ ├── 1442-serialize-extra-data.md │ │ ├── 1443-remove-first-tx.md │ │ ├── 1449-remove-metadate-precompile.md │ │ ├── 1450-init-without-genesis-tx.md │ │ └── 1467-remove-secret-key.md │ ├── code-refactors │ │ ├── 1280-thread-local.md │ │ ├── 1285-change-precompile-payload.md │ │ ├── 1309-client-version.md │ │ ├── 1320-constant-values.md │ │ ├── 1326-derive-command-line.md │ │ ├── 1328-change-config.md │ │ ├── 1332-split-config.md │ │ ├── 1333-remove-deprecated-config.md │ │ ├── 1349-all-in-one-run.md │ │ ├── 1351-immutable-chain-id.md │ │ ├── 1355-remove-sol-tests.md │ │ ├── 1363-impl-trie-for-mpttrie.md │ │ ├── 1367-security-secret-key.md │ │ ├── 1371-change-inner-hex.md │ │ └── 1405-error-display.md │ ├── documents │ │ ├── 1364-quick-start.md │ │ ├── 1369-fix-typos.md │ │ ├── 1379-meaning-genesis-transactions.md │ │ ├── 1430-update-getting-start.md │ │ └── 1434-update-doc-chain-id.md │ ├── features │ │ ├── 1278-check-genesis.md │ │ ├── 1340-decode-eip-55.md │ │ ├── 1380-hardfork-storage.md │ │ ├── 1386-split-run.md │ │ ├── 1389-batch-insert-sync.md │ │ ├── 1402-integrate-genesis-generator.md │ │ ├── 1404-hardfork-proposal.md │ │ ├── 1422-cmd-set-hardfork.md │ │ └── 1451-first-hardfork.md │ ├── performance-improvements │ │ └── 1300-reduce-modexp-mem.md │ └── summary.md └── v0.2.0-beta.2 │ ├── bug-fixes │ ├── 1476-encode-config.md │ ├── 1483-get-metadata.md │ ├── 1484-init-evm-config.md │ └── 1485-encode-proposal.md │ ├── code-refactors │ ├── 1481-no-plain-pk.md │ ├── 1482-remove-hex-default.md │ └── 1486-receipts-root.md │ ├── documents │ └── 1479-hardfork-api-doc.md │ └── summary.md ├── .dockerignore ├── .editorconfig ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── feature.yml │ ├── help.yml │ └── others.yml ├── PULL_REQUEST_TEMPLATE.md ├── config │ └── _labeler.yml ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── axon-start-test.yml │ ├── axon-sync-test.yml │ ├── build_image.yml │ ├── build_image_ghcr.yml │ ├── clippy.yml │ ├── copy_config_to_devops.yml │ ├── coverage.yml │ ├── e2e_test.yml │ ├── entry_workflow.yml │ ├── fmt.yml │ ├── generate_changlog_file.yml │ ├── hardfork_test.yml │ ├── issue_comments.yml │ ├── openzeppelin_test_11.yml │ ├── openzeppelin_test_16_19.yml │ ├── openzeppelin_test_1_5_and_12_15.yml │ ├── openzeppelin_test_6_10.yml │ ├── pr_lint.yml │ ├── regression_testing.yml │ ├── release-drafter.yml │ ├── release.yml │ ├── remove_ci_caches.yml │ ├── unit_test.yml │ ├── v3_core_test.yml │ └── web3_compatible.yml ├── .gitignore ├── CHANGELOG.md ├── CHANGELOG_OLD.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── SECURITY.md ├── build.rs ├── builtin-contract ├── crosschain │ ├── .gitignore │ ├── contracts │ │ ├── Metadata.sol │ │ ├── MirrorToken.sol │ │ ├── TestToken.sol │ │ ├── crosschain.sol │ │ └── libraries │ │ │ └── DataType.sol │ ├── hardhat.config.js │ ├── package.json │ ├── scripts │ │ ├── crosschain.deploy.js │ │ ├── crosschain.proxy.js │ │ ├── wckb.deploy.js │ │ └── wckb.grant_role.js │ ├── test │ │ ├── crosschain.js │ │ └── mirror_token.js │ └── yarn.lock └── system-contract │ ├── .gitignore │ ├── README.md │ ├── contracts │ ├── ckb_light_client │ │ └── CkbLightClient.sol │ ├── image_cell │ │ └── ImageCell.sol │ ├── libraries │ │ └── CkbType.sol │ └── metadata │ │ └── Metadata.sol │ ├── hardhat.config.js │ ├── package.json │ ├── test │ └── image-cell.js │ └── yarn.lock ├── clippy.toml ├── codecov.yml ├── common ├── apm-derive │ ├── Cargo.toml │ ├── examples │ │ ├── api.rs │ │ └── trace.rs │ └── src │ │ ├── kv_parser.rs │ │ ├── lib.rs │ │ ├── rpc_expand.rs │ │ └── trace_expand.rs ├── apm │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── lib.rs │ │ ├── metrics.rs │ │ ├── metrics │ │ ├── api.rs │ │ ├── consensus.rs │ │ ├── mem_tracker.rs │ │ ├── mempool.rs │ │ ├── network.rs │ │ └── storage.rs │ │ ├── server.rs │ │ └── tracing.rs ├── config-parser │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── types │ │ ├── config.rs │ │ ├── mod.rs │ │ └── spec.rs ├── crypto │ ├── Cargo.toml │ ├── benches │ │ └── bench_sig.rs │ └── src │ │ └── lib.rs ├── hasher │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── logger │ ├── Cargo.toml │ ├── README.md │ ├── log.yml │ └── src │ │ ├── date_fixed_roller.rs │ │ └── lib.rs ├── memory-tracker │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── merkle │ ├── Cargo.toml │ ├── benches │ │ └── bench.rs │ └── src │ │ └── lib.rs └── version │ ├── Cargo.toml │ └── src │ └── lib.rs ├── core ├── api │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── adapter.rs │ │ ├── graphql │ │ └── mod.rs │ │ ├── jsonrpc │ │ ├── error.rs │ │ ├── impl │ │ │ ├── axon.rs │ │ │ ├── ckb_light_client.rs │ │ │ ├── filter.rs │ │ │ ├── mod.rs │ │ │ ├── node.rs │ │ │ └── web3.rs │ │ ├── mod.rs │ │ ├── web3_types.rs │ │ └── ws_subscription.rs │ │ └── lib.rs ├── cli │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── args │ │ ├── generate_keypair.rs │ │ ├── hardfork.rs │ │ ├── init.rs │ │ ├── mod.rs │ │ ├── recover_keypair.rs │ │ └── run.rs │ │ ├── error.rs │ │ ├── lib.rs │ │ └── utils.rs ├── consensus │ ├── Cargo.toml │ ├── benches │ │ └── bench_wal.rs │ └── src │ │ ├── adapter.rs │ │ ├── consensus.rs │ │ ├── engine.rs │ │ ├── lib.rs │ │ ├── message.rs │ │ ├── status.rs │ │ ├── stop_signal.rs │ │ ├── synchronization.rs │ │ ├── tests │ │ ├── engine.rs │ │ ├── mod.rs │ │ └── synchronization.rs │ │ ├── types.rs │ │ ├── util.rs │ │ └── wal.rs ├── db │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── memory.rs │ │ └── rocks.rs ├── executor │ ├── Cargo.toml │ ├── benches │ │ ├── bench_convert_u256.rs │ │ ├── bench_transfer.rs │ │ ├── bench_vm.rs │ │ ├── mock.rs │ │ └── revm_adapter.rs │ ├── res │ │ ├── erc20.abi │ │ ├── erc20_code.txt │ │ ├── factory.abi │ │ ├── factory_code.txt │ │ ├── router.abi │ │ ├── router_code.txt │ │ ├── weth.abi │ │ └── weth_code.txt │ └── src │ │ ├── adapter │ │ ├── backend │ │ │ ├── apply.rs │ │ │ ├── mod.rs │ │ │ └── read_only.rs │ │ ├── mod.rs │ │ └── trie │ │ │ ├── db.rs │ │ │ ├── mod.rs │ │ │ └── wrapped.rs │ │ ├── debugger │ │ ├── create2.rs │ │ ├── mod.rs │ │ └── uniswap2.rs │ │ ├── lib.rs │ │ ├── precompiles │ │ ├── blake2_f.rs │ │ ├── call_ckb_vm.rs │ │ ├── ckb_blake2b.rs │ │ ├── ckb_mbt_verify.rs │ │ ├── ec_add.rs │ │ ├── ec_mul.rs │ │ ├── ec_pairing.rs │ │ ├── ecrecover.rs │ │ ├── get_cell.rs │ │ ├── get_header.rs │ │ ├── identity.rs │ │ ├── mod.rs │ │ ├── modexp.rs │ │ ├── ripemd160.rs │ │ ├── rsa.rs │ │ ├── secp256r1.rs │ │ ├── sha256.rs │ │ └── tests.rs │ │ ├── system_contract │ │ ├── ckb_light_client │ │ │ ├── abi │ │ │ │ ├── ckb_light_client_abi.json │ │ │ │ ├── ckb_light_client_abi.rs │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ └── store.rs │ │ ├── error.rs │ │ ├── image_cell │ │ │ ├── abi │ │ │ │ ├── README.md │ │ │ │ ├── image_cell_abi.json │ │ │ │ ├── image_cell_abi.rs │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ └── store.rs │ │ ├── metadata │ │ │ ├── abi │ │ │ │ ├── metadata_abi.json │ │ │ │ ├── metadata_abi.rs │ │ │ │ └── mod.rs │ │ │ ├── handle.rs │ │ │ ├── mod.rs │ │ │ ├── segment.rs │ │ │ └── store.rs │ │ ├── mod.rs │ │ ├── native_token.rs │ │ └── utils.rs │ │ ├── tests │ │ ├── mod.rs │ │ └── system_script │ │ │ ├── ckb_lc_and_ic.rs │ │ │ ├── ckb_light_client.rs │ │ │ ├── image_cell.rs │ │ │ ├── metadata.rs │ │ │ ├── mod.rs │ │ │ └── native_token.rs │ │ └── utils.rs ├── interoperation │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── mempool │ ├── Cargo.toml │ ├── benches │ │ ├── bench.rs │ │ └── mock.rs │ └── src │ │ ├── adapter │ │ ├── message.rs │ │ └── mod.rs │ │ ├── context.rs │ │ ├── lib.rs │ │ ├── pool.rs │ │ ├── tests │ │ ├── mempool.rs │ │ └── mod.rs │ │ └── tx_wrapper.rs ├── network │ ├── Cargo.toml │ ├── examples │ │ └── simple.rs │ └── src │ │ ├── common.rs │ │ ├── compress.rs │ │ ├── config.rs │ │ ├── endpoint.rs │ │ ├── error.rs │ │ ├── lib.rs │ │ ├── message │ │ └── mod.rs │ │ ├── outbound │ │ ├── gossip.rs │ │ ├── mod.rs │ │ └── rpc.rs │ │ ├── peer_manager │ │ ├── mod.rs │ │ ├── peer_store │ │ │ ├── addr_manager.rs │ │ │ ├── ban_list.rs │ │ │ ├── mod.rs │ │ │ ├── peer_store_db.rs │ │ │ ├── peer_store_impl.rs │ │ │ └── types.rs │ │ └── registry.rs │ │ ├── protocols │ │ ├── discovery │ │ │ ├── addr.rs │ │ │ ├── mod.rs │ │ │ ├── proto.rs │ │ │ └── state.rs │ │ ├── feeler.rs │ │ ├── identify │ │ │ ├── mod.rs │ │ │ └── protocol.rs │ │ ├── mod.rs │ │ ├── ping.rs │ │ └── transmitter │ │ │ ├── mod.rs │ │ │ └── protocol.rs │ │ ├── reactor │ │ ├── mod.rs │ │ ├── router.rs │ │ └── rpc_map.rs │ │ ├── rpc.rs │ │ ├── service.rs │ │ └── traits.rs ├── rpc-client │ ├── Cargo.toml │ └── src │ │ ├── client.rs │ │ └── lib.rs ├── run │ ├── Cargo.toml │ └── src │ │ ├── components │ │ ├── chain_spec.rs │ │ ├── extensions.rs │ │ ├── mod.rs │ │ ├── network.rs │ │ ├── profiling.rs │ │ ├── storage.rs │ │ └── system.rs │ │ ├── error.rs │ │ ├── key_provider.rs │ │ ├── lib.rs │ │ └── tests.rs └── storage │ ├── Cargo.toml │ ├── benches │ └── bench.rs │ └── src │ ├── cache.rs │ ├── hash_key.rs │ ├── lib.rs │ ├── schema.rs │ └── tests │ ├── adapter.rs │ ├── mod.rs │ └── storage.rs ├── devtools ├── abi-generator │ ├── Cargo.toml │ ├── abi_generate.py │ └── src │ │ └── main.rs ├── axon-tools │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── consts.rs │ │ ├── error.rs │ │ ├── hash.rs │ │ ├── hex.rs │ │ ├── lib.rs │ │ ├── precompile.rs │ │ ├── proof.rs │ │ ├── rlp_codec.rs │ │ ├── tests │ │ ├── block.json │ │ ├── metadata.json │ │ ├── mod.rs │ │ ├── proof.json │ │ ├── verify_proof.rs │ │ └── verify_trie_proof.rs │ │ └── types.rs ├── chain │ ├── blockscan-explorer.env │ ├── blockscan-screenshot.png │ ├── bls.key │ ├── config.toml │ ├── default.db-options │ ├── docker-compose.yml │ ├── k8s │ │ ├── node_1.toml │ │ ├── node_1_bls.key │ │ ├── node_1_net.key │ │ ├── node_2.toml │ │ ├── node_2_bls.key │ │ ├── node_2_net.key │ │ ├── node_3.toml │ │ ├── node_3_bls.key │ │ ├── node_3_net.key │ │ ├── node_4.toml │ │ ├── node_4_bls.key │ │ └── node_4_net.key │ ├── net.key │ ├── nodes │ │ ├── default.db-options │ │ ├── node_1.toml │ │ ├── node_1_bls.key │ │ ├── node_1_net.key │ │ ├── node_2.toml │ │ ├── node_2_bls.key │ │ ├── node_2_net.key │ │ ├── node_3.toml │ │ ├── node_3_bls.key │ │ ├── node_3_net.key │ │ ├── node_4.toml │ │ ├── node_4_bls.key │ │ └── node_4_net.key │ ├── quick-start.md │ └── specs │ │ ├── alphanet_nodes │ │ └── chain-spec.toml │ │ ├── multi_nodes │ │ └── chain-spec.toml │ │ ├── multi_nodes_short_epoch_len │ │ └── chain-spec.toml │ │ └── single_node │ │ └── chain-spec.toml ├── ci │ ├── ansible │ │ ├── ansible.cfg │ │ └── playbook.yml │ ├── build-arm64.sh │ ├── scripts │ │ └── helper.js │ └── terraform │ │ ├── .gitignore │ │ ├── .terraform.lock.hcl │ │ ├── README.md │ │ ├── ami.tf │ │ ├── main.tf │ │ ├── variables.tf │ │ └── versions.tf ├── docker │ ├── docker-entrypoint.sh │ └── health_check.sh └── metadata-cli │ ├── Cargo.toml │ ├── README.md │ ├── data.example.hex │ ├── input.example.json │ ├── input.example.toml │ └── src │ ├── main.rs │ └── serde_helpers.rs ├── docs └── assets │ └── logo │ └── axon-01.png ├── examples ├── custom_chain.rs └── solidity │ ├── CallCkbVm.sol │ ├── GetCell.sol │ ├── GetHeader.sol │ ├── Types.sol │ └── VerifyByCKb.sol ├── protocol ├── Cargo.toml └── src │ ├── codec │ ├── block.rs │ ├── error.rs │ ├── executor.rs │ ├── mod.rs │ ├── receipt.rs │ └── transaction.rs │ ├── constants │ ├── configs.rs │ ├── endpoints.rs │ └── mod.rs │ ├── lazy.rs │ ├── lib.rs │ ├── traits │ ├── api.rs │ ├── ckb_client.rs │ ├── consensus.rs │ ├── executor.rs │ ├── interoperation.rs │ ├── mempool.rs │ ├── mod.rs │ ├── network.rs │ └── storage.rs │ └── types │ ├── batch.rs │ ├── block.rs │ ├── ckb_client.rs │ ├── executor.rs │ ├── interoperation.rs │ ├── mod.rs │ ├── primitive.rs │ ├── receipt.rs │ └── transaction.rs ├── rust-toolchain ├── rustfmt.toml ├── src ├── lib.rs └── main.rs └── tests └── e2e ├── .babelrc ├── .eslintrc.js ├── CONTRIBUTING.md ├── CONTRIBUTING_en-Hans.md ├── config.js ├── config.json ├── jest ├── dappeteer_environment.js └── setup.js ├── package.json ├── src ├── create_test_data │ ├── ERC20.json │ └── createTestDataManage.js ├── eth_blockNumber.html ├── eth_blockNumber.test.js ├── eth_call.html ├── eth_call.test.js ├── eth_coinBase.html ├── eth_coinBase.test.js ├── eth_estimateGas.html ├── eth_estimateGas.test.js ├── eth_feeHistory.html ├── eth_feeHistory.test.js ├── eth_gasPrice.html ├── eth_gasPrice.test.js ├── eth_getBalance.html ├── eth_getBalance.test.js ├── eth_getBlockByHash.html ├── eth_getBlockByHash.test.js ├── eth_getBlockByNumber.html ├── eth_getBlockByNumber.test.js ├── eth_getBlockTransactionCountByHash.html ├── eth_getBlockTransactionCountByHash.test.js ├── eth_getBlockTransactionCountByNumber.html ├── eth_getBlockTransactionCountByNumber.test.js ├── eth_getCode.html ├── eth_getCode.test.js ├── eth_getFilterChange.test.js ├── eth_getFilterChanges.html ├── eth_getLogs.html ├── eth_getLogs.test.js ├── eth_getStorageAt.html ├── eth_getStorageAt.test.js ├── eth_getTransactionByBlockHashAndIndex.html ├── eth_getTransactionByBlockHashAndIndex.test.js ├── eth_getTransactionByBlockNumberAndIndex.html ├── eth_getTransactionByBlockNumberAndIndex.test.js ├── eth_getTransactionByHash.html ├── eth_getTransactionByHash.test.js ├── eth_getTransactionCount.html ├── eth_getTransactionCount.test.js ├── eth_getTransactionReceipt.html ├── eth_getTransactionReceipt.test.js ├── eth_hasHrate.html ├── eth_hasHrate.test.js ├── eth_mining.html ├── eth_mining.test.js ├── eth_newBlockFilter.html ├── eth_newBlockFilter.test.js ├── eth_newFilter.html ├── eth_newFilter.test.js ├── eth_newPendingTransactionFilter.html ├── eth_newPendingTransactionFilter.test.js ├── eth_sendRawTransaction.html ├── eth_sendRawTransaction.test.js ├── eth_submitHashrate.html ├── eth_submitHashrate.test.js ├── eth_submitWork.html ├── eth_submitWork.test.js ├── eth_subscribe.html ├── eth_subscribe.test.js ├── eth_syncing.html ├── eth_syncing.test.js ├── eth_uninstallFilter.html ├── eth_uninstallFilter.test.js ├── goto.js ├── net_listening.html ├── net_listening.test.js ├── net_peerCount.html ├── net_peerCount.test.js ├── net_version.html ├── net_version.test.js ├── web3_clientVersion.html ├── web3_clientVersion.test.js ├── web3_sha3.html └── web3_sha3.test.js └── yarn.lock /.changelog/config.toml: -------------------------------------------------------------------------------- 1 | project_url = "https://github.com/axonweb3/axon" 2 | -------------------------------------------------------------------------------- /.changelog/epilogue.md: -------------------------------------------------------------------------------- 1 | Changelogs before 0.2.0 can be found [here](./CHANGELOG_OLD.md). 2 | -------------------------------------------------------------------------------- /.changelog/unreleased/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/.changelog/unreleased/.gitkeep -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1270-correct-receipts-root.md: -------------------------------------------------------------------------------- 1 | - Make the calculation of `receipts_root` correct 2 | ([\#1270](https://github.com/axonweb3/axon/pull/1270)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1302-save-genesis-receipts.md: -------------------------------------------------------------------------------- 1 | - Save the receipts of genesis 2 | ([\#1302](https://github.com/axonweb3/axon/pull/1302)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1316-change-signature-hash-in-interoperation.md: -------------------------------------------------------------------------------- 1 | - Change the position of signature has in interoperation verification 2 | ([\#1316](https://github.com/axonweb3/axon/pull/1316)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1319-add-version.md: -------------------------------------------------------------------------------- 1 | - Add `version` field to block header and proposal 2 | ([\#1319](https://github.com/axonweb3/axon/pull/1319)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1338-merge-rocks-db.md: -------------------------------------------------------------------------------- 1 | - Read-write separation and merge RocksDB instance 2 | ([\#1338](https://github.com/axonweb3/axon/pull/1338)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1339-remove-header-fields.md: -------------------------------------------------------------------------------- 1 | - Remove useless fields in `Header` 2 | ([\#1339](https://github.com/axonweb3/axon/pull/1339)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1382-change-hex-rlp.md: -------------------------------------------------------------------------------- 1 | - Change the rlp codec of `Hex` ([\#1382](https://github.com/axonweb3/axon/pull/1382)) 2 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1454-insert-metadata-directly.md: -------------------------------------------------------------------------------- 1 | - Insert metadata directly when initialize chain 2 | ([\#1454](https://github.com/axonweb3/axon/pull/1454)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/breaking-changes/1471-split-private-key.md: -------------------------------------------------------------------------------- 1 | - Split bls and secp256k1 private key 2 | ([\#1471](https://github.com/axonweb3/axon/pull/1471)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1269-require-cli-sub-command.md: -------------------------------------------------------------------------------- 1 | - Always require CLI sub-command 2 | ([\#1269](https://github.com/axonweb3/axon/pull/1269)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1281-rename-subscribe-api.md: -------------------------------------------------------------------------------- 1 | - Fix `eth_subscribe` method name ([\#1281](https://github.com/axonweb3/axon/pull/1281)) 2 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1299-modexp-sub-overflow.md: -------------------------------------------------------------------------------- 1 | - `modexp` precompile contract may overflow 2 | ([\#1299](https://github.com/axonweb3/axon/pull/1299)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1303-no-unrwap-or-default.md: -------------------------------------------------------------------------------- 1 | - No default values when unexpected errors occurred 2 | ([\#1303](https://github.com/axonweb3/axon/pull/1303)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1344-gas-limit-convert.md: -------------------------------------------------------------------------------- 1 | - Gas limit conversion error 2 | ([\#1344](https://github.com/axonweb3/axon/pull/1344)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1348-disable-prometheus.md: -------------------------------------------------------------------------------- 1 | - Prometheus can not be disabled 2 | ([\#1348](https://github.com/axonweb3/axon/pull/1348)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1353-fix-genesis-hash.md: -------------------------------------------------------------------------------- 1 | - Make genesis hash correct 2 | ([\#1353](https://github.com/axonweb3/axon/pull/1353)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1370-same-trie.md: -------------------------------------------------------------------------------- 1 | - Use a same trie for the same chain 2 | ([\#1370](https://github.com/axonweb3/axon/pull/1370)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1396-deserialize-hex.md: -------------------------------------------------------------------------------- 1 | - The deserialize of ([\#1396](https://github.com/axonweb3/axon/pull/1396)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1400-fix-genesis-generator.md: -------------------------------------------------------------------------------- 1 | - `genesis-generator` is nondeterministic ([\#1400](https://github.com/axonweb3/axon/pull/1400)) 2 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1404-return-null-receipt.md: -------------------------------------------------------------------------------- 1 | - Return RPC `null` when no receipt was found 2 | ([\#1404](https://github.com/axonweb3/axon/pull/1404)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1431-display-sig-v.md: -------------------------------------------------------------------------------- 1 | - Fix display of signature v in transaction 2 | ([\#1431](https://github.com/axonweb3/axon/pull/1431)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1459-cors-accept-any.md: -------------------------------------------------------------------------------- 1 | - Set CORS to any to accept RPC alls from web-based apps 2 | ([\#1459](https://github.com/axonweb3/axon/pull/1459)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/bug-fixes/1468-genesis-default-value.md: -------------------------------------------------------------------------------- 1 | - Default values of genesis fields should be same as normal blocks 2 | ([\#1468](https://github.com/axonweb3/axon/pull/1468)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactor/1442-serialize-extra-data.md: -------------------------------------------------------------------------------- 1 | - Change serialization for block header `extra_data` 2 | ([\#1442](https://github.com/axonweb3/axon/pull/1442)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactor/1443-remove-first-tx.md: -------------------------------------------------------------------------------- 1 | - Remove first transaction in genesis 2 | ([\#1443](https://github.com/axonweb3/axon/pull/1443) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactor/1449-remove-metadate-precompile.md: -------------------------------------------------------------------------------- 1 | - Remove metadata precompile contract 2 | ([\#1449](https://github.com/axonweb3/axon/pull/1449)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactor/1450-init-without-genesis-tx.md: -------------------------------------------------------------------------------- 1 | - Initialize chain without genesis transaction file 2 | ([\#1450](https://github.com/axonweb3/axon/pull/1450)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactor/1467-remove-secret-key.md: -------------------------------------------------------------------------------- 1 | - Initialize chain without any secret key 2 | ([\#1467](https://github.com/axonweb3/axon/pull/1467)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1280-thread-local.md: -------------------------------------------------------------------------------- 1 | - Use thread local instead of global variable 2 | ([\#1280](https://github.com/axonweb3/axon/pull/1280)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1285-change-precompile-payload.md: -------------------------------------------------------------------------------- 1 | - Change the `call_ckb_vm` and `verify_by_ckb` precompile argument payload 2 | ([\#1285](https://github.com/axonweb3/axon/pull/1285)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1309-client-version.md: -------------------------------------------------------------------------------- 1 | - Get client version from crate version and git commit ID 2 | ([\#1309](https://github.com/axonweb3/axon/pull/1309)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1320-constant-values.md: -------------------------------------------------------------------------------- 1 | - Use constant values as default values 2 | ([\#1320](https://github.com/axonweb3/axon/pull/1320)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1326-derive-command-line.md: -------------------------------------------------------------------------------- 1 | - Use derive procedural macro to parse command line arguments 2 | ([\#1326](https://github.com/axonweb3/axon/pull/1326)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1328-change-config.md: -------------------------------------------------------------------------------- 1 | - Change config to single struct 2 | ([\#1328](https://github.com/axonweb3/axon/pull/1328)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1332-split-config.md: -------------------------------------------------------------------------------- 1 | - Split config and genesis to client config and chain spec 2 | ([\#1332](https://github.com/axonweb3/axon/pull/1332)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1333-remove-deprecated-config.md: -------------------------------------------------------------------------------- 1 | - Remove deprecated config ([\#1333](https://github.com/axonweb3/axon/pull/1333)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1349-all-in-one-run.md: -------------------------------------------------------------------------------- 1 | - Split the all-in-one file of `core-run` 2 | ([\#1349](https://github.com/axonweb3/axon/pull/1349)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1351-immutable-chain-id.md: -------------------------------------------------------------------------------- 1 | - Make chain id immutable ([\#1351](https://github.com/axonweb3/axon/pull/1351)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1355-remove-sol-tests.md: -------------------------------------------------------------------------------- 1 | - Remove useless tests of solidity contract 2 | ([\#1355](https://github.com/axonweb3/axon/pull/1355)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1363-impl-trie-for-mpttrie.md: -------------------------------------------------------------------------------- 1 | - Implement `Trie` for `MPTTrie` ([\#1363](https://github.com/axonweb3/axon/pull/1363)) 2 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1367-security-secret-key.md: -------------------------------------------------------------------------------- 1 | - Slightly improve security for secret keys 2 | ([\#1367](https://github.com/axonweb3/axon/pull/1367)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1371-change-inner-hex.md: -------------------------------------------------------------------------------- 1 | - Change the memory layout of `Hex` 2 | ([\#1371](https://github.com/axonweb3/axon/pull/1371)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/code-refactors/1405-error-display.md: -------------------------------------------------------------------------------- 1 | - Make error message display better 2 | ([\#1405](https://github.com/axonweb3/axon/pull/1405)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/documents/1364-quick-start.md: -------------------------------------------------------------------------------- 1 | - Add quick start and blocksacn usage 2 | ([\#1364](https://github.com/axonweb3/axon/pull/1364)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/documents/1369-fix-typos.md: -------------------------------------------------------------------------------- 1 | - Fix some typos ([\#1369](https://github.com/axonweb3/axon/pull/1369)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/documents/1379-meaning-genesis-transactions.md: -------------------------------------------------------------------------------- 1 | - Update the meaning of genesis transactions 2 | ([\#1379](https://github.com/axonweb3/axon/pull/1379)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/documents/1430-update-getting-start.md: -------------------------------------------------------------------------------- 1 | - Update `Getting Started` section in README.md 2 | ([\#1430](https://github.com/axonweb3/axon/pull/1430)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/documents/1434-update-doc-chain-id.md: -------------------------------------------------------------------------------- 1 | - Update default dev chain ID 2 | ([\#1434](https://github.com/axonweb3/axon/pull/1434)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1278-check-genesis.md: -------------------------------------------------------------------------------- 1 | - Check provided genesis if not first run 2 | ([\#1278](https://github.com/axonweb3/axon/pull/1278)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1340-decode-eip-55.md: -------------------------------------------------------------------------------- 1 | - Decode addresses with EIP-55 2 | ([\#1340](https://github.com/axonweb3/axon/pull/1340)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1380-hardfork-storage.md: -------------------------------------------------------------------------------- 1 | - Add hardfork storage to metadata system contract 2 | ([\#1380](https://github.com/axonweb3/axon/pull/1380)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1386-split-run.md: -------------------------------------------------------------------------------- 1 | - Split `run` command to `init` and `run` 2 | ([\#1386](https://github.com/axonweb3/axon/pull/1386)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1389-batch-insert-sync.md: -------------------------------------------------------------------------------- 1 | - Storage batch insert data with sync 2 | ([\#1389](https://github.com/axonweb3/axon/pull/1389)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1402-integrate-genesis-generator.md: -------------------------------------------------------------------------------- 1 | - Integrate genesis-generator into axon `init` command 2 | ([\#1402](https://github.com/axonweb3/axon/pull/1402)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1404-hardfork-proposal.md: -------------------------------------------------------------------------------- 1 | - Add hardfork proposal process 2 | ([\#1404](https://github.com/axonweb3/axon/pull/1404)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1422-cmd-set-hardfork.md: -------------------------------------------------------------------------------- 1 | - Support set hardfork in command line 2 | ([\#1422](https://github.com/axonweb3/axon/pull/1422)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/features/1451-first-hardfork.md: -------------------------------------------------------------------------------- 1 | - First hardfork with contract size limit 2 | ([\#1451](https://github.com/axonweb3/axon/pull/1451)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/performance-improvements/1300-reduce-modexp-mem.md: -------------------------------------------------------------------------------- 1 | - Reduce memory cost in `modexp` precompile contract 2 | ([\#1300](https://github.com/axonweb3/axon/pull/1300)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.1/summary.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | Release 0.2.0-beta.1 version. 8 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/bug-fixes/1476-encode-config.md: -------------------------------------------------------------------------------- 1 | - Fix the encode `ConsensusConfig` function 2 | ([\#1476](https://github.com/axonweb3/axon/pull/1476)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/bug-fixes/1483-get-metadata.md: -------------------------------------------------------------------------------- 1 | - Fix get metadata by block number 2 | ([\#1483](https://github.com/axonweb3/axon/pull/1483)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/bug-fixes/1484-init-evm-config.md: -------------------------------------------------------------------------------- 1 | - Fix init EVM config ([\#1484](https://github.com/axonweb3/axon/pull/1484)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/bug-fixes/1485-encode-proposal.md: -------------------------------------------------------------------------------- 1 | - Fix encode and decode of `Proposal` struct 2 | ([\#1485](https://github.com/axonweb3/axon/pull/1485)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/code-refactors/1481-no-plain-pk.md: -------------------------------------------------------------------------------- 1 | - No plain-text private key in configuration file 2 | ([\#1481](https://github.com/axonweb3/axon/pull/1481)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/code-refactors/1482-remove-hex-default.md: -------------------------------------------------------------------------------- 1 | - Remove default value of `Hex` 2 | ([\#1482](https://github.com/axonweb3/axon/pull/1482)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/code-refactors/1486-receipts-root.md: -------------------------------------------------------------------------------- 1 | - Change the calculation of receipts root to [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) 2 | ([\#1486](https://github.com/axonweb3/axon/pull/1486)) 3 | -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/documents/1479-hardfork-api-doc.md: -------------------------------------------------------------------------------- 1 | - Add hardfork related APIs document 2 | ([\#1479](https://github.com/axonweb3/axon/pull/1479)) -------------------------------------------------------------------------------- /.changelog/v0.2.0-beta.2/summary.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | This release contains some important bugfixes from the previous 0.2.0-beta.1 version. 8 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | logs 3 | devtools/chain/data 4 | 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | indent_style = space 13 | indent_size = 4 14 | 15 | [*.md] 16 | # double whitespace at end of line 17 | # denotes a line break in Markdown 18 | trim_trailing_whitespace = false 19 | 20 | [*.yml] 21 | indent_size = 2 22 | 23 | [*.json] 24 | indent_size = 2 25 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @axonweb3/axon-dev -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest a feature to the Mercury project 3 | labels: ["t:feature"] 4 | 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this feature! 10 | - type: input 11 | id: contact 12 | attributes: 13 | label: Contact Details 14 | description: How can we get in touch with you if we need more info? 15 | placeholder: ex. email@example.com 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: what-added 20 | attributes: 21 | label: Propose-a-new-feature 22 | description: Describe the solution you'd like(Is your feature request related to a problem?). 23 | placeholder: Tell us what you want! 24 | value: "Describe the solution you'd like:" 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: the-alternatives 29 | attributes: 30 | label: Alternatives you've considered 31 | description: Also tell us, any alternative solutions or features you've considered? 32 | placeholder: Tell us the alternatives you've considered! 33 | value: "Describe alternatives you've considered:" 34 | validations: 35 | required: false 36 | - type: textarea 37 | attributes: 38 | label: Anything else? 39 | description: | 40 | Links? References? Anything that will give us more context about the issue you are encountering! 41 | 42 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 43 | validations: 44 | required: false 45 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/help.yml: -------------------------------------------------------------------------------- 1 | name: Help me 2 | description: What kind of help do you want? 3 | labels: ["t:help"] 4 | 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | What kind of help do you want? 10 | - type: input 11 | id: contact 12 | attributes: 13 | label: Contact Details 14 | description: How can we get in touch with you if we need more info? 15 | placeholder: ex. email@example.com 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: what-happend 20 | attributes: 21 | label: What happened 22 | description: What kind of help do you want? 23 | placeholder: What kind of help do you want? 24 | value: "Describe the problem details:" 25 | validations: 26 | required: true 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/others.yml: -------------------------------------------------------------------------------- 1 | name: Others 2 | description: File out a others that you met 3 | labels: ["t:others"] 4 | 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this issue! 10 | - type: input 11 | id: contact 12 | attributes: 13 | label: Contact Details 14 | description: How can we get in touch with you if we need more info? 15 | placeholder: ex. email@example.com 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: what-happend 20 | attributes: 21 | label: What happened 22 | description: Tell us what happened, or what you want. 23 | placeholder: Tell us what problem that you met! 24 | value: "Describe the problem details:" 25 | validations: 26 | required: true 27 | 28 | 29 | -------------------------------------------------------------------------------- /.github/config/_labeler.yml: -------------------------------------------------------------------------------- 1 | underlying: 2 | - any: ['core/consensus/src/*', 'core/mempool/src/*', 'core/executor/src/*', 'core/network/src/*', 'core/storage/src/*'] 3 | 4 | API: 5 | - core/api/src/* 6 | 7 | interoperation: 8 | - core/interoperation/src/* 9 | 10 | crosschain: 11 | - any: ['core/cross-client/src/*', 'core/tx-assembler/src/*'] 12 | 13 | devtools: 14 | - devtools/* 15 | 16 | documents: 17 | - any: ['docs/*', README.md, CHANGELOG.md] 18 | 19 | e2e: 20 | - tests/e2e/src/* 21 | 22 | contract: 23 | - builtin-contract/* 24 | 25 | protocol: 26 | - protocol/src/* 27 | 28 | toolchain: 29 | - rust-toolchain 30 | 31 | ci: 32 | - any: ['.github/actions/*', '.github/workflows/*'] 33 | 34 | apm: 35 | - any: ['common/apm/src/*', 'common/apm-derive/src/*', 'common/memory-tracker/src/*'] 36 | 37 | config: 38 | - any: ['common/config-parser/src/*'] 39 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: cargo 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | time: "03:00" 13 | timezone: Asia/Shanghai 14 | ignore: 15 | - dependency-name: creep 16 | - dependency-name: rand 17 | 18 | - package-ecosystem: "github-actions" 19 | directory: "/" 20 | schedule: 21 | interval: daily 22 | time: "03:00" 23 | timezone: Asia/Shanghai 24 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$RESOLVED_VERSION-alpha.1' 2 | tag-template: 'v$RESOLVED_VERSION-alpha.1' 3 | template: | 4 | # What's Changed 5 | 6 | $CHANGES 7 | 8 | **Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION 9 | categories: 10 | - title: '🚀 Features' 11 | label: 'feature' 12 | - title: '🔥 Enhancement' 13 | label: 'enhancement' 14 | - title: '🐛 Bug Fixes' 15 | label: 'bugfix' 16 | - title: '🐝 refactor' 17 | label: 'refactor' 18 | - title: '🧰 Chore' 19 | label: 'chore' 20 | - title: '📖 Documentation' 21 | label: 'document' 22 | - title: '✨ Other changes' 23 | - title: '⬆️ Dependency Updates' 24 | label: 'dependencies' 25 | - title: '🌈 Style' 26 | label: 'style' 27 | 28 | version-resolver: 29 | minor: 30 | labels: 31 | - 'feature' 32 | patch: 33 | labels: 34 | - 'bug' 35 | - 'maintenance' 36 | - 'docs' 37 | - 'dependencies' 38 | - 'security' 39 | 40 | exclude-labels: 41 | - 'skip-changelog' 42 | -------------------------------------------------------------------------------- /.github/workflows/clippy.yml: -------------------------------------------------------------------------------- 1 | name: Cargo Clippy 2 | 3 | on: 4 | push: 5 | pull_request: 6 | merge_group: 7 | 8 | # Ensure that only a single job or workflow using the same concurrency group will run at a time. 9 | # see https://docs.github.com/en/actions/using-jobs/using-concurrency#example-only-cancel-in-progress-jobs-or-runs-for-the-current-workflow 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} 12 | # only needs to check the group's latest commit 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | cargo-clippy: 17 | strategy: 18 | matrix: 19 | # Supported GitHub-hosted runners and hardware resources 20 | # see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources 21 | os: [ubuntu-22.04] 22 | fail-fast: false 23 | runs-on: ${{ matrix.os }} 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - name: Cache of Cargo 29 | uses: actions/cache@v3 30 | with: 31 | path: | 32 | ~/.cargo/bin/ 33 | ~/.cargo/registry/index/ 34 | ~/.cargo/registry/cache/ 35 | ~/.cargo/git/db/ 36 | target/ 37 | key: ${{ matrix.os }}-${{ runner.os }}-${{ runner.arch }}-cargo-clippy-${{ hashFiles('**/Cargo.lock') }} 38 | restore-keys: | 39 | ${{ matrix.os }}-${{ runner.os }}-${{ runner.arch }}-cargo-clippy 40 | ${{ matrix.os }}-${{ runner.os }}-${{ runner.arch }}-cargo 41 | 42 | - name: Install cargo-clippy 43 | run: rustup component add clippy 44 | 45 | - name: Run cargo-clippy in Makefile 46 | run: make clippy && git diff --exit-code Cargo.lock 47 | -------------------------------------------------------------------------------- /.github/workflows/fmt.yml: -------------------------------------------------------------------------------- 1 | name: Code Format 2 | 3 | on: 4 | pull_request: 5 | merge_group: 6 | workflow_dispatch: 7 | 8 | # Ensure that only a single job or workflow using the same concurrency group will run at a time. 9 | # see https://docs.github.com/en/actions/using-jobs/using-concurrency#example-only-cancel-in-progress-jobs-or-runs-for-the-current-workflow 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} 12 | # only needs to check the group's latest commit 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | rustfmt: 17 | strategy: 18 | matrix: 19 | # Supported GitHub-hosted runners and hardware resources 20 | # see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources 21 | os: [ubuntu-22.04] 22 | fail-fast: false 23 | runs-on: ${{ matrix.os }} 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - uses: actions-rs/toolchain@v1 29 | with: 30 | profile: minimal 31 | components: rustfmt 32 | toolchain: nightly 33 | 34 | - name: Cargo +nightly fmt --all -- --check 35 | run: make check-fmt 36 | 37 | - name: Install cargo-sort 38 | run: | 39 | which cargo-sort >/dev/null && echo "cargo-sort is installed" \ 40 | || (echo "cargo-sort is not installed" && cargo install cargo-sort) 41 | 42 | - name: Ensure Cargo.toml dependency tables are sorted 43 | run: make check-sort 44 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | update_release_draft: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: release-drafter/release-drafter@master 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | -------------------------------------------------------------------------------- /.github/workflows/remove_ci_caches.yml: -------------------------------------------------------------------------------- 1 | name: cleanup caches daily 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | # Manurally trigger 6 | workflow_dispatch: 7 | 8 | 9 | jobs: 10 | cleanup: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Check out code 14 | uses: actions/checkout@v4 15 | 16 | - name: Cleanup 17 | run: | 18 | gh extension install actions/gh-actions-cache 19 | 20 | REPO=${{ github.repository }} 21 | BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge" 22 | 23 | echo "Fetching list of cache key" 24 | cacheKeys=$(gh actions-cache list -R $REPO | cut -f 1 ) 25 | 26 | # Setting this to not fail the workflow while deleting cache keys. 27 | set +e 28 | echo "Deleting caches..." 29 | for cacheKey in $cacheKeys 30 | do 31 | gh actions-cache delete $cacheKey -R $REPO --confirm 32 | done 33 | echo "Done" 34 | env: 35 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # These are backup files generated by rustfmt 6 | **/*.rs.bk 7 | 8 | # Added by cargo 9 | # 10 | # already existing elements are commented out 11 | 12 | /target 13 | #**/*.rs.bk 14 | 15 | # OS 16 | .DS_Store 17 | 18 | # IDE 19 | .idea/ 20 | .vscode/ 21 | 22 | # dev 23 | devtools/chain/data 24 | 25 | tests/e2e/node_modules 26 | tests/e2e/yarn-error.log 27 | tests/e2e/src/test_data_temp_file/testData_*.json 28 | 29 | # rocksdb 30 | **/rocksdb/ 31 | logs/ 32 | 33 | # free space, you can store anything you want here 34 | free-space 35 | 36 | byzantine/tests/node_modules 37 | 38 | *.out 39 | 40 | node_modules/* 41 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.72 as builder 2 | 3 | WORKDIR /build 4 | COPY . . 5 | 6 | RUN set -eux; \ 7 | apt-get update; \ 8 | apt-get install -y --no-install-recommends \ 9 | cmake \ 10 | clang \ 11 | llvm \ 12 | gcc; \ 13 | rm -rf /var/lib/apt/lists/* 14 | 15 | RUN cd /build && cargo build --release 16 | 17 | 18 | FROM debian:bookworm-20230612-slim 19 | 20 | RUN apt-get update \ 21 | && apt-get install -y --no-install-recommends curl jq \ 22 | && rm -rf /var/lib/apt/lists/* 23 | 24 | WORKDIR /app 25 | 26 | COPY --from=builder \ 27 | /usr/lib/x86_64-linux-gnu/libssl.so.* \ 28 | /usr/lib/x86_64-linux-gnu/libcrypto.so.* \ 29 | /usr/lib/x86_64-linux-gnu/ 30 | COPY --from=builder /build/target/release/axon /app/axon 31 | COPY --from=builder /build/devtools /app/devtools 32 | 33 | CMD /app/devtools/docker/docker-entrypoint.sh 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Nervos Foundation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | if let Some(commit_id) = std::process::Command::new("git") 3 | .args(["describe", "--always", "--dirty", "--exclude", "*"]) 4 | .output() 5 | .ok() 6 | .and_then(|r| String::from_utf8(r.stdout).ok()) 7 | { 8 | println!("cargo:rustc-env=AXON_COMMIT_ID={}", commit_id); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /builtin-contract/crosschain/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | scripts/*.json 7 | 8 | #Hardhat files 9 | cache 10 | artifacts 11 | .openzeppelin 12 | *.log -------------------------------------------------------------------------------- /builtin-contract/crosschain/contracts/Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.8.0; 4 | 5 | interface IMetadata { 6 | function isProposer(address relayer) external returns (bool); 7 | 8 | function verifierList() external returns (address[] memory, uint256); 9 | 10 | function isVerifier(address relayer) external returns (bool); 11 | } 12 | -------------------------------------------------------------------------------- /builtin-contract/crosschain/contracts/MirrorToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.8.0; 3 | 4 | import "@openzeppelin/contracts/access/AccessControl.sol"; 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | import "@openzeppelin/contracts/access/Ownable.sol"; 7 | 8 | interface IMirrorToken is IERC20 { 9 | function burn(address from, uint256 amount) external; 10 | 11 | function mint(address to, uint256 amount) external; 12 | } 13 | 14 | contract MirrorToken is ERC20, AccessControl, Ownable, IMirrorToken { 15 | bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); 16 | 17 | uint8 private _decimals; 18 | 19 | constructor( 20 | string memory name, 21 | string memory symbol, 22 | uint8 decimals_ 23 | ) ERC20(name, symbol) { 24 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); 25 | _decimals = decimals_; 26 | } 27 | 28 | function decimals() public view override returns (uint8) { 29 | return _decimals; 30 | } 31 | 32 | function mint(address to, uint256 amount) 33 | external 34 | override 35 | onlyRole(MANAGER_ROLE) 36 | { 37 | _mint(to, amount); 38 | } 39 | 40 | function burn(address from, uint256 amount) 41 | external 42 | override 43 | onlyRole(MANAGER_ROLE) 44 | { 45 | _burn(from, amount); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /builtin-contract/crosschain/contracts/TestToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.8.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract TestToken is ERC20 { 7 | constructor() ERC20("test", "test") { 8 | _mint(_msgSender(), 1000 * 10**18); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /builtin-contract/crosschain/contracts/libraries/DataType.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.8.0; 4 | 5 | library DataType { 6 | struct TokenConfig { 7 | uint256 feeRatio; 8 | uint256 threshold; 9 | } 10 | 11 | struct CKBToAxonRecord { 12 | address to; 13 | address tokenAddress; 14 | uint256 sUDTAmount; 15 | uint256 CKBAmount; 16 | bytes32 txHash; 17 | } 18 | 19 | struct AxonToCKBRecord { 20 | address tokenAddress; 21 | uint256 amount; 22 | uint256 minWCKBAmount; 23 | string to; 24 | uint256 limitSign; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /builtin-contract/crosschain/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "crosschain-hardhat", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "compile": "hardhat compile", 8 | "test": "hardhat test", 9 | "deploy": "hardhat run scripts/crosschain.deploy.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@ethereumjs/tx": "^4.1.2", 15 | "@nomiclabs/hardhat-ethers": "^2.2.2", 16 | "@nomiclabs/hardhat-waffle": "^2.0.5", 17 | "@openzeppelin/contracts": "^4.9.2", 18 | "@openzeppelin/hardhat-upgrades": "^1.22.0", 19 | "chai": "^4.3.6", 20 | "ethereum-waffle": "^3.4.4", 21 | "ethereumjs-util": "^7.1.4", 22 | "ethers": "^5.7.1", 23 | "hardhat": "^2.14.0" 24 | }, 25 | "dependencies": { 26 | "dotenv": "^16.0.3" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /builtin-contract/system-contract/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | scripts/*.json 7 | 8 | # Hardhat files 9 | cache 10 | artifacts 11 | .openzeppelin 12 | *.log 13 | -------------------------------------------------------------------------------- /builtin-contract/system-contract/README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | It is an Ethereum smart contract project created by [hardhat](https://hardhat.org/tutorial). 4 | 5 | # Building 6 | 7 | ## Requirements 8 | 9 | - [node.js](https://github.com/nodesource/distributions#debinstall) 10 | - [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#debian-stable) 11 | - [npx](https://manpages.ubuntu.com/manpages/focal/man1/npx.1.html#install) 12 | 13 | ## Install 14 | 15 | ``` 16 | yarn 17 | ``` 18 | 19 | ## Compile 20 | 21 | ``` 22 | npx hardhat compile 23 | ``` 24 | 25 | ## Test 26 | 27 | ``` 28 | npx hardhat test 29 | ``` 30 | -------------------------------------------------------------------------------- /builtin-contract/system-contract/contracts/ckb_light_client/CkbLightClient.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.8.0; 3 | 4 | import "../libraries/CkbType.sol"; 5 | 6 | // **Notice** 7 | // This file only defines the interface of CKB light client contract. The real 8 | // implementation is in `core/executor/src/system_contract/ckb_light_client`. 9 | interface CkbLightClient { 10 | function setState(bool allowRead) external; 11 | 12 | function update(CkbType.Header[] calldata headers) external; 13 | 14 | function rollback(bytes32[] calldata blockHashes) external; 15 | } 16 | -------------------------------------------------------------------------------- /builtin-contract/system-contract/contracts/image_cell/ImageCell.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.8.0; 4 | 5 | import "../libraries/CkbType.sol"; 6 | 7 | library ImageCell { 8 | struct BlockUpdate { 9 | uint64 blockNumber; 10 | CkbType.OutPoint[] txInputs; 11 | CkbType.CellInfo[] txOutputs; 12 | } 13 | 14 | struct BlockRollBlack { 15 | CkbType.OutPoint[] txInputs; 16 | CkbType.OutPoint[] txOutputs; 17 | } 18 | } 19 | 20 | // **Notice** 21 | // This file only defines the interface of image cell contract. The real 22 | // implementation is in `core/executor/src/system_contract/image_cell`. 23 | interface ImageCellType { 24 | function setState(bool allowRead) external; 25 | 26 | function update(ImageCell.BlockUpdate[] calldata blocks) external; 27 | 28 | function rollback(ImageCell.BlockRollBlack[] calldata blocks) external; 29 | } 30 | -------------------------------------------------------------------------------- /builtin-contract/system-contract/contracts/libraries/CkbType.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.8.0; 4 | 5 | library CkbType { 6 | struct Header { 7 | uint32 version; 8 | uint32 compactTarget; 9 | uint64 timestamp; 10 | uint64 number; 11 | uint64 epoch; 12 | bytes32 parentHash; 13 | bytes32 transactionsRoot; 14 | bytes32 proposalsHash; 15 | bytes32 extraHash; 16 | bytes32 dao; 17 | uint128 nonce; 18 | bytes extension; 19 | bytes32 blockHash; 20 | } 21 | 22 | struct CellInfo { 23 | OutPoint outPoint; 24 | CellOutput output; 25 | bytes data; 26 | } 27 | 28 | struct OutPoint { 29 | bytes32 txHash; 30 | uint32 index; 31 | } 32 | 33 | struct CellOutput { 34 | uint64 capacity; 35 | Script lock; 36 | Script[] type_; 37 | } 38 | 39 | struct Script { 40 | bytes32 codeHash; 41 | ScriptHashType hashType; 42 | bytes args; 43 | } 44 | 45 | enum ScriptHashType { 46 | Data, // Type "data" matches script code via cell data hash, and run the script code in v0 CKB VM. 47 | Type, // Type "type" matches script code via cell type script hash. 48 | Data1 // Type "data1" matches script code via cell data hash, and run the script code in v1 CKB VM. 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /builtin-contract/system-contract/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | require('dotenv').config(); 3 | 4 | /** @type import('hardhat/config').HardhatUserConfig */ 5 | module.exports = { 6 | solidity: "0.8.20", 7 | }; 8 | -------------------------------------------------------------------------------- /builtin-contract/system-contract/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "system-contract-hardhat", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "compile": "hardhat compile", 7 | "test": "hardhat test" 8 | }, 9 | "author": "", 10 | "license": "SC", 11 | "devDependencies": { 12 | "@nomiclabs/hardhat-ethers": "^2.1.1", 13 | "@nomiclabs/hardhat-waffle": "^2.0.2", 14 | "chai": "^4.3.7", 15 | "ethers": "^5.7.2", 16 | "hardhat": "^2.12.4" 17 | }, 18 | "dependencies": { 19 | "dotenv": "^16.0.3" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | too-many-arguments-threshold = 12 2 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | target: 50 6 | threshold: null 7 | patch: false 8 | 9 | comment: 10 | layout: "reach, diff, flags, files" 11 | behavior: default 12 | require_changes: false 13 | require_base: false 14 | require_head: true 15 | -------------------------------------------------------------------------------- /common/apm-derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-apm-derive" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [lib] 8 | proc-macro = true 9 | 10 | [dependencies] 11 | fut-ret = "0.2" 12 | proc-macro2 = "1.0" 13 | quote = "1.0" 14 | serde_json = "1.0" 15 | syn = { version = "1.0", features = ["full"] } 16 | 17 | [dev-dependencies] 18 | async-trait = "0.1" 19 | common-apm = { path = "../apm" } 20 | jsonrpsee = { version = "0.20", features = ["macros"] } 21 | log = "0.4" 22 | 23 | protocol = { path = "../../protocol", package = "axon-protocol" } 24 | -------------------------------------------------------------------------------- /common/apm-derive/examples/api.rs: -------------------------------------------------------------------------------- 1 | use async_trait::async_trait; 2 | use common_apm_derive::metrics_rpc; 3 | use jsonrpsee::core::Error; 4 | 5 | use protocol::types::{Hash, SignedTransaction}; 6 | 7 | #[async_trait] 8 | pub trait Rpc { 9 | async fn send_transaction(&self, tx: SignedTransaction) -> Result; 10 | 11 | fn listening(&self) -> Result; 12 | } 13 | 14 | pub struct RpcExample; 15 | 16 | #[async_trait] 17 | impl Rpc for RpcExample { 18 | #[metrics_rpc("eth_sendRawTransaction")] 19 | async fn send_transaction(&self, tx: SignedTransaction) -> Result { 20 | Ok(tx.transaction.hash) 21 | } 22 | 23 | #[metrics_rpc("net_listening")] 24 | fn listening(&self) -> Result { 25 | Ok(false) 26 | } 27 | } 28 | 29 | fn main() {} 30 | -------------------------------------------------------------------------------- /common/apm-derive/examples/trace.rs: -------------------------------------------------------------------------------- 1 | use async_trait::async_trait; 2 | use common_apm_derive::trace_span; 3 | 4 | use protocol::{traits::Context, types::SignedTransaction, ProtocolResult}; 5 | 6 | #[async_trait] 7 | pub trait ToTrace { 8 | async fn store(&self, ctx: Context, txs: Vec) -> ProtocolResult<()>; 9 | 10 | fn version(&self, ctx: Context) -> String; 11 | } 12 | 13 | pub struct TraceExample; 14 | 15 | #[async_trait] 16 | impl ToTrace for TraceExample { 17 | #[trace_span(kind = "trace", logs = "{tx_len: txs.len()}")] 18 | async fn store(&self, ctx: Context, txs: Vec) -> ProtocolResult<()> { 19 | debug_assert!(txs.len() == 1); 20 | Ok(()) 21 | } 22 | 23 | #[trace_span(kind = "trace")] 24 | fn version(&self, ctx: Context) -> String { 25 | "0.1.0".to_string() 26 | } 27 | } 28 | 29 | fn main() {} 30 | -------------------------------------------------------------------------------- /common/apm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-apm" 3 | version = "0.2.1" 4 | authors = ["Nervos Dev "] 5 | edition = "2021" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | arc-swap = "1.6" 10 | axum = "0.6" 11 | beef = "0.5" 12 | derive_more = "0.99" 13 | lazy_static = "1.4" 14 | log = "0.4" 15 | minstant = "0.1" 16 | prometheus = "0.13" 17 | prometheus-static-metric = "0.5" 18 | rustracing = { git = "http://github.com/KaoImin/rustracing", branch = "main" } 19 | rustracing_jaeger = { git = "http://github.com/KaoImin/rustracing_jaeger", branch = "main" } 20 | trackable = "1.2" 21 | 22 | common-apm-derive = { path = "../apm-derive" } 23 | protocol = { path = "../../protocol", package = "axon-protocol", default-features = false } 24 | -------------------------------------------------------------------------------- /common/apm/src/lib.rs: -------------------------------------------------------------------------------- 1 | // https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp 2 | #![allow(clippy::float_cmp)] 3 | 4 | pub mod metrics; 5 | pub mod server; 6 | pub mod tracing; 7 | 8 | pub use common_apm_derive::{metrics_rpc, trace_span}; 9 | pub use minstant::{Anchor, Instant}; 10 | pub use prometheus; 11 | pub use prometheus_static_metric; 12 | pub use rustracing_jaeger::span::TraceId; 13 | -------------------------------------------------------------------------------- /common/apm/src/metrics/mem_tracker.rs: -------------------------------------------------------------------------------- 1 | use crate::metrics::{register_int_gauge_vec, IntGaugeVec}; 2 | 3 | use lazy_static::lazy_static; 4 | 5 | lazy_static! { 6 | pub static ref MEMORY_TRACE_VEC: IntGaugeVec = 7 | register_int_gauge_vec!("axon_memory_trace", "axon memory usage status", &[ 8 | "source", "type" 9 | ]) 10 | .unwrap(); 11 | pub static ref DB_MEMORY_TRACE_VEC: IntGaugeVec = 12 | register_int_gauge_vec!("axon_db_memory_trace", "axon memory usage status", &[ 13 | "source", "type", "cf" 14 | ]) 15 | .unwrap(); 16 | } 17 | -------------------------------------------------------------------------------- /common/apm/src/server.rs: -------------------------------------------------------------------------------- 1 | use axum::Router; 2 | use std::net::SocketAddr; 3 | 4 | pub async fn run_prometheus_server(prometheus_listening_address: SocketAddr) { 5 | let router = Router::new().route("/metrics", axum::routing::get(get_metrics)); 6 | axum::Server::bind(&prometheus_listening_address) 7 | .serve(router.into_make_service()) 8 | .await 9 | .unwrap(); 10 | } 11 | 12 | async fn get_metrics() -> String { 13 | let metrics_data = match crate::metrics::all_metrics() { 14 | Ok(data) => data, 15 | Err(e) => e.to_string().into_bytes(), 16 | }; 17 | 18 | String::from_utf8(metrics_data).unwrap() 19 | } 20 | -------------------------------------------------------------------------------- /common/config-parser/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-config-parser" 3 | version = "0.2.1" 4 | authors = ["Nervos Dev "] 5 | edition = "2021" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4", features = ["derive"] } 10 | reqwest = "0.11" 11 | serde = { version = "1.0", features = ["derive"] } 12 | serde_json = "1.0" 13 | stringreader = "0.1" 14 | strum = "0.25" 15 | strum_macros = "0.25" 16 | tentacle-multiaddr = "0.3" 17 | toml = "0.8" 18 | 19 | common-crypto = { path = "../../common/crypto" } 20 | protocol = { path = "../../protocol", package = "axon-protocol", default-features = false } 21 | -------------------------------------------------------------------------------- /common/config-parser/src/types/mod.rs: -------------------------------------------------------------------------------- 1 | use std::{ffi::OsStr, marker::PhantomData, path::PathBuf}; 2 | 3 | use clap::builder::{StringValueParser, TypedValueParser}; 4 | use serde::de; 5 | 6 | use crate::parse_file; 7 | 8 | mod config; 9 | pub mod spec; 10 | 11 | pub use config::*; 12 | 13 | #[derive(Clone, Debug)] 14 | pub struct JsonValueParser(PhantomData); 15 | 16 | impl Default for JsonValueParser 17 | where 18 | T: de::DeserializeOwned + 'static + Clone + Send + Sync, 19 | { 20 | fn default() -> Self { 21 | Self(PhantomData) 22 | } 23 | } 24 | 25 | impl TypedValueParser for JsonValueParser 26 | where 27 | T: de::DeserializeOwned + 'static + Clone + Send + Sync, 28 | { 29 | type Value = T; 30 | 31 | fn parse_ref( 32 | &self, 33 | cmd: &clap::Command, 34 | arg: Option<&clap::Arg>, 35 | value: &OsStr, 36 | ) -> Result { 37 | let file_path = StringValueParser::new() 38 | .parse_ref(cmd, arg, value) 39 | .map(PathBuf::from)?; 40 | parse_file(&file_path, true).map_err(|err| { 41 | let kind = clap::error::ErrorKind::InvalidValue; 42 | let msg = format!( 43 | "failed to parse JSON file {} since {err}", 44 | file_path.display() 45 | ); 46 | clap::Error::raw(kind, msg) 47 | }) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /common/crypto/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-crypto" 3 | version = "0.2.1" 4 | authors = ["Nervos Dev "] 5 | edition = "2021" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | # We need to enable the portable feature because some github runners don't support ADX 10 | blst = { version = "0.3", features = ["portable"] } 11 | ophelia = "0.3" 12 | ophelia-blst = "0.3" 13 | ophelia-secp256k1 = "0.3" 14 | 15 | [dev-dependencies] 16 | criterion = "0.5" 17 | overlord = "0.4" 18 | rand = "0.7" 19 | rlp = "0.5" 20 | 21 | protocol = { path = "../../protocol", package = "axon-protocol", default-features = false } 22 | 23 | [[bench]] 24 | harness = false 25 | name = "bench_sig" 26 | -------------------------------------------------------------------------------- /common/crypto/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub use ophelia::HashValue; 2 | pub use ophelia::{ 3 | BlsSignatureVerify, Crypto, Error, PrivateKey, PublicKey, Signature, ToBlsPublicKey, 4 | ToPublicKey, UncompressedPublicKey, 5 | }; 6 | pub use ophelia_blst::{BlsPrivateKey, BlsPublicKey, BlsSignature}; 7 | pub use ophelia_secp256k1::{ 8 | recover as secp256k1_recover, Secp256k1, Secp256k1PrivateKey, Secp256k1PublicKey, 9 | Secp256k1Recoverable, Secp256k1RecoverablePrivateKey, Secp256k1RecoverablePublicKey, 10 | Secp256k1RecoverableSignature, Secp256k1Signature, 11 | }; 12 | -------------------------------------------------------------------------------- /common/hasher/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-hasher" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | tiny-keccak = { version = "2.0", features = ["keccak"] } 9 | -------------------------------------------------------------------------------- /common/hasher/src/lib.rs: -------------------------------------------------------------------------------- 1 | use tiny_keccak::{Hasher, Keccak}; 2 | 3 | pub fn keccak256>(data: B) -> [u8; 32] { 4 | let mut result = [0u8; 32]; 5 | let mut hasher = Keccak::v256(); 6 | hasher.update(data.as_ref()); 7 | hasher.finalize(&mut result); 8 | result 9 | } 10 | -------------------------------------------------------------------------------- /common/logger/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-logger" 3 | version = "0.2.1" 4 | authors = ["Nervos Dev "] 5 | edition = "2021" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | anyhow = "1.0" 10 | chrono = "0.4" 11 | creep = "0.2" 12 | env_logger = "0.10" 13 | json = "0.12" 14 | log = "0.4" 15 | # Turn off gzip feature, it hurts performance. For more information, reference 16 | # log4rs document. 17 | log4rs = { version = "1.2", features = ["all_components", "file_appender", "yaml_format"] } 18 | rustracing_jaeger = "0.7" 19 | serde = { version = "1.0", features = ["derive"] } 20 | -------------------------------------------------------------------------------- /common/logger/log.yml: -------------------------------------------------------------------------------- 1 | # This file is yaml style config, can make testing the logger more easily. 2 | # When you need to do some test, Add the code below to the `init` function. 3 | # log4rs::init_file("common/logger/log.yml", Default::default()).unwrap(); 4 | # reference: 5 | appenders: 6 | console: 7 | kind: console 8 | encoder: 9 | # this pattern below contains file name and line, usefule for debugging 10 | # pattern: "[{d} {h({l})} {t} {f}:{L}] {m}{n}" 11 | pattern: "[{d} {h({l})} {t}] {m}{n}" 12 | 13 | file: 14 | kind: file 15 | path: logs/axon.log 16 | encoder: 17 | kind: json 18 | 19 | metrics: 20 | kind: file 21 | path: logs/metrics.log 22 | encoder: 23 | kind: json 24 | 25 | root: 26 | level: info 27 | appenders: 28 | - console 29 | - file 30 | 31 | loggers: 32 | metrics: 33 | level: trace 34 | appenders: 35 | - metrics 36 | additive: false 37 | -------------------------------------------------------------------------------- /common/memory-tracker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = "2021" 3 | name = "common-memory-tracker" 4 | version = "0.1.0" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | jemalloc-ctl = { version = "0.5", package = "tikv-jemalloc-ctl" } 9 | libc = "0.2" 10 | log = "0.4" 11 | once_cell = "1.17" 12 | rocksdb = { version = "0.21", package = "ckb-rocksdb" } 13 | 14 | common-apm = { path = "../apm" } 15 | protocol = { path = "../../protocol", package = "axon-protocol" } 16 | -------------------------------------------------------------------------------- /common/merkle/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-merkle" 3 | version = "0.2.1" 4 | authors = ["Nervos Dev "] 5 | edition = "2021" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | hasher = "0.1" 10 | rlp = "0.5" 11 | static_merkle_tree = "1.1" 12 | 13 | protocol = { path = "../../protocol", package = "axon-protocol", default-features = false } 14 | 15 | [dev-dependencies] 16 | criterion = "0.5" 17 | rand = "0.7" 18 | 19 | [[bench]] 20 | harness = false 21 | name = "bench" 22 | -------------------------------------------------------------------------------- /common/merkle/benches/bench.rs: -------------------------------------------------------------------------------- 1 | use criterion::{criterion_group, criterion_main, Criterion}; 2 | 3 | use common_merkle::*; 4 | use protocol::types::Hash; 5 | 6 | fn mock_hash() -> Hash { 7 | Hash::random() 8 | } 9 | 10 | fn rand_hashes(size: usize) -> Vec { 11 | (0..size).map(|_| mock_hash()).collect::>() 12 | } 13 | 14 | fn criterion_merkle(c: &mut Criterion) { 15 | // MacOS M1 Pro 16G: 345.85µs 16 | c.bench_function("merkle 1000 hashes", |b| { 17 | let case = rand_hashes(1000); 18 | b.iter(|| { 19 | let _ = Merkle::from_hashes(case.clone()); 20 | }); 21 | }); 22 | // MacOS M1 Pro 16G: 697.92µs 23 | c.bench_function("merkle 2000 hashes", |b| { 24 | let case = rand_hashes(2000); 25 | b.iter(|| { 26 | let _ = Merkle::from_hashes(case.clone()); 27 | }); 28 | }); 29 | // MacOS M1 Pro 16G: 1.41ms 30 | c.bench_function("merkle 4000 hashes", |b| { 31 | let case = rand_hashes(4000); 32 | b.iter(|| { 33 | let _ = Merkle::from_hashes(case.clone()); 34 | }); 35 | }); 36 | // MacOS M1 Pro 16G: 2.84ms 37 | c.bench_function("merkle 8000 hashes", |b| { 38 | let case = rand_hashes(8000); 39 | b.iter(|| { 40 | let _ = Merkle::from_hashes(case.clone()); 41 | }); 42 | }); 43 | // MacOS M1 Pro 16G: 5.65ms 44 | c.bench_function("merkle 16000 hashes", |b| { 45 | let case = rand_hashes(16000); 46 | b.iter(|| { 47 | let _ = Merkle::from_hashes(case.clone()); 48 | }); 49 | }); 50 | } 51 | 52 | criterion_group!(benches, criterion_merkle); 53 | criterion_main!(benches); 54 | -------------------------------------------------------------------------------- /common/version/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common-version" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | semver = "1.0" 9 | -------------------------------------------------------------------------------- /common/version/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{Display, Formatter}; 2 | use std::str::FromStr; 3 | 4 | pub const DEFAULT_COMMIT_ID: &str = "unknown"; 5 | 6 | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] 7 | pub struct Version { 8 | inner: semver::Version, 9 | } 10 | 11 | impl FromStr for Version { 12 | type Err = semver::Error; 13 | 14 | fn from_str(s: &str) -> Result { 15 | semver::Version::from_str(s).map(|inner| Version { inner }) 16 | } 17 | } 18 | 19 | impl Display for Version { 20 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 21 | write!(f, "{}", self.inner) 22 | } 23 | } 24 | 25 | impl Version { 26 | pub fn new(ver: &str) -> Self { 27 | Version::from_str(ver) 28 | .unwrap_or_else(|e| panic!("Parse version error {:?}", e)) 29 | .set_commit_id(DEFAULT_COMMIT_ID) 30 | } 31 | 32 | pub fn new_with_commit_id(ver: &str, commit_id: &str) -> Self { 33 | Version::new(ver).set_commit_id(commit_id) 34 | } 35 | 36 | pub fn commit_id(&self) -> String { 37 | self.inner.build.to_ascii_lowercase() 38 | } 39 | 40 | fn set_commit_id(mut self, commit_id: &str) -> Self { 41 | self.inner.build = semver::BuildMetadata::new(commit_id) 42 | .unwrap_or_else(|e| panic!("Parse commit id error {:?}", e)); 43 | 44 | self 45 | } 46 | } 47 | 48 | #[cfg(test)] 49 | mod tests { 50 | use semver::BuildMetadata; 51 | use std::str::FromStr; 52 | 53 | use crate::DEFAULT_COMMIT_ID; 54 | 55 | #[test] 56 | fn test_parse_default_commit_id() { 57 | let build = BuildMetadata::from_str(DEFAULT_COMMIT_ID); 58 | assert_eq!(build.unwrap().as_str(), DEFAULT_COMMIT_ID); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /core/api/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-api" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | # async-graphql = { version = "3.0", features = ["tracing"] } 9 | beef = "0.5" 10 | ckb-jsonrpc-types = "0.111" 11 | ckb-traits = "0.111" 12 | ckb-types = "0.111" 13 | hyper = "0.14" 14 | jsonrpsee = { version = "0.20", features = ["macros", "server"] } 15 | log = "0.4" 16 | parking_lot = "0.12" 17 | pprof = { version = "0.11", features = ["prost-codec"], optional = true } 18 | rlp = "0.5" 19 | serde = { version = "1.0", features = ["derive"] } 20 | serde_json = "1.0" 21 | strum = "0.25" 22 | tower = "0.4" 23 | tower-http = { version = "0.4", features = ["cors"] } 24 | 25 | common-apm = { path = "../../common/apm" } 26 | common-config-parser = { path = "../../common/config-parser" } 27 | core-consensus = { path = "../../core/consensus" } 28 | core-executor = { path = "../../core/executor" } 29 | core-interoperation = { path = "../../core/interoperation" } 30 | either = { version = "1.8", features = ["serde"] } 31 | protocol = { path = "../../protocol", package = "axon-protocol" } 32 | 33 | [dev-dependencies] 34 | json = "0.12" 35 | -------------------------------------------------------------------------------- /core/api/src/graphql/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core/api/src/jsonrpc/impl/mod.rs: -------------------------------------------------------------------------------- 1 | mod axon; 2 | mod ckb_light_client; 3 | mod filter; 4 | mod node; 5 | mod web3; 6 | 7 | pub use axon::AxonRpcImpl; 8 | pub use ckb_light_client::CkbLightClientRpcImpl; 9 | pub use filter::filter_module; 10 | pub use node::NodeRpcImpl; 11 | pub use web3::{from_receipt_to_web3_log, Web3RpcImpl}; 12 | -------------------------------------------------------------------------------- /core/api/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod adapter; 2 | pub mod graphql; 3 | pub mod jsonrpc; 4 | 5 | pub use adapter::DefaultAPIAdapter; 6 | 7 | use std::error::Error; 8 | 9 | use protocol::{Display, ProtocolError, ProtocolErrorKind}; 10 | 11 | #[derive(Debug, Display)] 12 | pub enum APIError { 13 | #[display(fmt = "adapter error {:?}", _0)] 14 | Adapter(String), 15 | 16 | #[display(fmt = "http server error {:?}", _0)] 17 | HttpServer(String), 18 | 19 | #[display(fmt = "web socket server error {:?}", _0)] 20 | WebSocketServer(String), 21 | 22 | #[display(fmt = "storage error {:?}", _0)] 23 | Storage(String), 24 | 25 | #[display(fmt = "Invalid request payload {:?}", _0)] 26 | RequestPayload(String), 27 | } 28 | 29 | impl Error for APIError {} 30 | 31 | impl From for ProtocolError { 32 | fn from(error: APIError) -> ProtocolError { 33 | ProtocolError::new(ProtocolErrorKind::API, Box::new(error)) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core/cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-cli" 3 | version = "0.1.1" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | anyhow = "1.0" 9 | clap = { version = "4.4", features = ["cargo", "string", "derive"] } 10 | semver = "1.0" 11 | serde = { version = "1.0", features = ["derive"] } 12 | serde_json = "1.0" 13 | tempfile = "3.6" 14 | tentacle-secio = "0.6" 15 | thiserror = "1.0" 16 | 17 | common-config-parser = { path = "../../common/config-parser" } 18 | common-crypto ={ path = "../../common/crypto" } 19 | common-logger = { path = "../../common/logger" } 20 | common-version = { path = "../../common/version" } 21 | core-run = { path = "../../core/run" } 22 | protocol = { path = "../../protocol", package = "axon-protocol" } 23 | -------------------------------------------------------------------------------- /core/cli/src/args/hardfork.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | use common_config_parser::types::{spec::HardforkInput, Config}; 4 | 5 | use crate::error::{Error, Result}; 6 | 7 | #[derive(Parser, Debug)] 8 | #[command(about = "About Axon hardfork feature")] 9 | pub struct HardforkArgs { 10 | #[arg( 11 | short = 'c', 12 | long = "config", 13 | value_name = "CONFIG_FILE", 14 | help = "File path of client configurations." 15 | )] 16 | pub config: Config, 17 | 18 | #[command(flatten)] 19 | hardforks: Option, 20 | } 21 | 22 | impl HardforkArgs { 23 | pub fn execute(self) -> Result<()> { 24 | core_run::set_hardfork_info(self.config, self.hardforks.map(Into::into)) 25 | .map_err(Error::Running)?; 26 | Ok(()) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/cli/src/args/init.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | use common_config_parser::types::{spec::ChainSpec, Config}; 4 | use common_version::Version; 5 | 6 | use crate::{ 7 | error::{Error, Result}, 8 | utils, 9 | }; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(about = "Initialize new axon data directory")] 13 | pub struct InitArgs { 14 | #[arg( 15 | short = 'c', 16 | long = "config", 17 | value_name = "CONFIG_FILE", 18 | help = "File path of client configurations." 19 | )] 20 | pub config: Config, 21 | #[arg( 22 | short = 's', 23 | long = "chain-spec", 24 | value_name = "CHAIN_SPEC_FILE", 25 | help = "File path of chain spec." 26 | )] 27 | pub spec: ChainSpec, 28 | } 29 | 30 | impl InitArgs { 31 | pub(crate) fn execute(self, kernel_version: Version) -> Result<()> { 32 | let Self { config, spec } = self; 33 | 34 | utils::check_version( 35 | &config.data_path_for_version(), 36 | &kernel_version, 37 | utils::latest_compatible_version(), 38 | )?; 39 | utils::register_log(&config); 40 | 41 | core_run::init(config, spec).map_err(Error::Running) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/cli/src/args/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod generate_keypair; 2 | pub(crate) mod hardfork; 3 | pub(crate) mod init; 4 | pub(crate) mod recover_keypair; 5 | pub(crate) mod run; 6 | -------------------------------------------------------------------------------- /core/cli/src/args/run.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | use common_config_parser::types::Config; 4 | use common_version::Version; 5 | use core_run::{KeyProvider, StopOpt}; 6 | 7 | use crate::{ 8 | error::{Error, Result}, 9 | utils, 10 | }; 11 | 12 | #[derive(Parser, Debug)] 13 | #[command(about = "Run axon service")] 14 | pub struct RunArgs { 15 | #[arg( 16 | short = 'c', 17 | long = "config", 18 | value_name = "CONFIG_FILE", 19 | help = "File path of client configurations." 20 | )] 21 | pub config: Config, 22 | #[arg(long = "mine-blocks", help = "Exit after mine N blocks")] 23 | pub mine_blocks: Option, 24 | #[arg(long = "mine-to-height", help = "Exit when reach the height")] 25 | pub mine_to_height: Option, 26 | } 27 | 28 | impl RunArgs { 29 | pub(crate) fn execute( 30 | self, 31 | application_version: Version, 32 | kernel_version: Version, 33 | key_provider: Option, 34 | ) -> Result<()> { 35 | let Self { 36 | config, 37 | mine_blocks, 38 | mine_to_height, 39 | } = self; 40 | 41 | let stop_opt = match (mine_blocks, mine_to_height) { 42 | (Some(blocks), None) => Some(StopOpt::MineNBlocks(blocks)), 43 | (None, Some(height)) => Some(StopOpt::MineToHeight(height)), 44 | _ => None, 45 | }; 46 | 47 | utils::check_version( 48 | &config.data_path_for_version(), 49 | &kernel_version, 50 | utils::latest_compatible_version(), 51 | )?; 52 | utils::register_log(&config); 53 | 54 | let version = application_version.to_string(); 55 | core_run::run(version, config, key_provider, stop_opt).map_err(Error::Running) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/cli/src/error.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | use common_version::Version; 4 | use thiserror::Error; 5 | 6 | use protocol::ProtocolError; 7 | 8 | #[non_exhaustive] 9 | #[derive(Error, Debug)] 10 | pub enum Error { 11 | // Boxing so the error type isn't too large (clippy::result-large-err). 12 | #[error(transparent)] 13 | CheckingVersion(Box), 14 | 15 | #[error("reading data version: {0}")] 16 | ReadingVersion(#[source] io::Error), 17 | #[error("writing data version: {0}")] 18 | WritingVersion(#[source] io::Error), 19 | 20 | #[error("reading private key: {0}")] 21 | ReadingPrivateKey(#[source] io::Error), 22 | #[error("writing private key: {0}")] 23 | WritingPrivateKey(#[source] io::Error), 24 | 25 | #[error(transparent)] 26 | Running(ProtocolError), 27 | 28 | #[error("crypto error: {0}")] 29 | Crypto(String), 30 | 31 | #[error("internal error: {0}")] 32 | Internal(String), 33 | } 34 | 35 | #[non_exhaustive] 36 | #[derive(Error, Debug)] 37 | #[cfg_attr(test, derive(PartialEq, Eq))] 38 | #[error("data version({data}) is not compatible with the current axon version({current}), version >= {least_compatible} is supported")] 39 | pub struct CheckingVersionError { 40 | pub current: Version, 41 | pub data: Version, 42 | pub least_compatible: Version, 43 | } 44 | 45 | pub type Result = std::result::Result; 46 | -------------------------------------------------------------------------------- /core/consensus/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-consensus" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | arc-swap = "1.6" 9 | 10 | futures = { version = "0.3", features = ["async-await"] } 11 | json = "0.12" 12 | lazy_static = "1.4" 13 | log = "0.4" 14 | overlord = "0.4" 15 | parking_lot = "0.12" 16 | rlp = "0.5" 17 | rlp-derive = "0.1" 18 | serde = { version = "1.0", features = ["derive"] } 19 | serde_json = "1.0" 20 | 21 | common-apm = { path = "../../common/apm" } 22 | common-apm-derive = { path = "../../common/apm-derive" } 23 | common-crypto = { path = "../../common/crypto" } 24 | common-logger = { path = "../../common/logger" } 25 | common-merkle = { path = "../../common/merkle" } 26 | core-executor = { path = "../../core/executor" } 27 | core-mempool = { path = "../../core/mempool" } 28 | core-network = { path = "../../core/network" } 29 | core-storage = { path = "../../core/storage" } 30 | protocol = { path = "../../protocol", package = "axon-protocol" } 31 | 32 | [dev-dependencies] 33 | bit-vec = "0.6" 34 | criterion = "0.5" 35 | num-traits = "0.2" 36 | 37 | [features] 38 | default = [] 39 | random_leader = ["overlord/random_leader"] 40 | 41 | [[bench]] 42 | harness = false 43 | name = "bench_wal" 44 | -------------------------------------------------------------------------------- /core/consensus/src/status.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use parking_lot::Mutex; 4 | 5 | use protocol::types::{BlockNumber, Hash, Proof, H256, U256}; 6 | 7 | #[derive(Clone)] 8 | pub struct StatusAgent(Arc>); 9 | 10 | impl StatusAgent { 11 | pub fn new(status: CurrentStatus) -> Self { 12 | StatusAgent(Arc::new(Mutex::new(status))) 13 | } 14 | 15 | pub fn inner(&self) -> CurrentStatus { 16 | self.0.lock().clone() 17 | } 18 | 19 | pub fn swap(&self, new: CurrentStatus) { 20 | *self.0.lock() = new; 21 | } 22 | } 23 | 24 | #[derive(Default, Clone, Debug, PartialEq, Eq)] 25 | pub struct CurrentStatus { 26 | pub prev_hash: Hash, 27 | pub last_number: BlockNumber, 28 | pub last_state_root: H256, 29 | pub tx_num_limit: u64, 30 | pub max_tx_size: U256, 31 | pub proof: Proof, 32 | } 33 | -------------------------------------------------------------------------------- /core/consensus/src/stop_signal.rs: -------------------------------------------------------------------------------- 1 | use std::sync::RwLock; 2 | 3 | use protocol::tokio::{self}; 4 | 5 | pub enum StopOpt { 6 | MineNBlocks(u64), 7 | MineToHeight(u64), 8 | } 9 | 10 | type SignalSender = tokio::sync::oneshot::Sender<()>; 11 | 12 | pub struct StopSignal { 13 | tx: RwLock>, 14 | stop_at_height: Option, 15 | } 16 | 17 | impl StopSignal { 18 | pub fn new(tx: SignalSender) -> Self { 19 | Self { 20 | tx: RwLock::new(Some(tx)), 21 | stop_at_height: None, 22 | } 23 | } 24 | 25 | pub fn with_stop_at(tx: SignalSender, height: u64) -> Self { 26 | Self { 27 | tx: RwLock::new(Some(tx)), 28 | stop_at_height: Some(height), 29 | } 30 | } 31 | 32 | pub fn check_height_and_send(&self, height: u64) { 33 | if Some(height) == self.stop_at_height { 34 | self.send(); 35 | } 36 | } 37 | 38 | pub fn send(&self) { 39 | if let Some(tx) = self.tx.write().unwrap().take() { 40 | let _ = tx.send(()); 41 | } 42 | } 43 | 44 | pub fn is_stopped(&self) -> bool { 45 | self.tx.read().unwrap().is_none() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /core/db/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-db" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | parking_lot = "0.12" 9 | rocksdb = { version = "0.21", package = "ckb-rocksdb" } 10 | 11 | common-apm = { path = "../../common/apm" } 12 | common-apm-derive = { path = "../../common/apm-derive" } 13 | common-config-parser = { path = "../../common/config-parser" } 14 | protocol = { path = "../../protocol", package = "axon-protocol" } 15 | 16 | -------------------------------------------------------------------------------- /core/db/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod memory; 2 | mod rocks; 3 | 4 | pub use crate::memory::MemoryAdapter; 5 | pub use crate::rocks::{get_column, map_category, RocksAdapter}; 6 | pub use rocksdb::DB as RocksDB; 7 | -------------------------------------------------------------------------------- /core/executor/src/adapter/backend/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod apply; 2 | pub mod read_only; 3 | -------------------------------------------------------------------------------- /core/executor/src/adapter/mod.rs: -------------------------------------------------------------------------------- 1 | mod backend; 2 | mod trie; 3 | 4 | pub use backend::{apply::AxonExecutorApplyAdapter, read_only::AxonExecutorReadOnlyAdapter}; 5 | pub use trie::{db::RocksTrieDB, wrapped::MPTTrie}; 6 | 7 | #[macro_export] 8 | macro_rules! blocking_async { 9 | ($self_: ident, $adapter: ident, $method: ident$ (, $args: expr)*) => {{ 10 | let rt = protocol::tokio::runtime::Handle::current(); 11 | let adapter_clone = $self_.$adapter(); 12 | 13 | protocol::tokio::task::block_in_place(move || { 14 | rt.block_on(adapter_clone.$method( $($args,)* )).unwrap() 15 | }) 16 | }}; 17 | } 18 | -------------------------------------------------------------------------------- /core/executor/src/adapter/trie/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod db; 2 | pub mod wrapped; 3 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/ckb_blake2b.rs: -------------------------------------------------------------------------------- 1 | use evm::executor::stack::{PrecompileFailure, PrecompileOutput}; 2 | use evm::{Context, ExitError, ExitSucceed}; 3 | 4 | use protocol::{ckb_blake2b_256, types::H160}; 5 | 6 | use crate::err; 7 | use crate::precompiles::{axon_precompile_address, PrecompileContract}; 8 | 9 | #[derive(Default, Clone)] 10 | pub struct CkbBlake2b; 11 | 12 | impl PrecompileContract for CkbBlake2b { 13 | const ADDRESS: H160 = axon_precompile_address(0x06); 14 | const MIN_GAS: u64 = 60; 15 | 16 | fn exec_fn( 17 | input: &[u8], 18 | gas_limit: Option, 19 | _context: &Context, 20 | _is_static: bool, 21 | ) -> Result<(PrecompileOutput, u64), PrecompileFailure> { 22 | let gas = Self::gas_cost(input); 23 | if let Some(limit) = gas_limit { 24 | if gas > limit { 25 | return err!(); 26 | } 27 | } 28 | 29 | Ok(( 30 | PrecompileOutput { 31 | exit_status: ExitSucceed::Returned, 32 | output: ckb_blake2b_256(input).to_vec(), 33 | }, 34 | gas, 35 | )) 36 | } 37 | 38 | /// Estimate the gas cost = MIN_GAS + dynamic_gas 39 | /// = MIN_GAS + 12 * data_word_size 40 | fn gas_cost(input: &[u8]) -> u64 { 41 | let data_word_size = (input.len() + 31) / 32; 42 | (data_word_size * 12) as u64 + Self::MIN_GAS 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/ec_add.rs: -------------------------------------------------------------------------------- 1 | use bn::AffineG1; 2 | use evm::executor::stack::{PrecompileFailure, PrecompileOutput}; 3 | use evm::{Context, ExitError, ExitSucceed}; 4 | 5 | use protocol::types::H160; 6 | 7 | use crate::err; 8 | use crate::precompiles::{eip_precompile_address, read_point, PrecompileContract}; 9 | 10 | #[derive(Default)] 11 | pub struct EcAdd; 12 | 13 | impl PrecompileContract for EcAdd { 14 | const ADDRESS: H160 = eip_precompile_address(0x06); 15 | const MIN_GAS: u64 = 150; 16 | 17 | fn exec_fn( 18 | input: &[u8], 19 | gas_limit: Option, 20 | _context: &Context, 21 | _is_static: bool, 22 | ) -> Result<(PrecompileOutput, u64), PrecompileFailure> { 23 | let gas = Self::gas_cost(input); 24 | if let Some(limit) = gas_limit { 25 | if limit < gas { 26 | return err!(); 27 | } 28 | } 29 | 30 | let p1 = read_point(input, 0)?; 31 | let p2 = read_point(input, 64)?; 32 | 33 | let mut res = [0u8; 64]; 34 | if let Some(sum) = AffineG1::from_jacobian(p1 + p2) { 35 | sum.x() 36 | .to_big_endian(&mut res[0..32]) 37 | .map_err(|_| err!(_, "Invalid sum X"))?; 38 | sum.y() 39 | .to_big_endian(&mut res[32..64]) 40 | .map_err(|_| err!(_, "Invalid sum Y"))?; 41 | } 42 | 43 | Ok(( 44 | PrecompileOutput { 45 | exit_status: ExitSucceed::Returned, 46 | output: res.to_vec(), 47 | }, 48 | gas, 49 | )) 50 | } 51 | 52 | fn gas_cost(_input: &[u8]) -> u64 { 53 | Self::MIN_GAS 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/ec_mul.rs: -------------------------------------------------------------------------------- 1 | use bn::AffineG1; 2 | use evm::executor::stack::{PrecompileFailure, PrecompileOutput}; 3 | use evm::{Context, ExitError, ExitSucceed}; 4 | 5 | use protocol::types::H160; 6 | 7 | use crate::err; 8 | use crate::precompiles::{eip_precompile_address, read_fr, read_point, PrecompileContract}; 9 | 10 | #[derive(Default)] 11 | pub struct EcMul; 12 | 13 | impl PrecompileContract for EcMul { 14 | const ADDRESS: H160 = eip_precompile_address(0x07); 15 | const MIN_GAS: u64 = 6_000; 16 | 17 | fn exec_fn( 18 | input: &[u8], 19 | gas_limit: Option, 20 | _context: &Context, 21 | _is_static: bool, 22 | ) -> Result<(PrecompileOutput, u64), PrecompileFailure> { 23 | let gas = Self::gas_cost(input); 24 | if let Some(limit) = gas_limit { 25 | if limit < gas { 26 | return err!(); 27 | } 28 | } 29 | 30 | let p = read_point(input, 0)?; 31 | let fr = read_fr(input, 64)?; 32 | 33 | let mut res = [0u8; 64]; 34 | if let Some(sum) = AffineG1::from_jacobian(p * fr) { 35 | sum.x() 36 | .to_big_endian(&mut res[0..32]) 37 | .map_err(|_| err!(_, "Invalid sum X"))?; 38 | sum.y() 39 | .to_big_endian(&mut res[32..64]) 40 | .map_err(|_| err!(_, "Invalid sum Y"))?; 41 | } 42 | 43 | Ok(( 44 | PrecompileOutput { 45 | exit_status: ExitSucceed::Returned, 46 | output: res.to_vec(), 47 | }, 48 | gas, 49 | )) 50 | } 51 | 52 | fn gas_cost(_input: &[u8]) -> u64 { 53 | Self::MIN_GAS 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/identity.rs: -------------------------------------------------------------------------------- 1 | use evm::executor::stack::{PrecompileFailure, PrecompileOutput}; 2 | use evm::{Context, ExitError, ExitSucceed}; 3 | 4 | use protocol::types::H160; 5 | 6 | use crate::err; 7 | use crate::precompiles::{eip_precompile_address, PrecompileContract}; 8 | 9 | #[derive(Default, Clone)] 10 | pub struct Identity; 11 | 12 | impl PrecompileContract for Identity { 13 | const ADDRESS: H160 = eip_precompile_address(0x04); 14 | const MIN_GAS: u64 = 15; 15 | 16 | fn exec_fn( 17 | input: &[u8], 18 | gas_limit: Option, 19 | _context: &Context, 20 | _is_static: bool, 21 | ) -> Result<(PrecompileOutput, u64), PrecompileFailure> { 22 | let gas = Self::gas_cost(input); 23 | if let Some(limit) = gas_limit { 24 | if gas > limit { 25 | return err!(); 26 | } 27 | } 28 | 29 | Ok(( 30 | PrecompileOutput { 31 | exit_status: ExitSucceed::Returned, 32 | output: input.to_vec(), 33 | }, 34 | gas, 35 | )) 36 | } 37 | 38 | fn gas_cost(input: &[u8]) -> u64 { 39 | let data_word_size = (input.len() + 31) / 32; 40 | (data_word_size * 3) as u64 + Self::MIN_GAS 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/ripemd160.rs: -------------------------------------------------------------------------------- 1 | use evm::executor::stack::{PrecompileFailure, PrecompileOutput}; 2 | use evm::{Context, ExitError, ExitSucceed}; 3 | use ripemd::Digest; 4 | 5 | use protocol::types::H160; 6 | 7 | use crate::err; 8 | use crate::precompiles::{eip_precompile_address, PrecompileContract}; 9 | 10 | #[derive(Default, Clone)] 11 | pub struct Ripemd160; 12 | 13 | impl PrecompileContract for Ripemd160 { 14 | const ADDRESS: H160 = eip_precompile_address(0x03); 15 | const MIN_GAS: u64 = 600; 16 | 17 | fn exec_fn( 18 | input: &[u8], 19 | gas_limit: Option, 20 | _context: &Context, 21 | _is_static: bool, 22 | ) -> Result<(PrecompileOutput, u64), PrecompileFailure> { 23 | let gas = Self::gas_cost(input); 24 | if let Some(limit) = gas_limit { 25 | if gas > limit { 26 | return err!(); 27 | } 28 | } 29 | 30 | let mut ret = [0u8; 32]; 31 | let mut hasher = ripemd::Ripemd160::default(); 32 | hasher.update(input); 33 | ret[12..].copy_from_slice(&hasher.finalize()); 34 | 35 | Ok(( 36 | PrecompileOutput { 37 | exit_status: ExitSucceed::Returned, 38 | output: ret.to_vec(), 39 | }, 40 | gas, 41 | )) 42 | } 43 | 44 | fn gas_cost(input: &[u8]) -> u64 { 45 | let data_word_size = (input.len() + 31) / 32; 46 | (data_word_size * 120) as u64 + Self::MIN_GAS 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/rsa.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/secp256r1.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core/executor/src/precompiles/sha256.rs: -------------------------------------------------------------------------------- 1 | use evm::executor::stack::{PrecompileFailure, PrecompileOutput}; 2 | use evm::{Context, ExitError, ExitSucceed}; 3 | use sha2::Digest; 4 | 5 | use protocol::types::H160; 6 | 7 | use crate::err; 8 | use crate::precompiles::{eip_precompile_address, PrecompileContract}; 9 | 10 | #[derive(Default, Clone)] 11 | pub struct Sha256; 12 | 13 | impl PrecompileContract for Sha256 { 14 | const ADDRESS: H160 = eip_precompile_address(0x02); 15 | const MIN_GAS: u64 = 60; 16 | 17 | fn exec_fn( 18 | input: &[u8], 19 | gas_limit: Option, 20 | _context: &Context, 21 | _is_static: bool, 22 | ) -> Result<(PrecompileOutput, u64), PrecompileFailure> { 23 | let gas = Self::gas_cost(input); 24 | if let Some(limit) = gas_limit { 25 | if gas > limit { 26 | return err!(); 27 | } 28 | } 29 | 30 | let mut hasher = sha2::Sha256::default(); 31 | hasher.update(input); 32 | 33 | Ok(( 34 | PrecompileOutput { 35 | exit_status: ExitSucceed::Returned, 36 | output: hasher.finalize().to_vec(), 37 | }, 38 | gas, 39 | )) 40 | } 41 | 42 | fn gas_cost(input: &[u8]) -> u64 { 43 | let data_word_size = (input.len() + 31) / 32; 44 | (data_word_size * 12) as u64 + Self::MIN_GAS 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/executor/src/system_contract/ckb_light_client/abi/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod ckb_light_client_abi; 2 | -------------------------------------------------------------------------------- /core/executor/src/system_contract/image_cell/abi/README.md: -------------------------------------------------------------------------------- 1 | # Generate `image_cell_abi.json` 2 | 3 | Ethereum contract ABI is generated by [hardhat](https://hardhat.org/tutorial/writing-and-compiling-contracts). 4 | 5 | ``` 6 | cd ../contract 7 | yarn 8 | npx hardhat compile 9 | ``` 10 | 11 | Then you will find that ABI is in file `artifacts/contracts/ImageCell.sol/ImageCell.json`. Find the key `abi` and copy its value to file `image_cell_abi.json`. 12 | 13 | # Generate `image_cell_abi.rs` 14 | 15 | `image_cell_abi.rs` is generated by [abigen macro](https://docs.rs/ethers-contract/0.2.2/ethers_contract/macro.abigen.html) or the [Abigen builder](https://docs.rs/ethers-contract/0.2.2/ethers_contract/macro.abigen.html), and they can both accept `image_cell_abi.json` as input. 16 | -------------------------------------------------------------------------------- /core/executor/src/system_contract/image_cell/abi/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod image_cell_abi; 2 | 3 | use ckb_types::{packed, prelude::Unpack}; 4 | 5 | use protocol::types::OutPoint; 6 | 7 | impl From for image_cell_abi::OutPoint { 8 | fn from(value: OutPoint) -> Self { 9 | image_cell_abi::OutPoint { 10 | tx_hash: value.tx_hash.0, 11 | index: value.index, 12 | } 13 | } 14 | } 15 | 16 | impl From for image_cell_abi::CellOutput { 17 | fn from(value: packed::CellOutput) -> Self { 18 | image_cell_abi::CellOutput { 19 | capacity: value.capacity().unpack(), 20 | lock: value.lock().into(), 21 | type_: value 22 | .type_() 23 | .to_opt() 24 | .map(|v| vec![v.into()]) 25 | .unwrap_or_default(), 26 | } 27 | } 28 | } 29 | 30 | impl From for image_cell_abi::Script { 31 | fn from(value: packed::Script) -> Self { 32 | let args: Vec = value.args().unpack(); 33 | 34 | image_cell_abi::Script { 35 | code_hash: value.code_hash().unpack().0, 36 | hash_type: value.hash_type().into(), 37 | args: args.into(), 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/executor/src/tests/system_script/ckb_lc_and_ic.rs: -------------------------------------------------------------------------------- 1 | use super::{ckb_light_client, image_cell}; 2 | 3 | #[test] 4 | fn test_ckb_light_client_and_image_cell() { 5 | ckb_light_client::test_write_functions(); 6 | image_cell::test_write_functions(); 7 | } 8 | -------------------------------------------------------------------------------- /core/executor/src/tests/system_script/mod.rs: -------------------------------------------------------------------------------- 1 | mod ckb_lc_and_ic; 2 | mod ckb_light_client; 3 | mod image_cell; 4 | mod metadata; 5 | mod native_token; 6 | -------------------------------------------------------------------------------- /core/interoperation/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-interoperation" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | arc-swap = "1.5" 10 | ckb-chain-spec = "0.111" 11 | ckb-error = "0.111" 12 | ckb-script = "0.111" 13 | ckb-traits = "0.111" 14 | ckb-types = "0.111" 15 | ckb-vm = { version = "=0.24.6", features = ["asm"] } 16 | lazy_static = "1.4" 17 | log = "0.4" 18 | 19 | protocol = { path = "../../protocol", package = "axon-protocol", default-features = false } 20 | 21 | [dev-dependencies] 22 | cardano-serialization-lib = "7.0" 23 | cardano-message-signing = { git = "https://github.com/ashuralyk/message-signing", branch = "rust" } 24 | ckb-jsonrpc-types = "0.111" 25 | ed25519-dalek = "1.0" 26 | ethers-core = "2.0" 27 | serde_json = "1.0" 28 | 29 | core-rpc-client = { path = "../../core/rpc-client" } 30 | core-executor = { path = "../../core/executor" } 31 | core-storage = { path = "../../core/storage" } 32 | core-db = { path = "../../core/db" } 33 | -------------------------------------------------------------------------------- /core/mempool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-mempool" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | ckb-types = "0.111" 9 | crossbeam-queue = "0.3" 10 | dashmap = { version = "5.5", features = ["rayon"] } 11 | futures = { version = "0.3", features = ["async-await"] } 12 | log = "0.4" 13 | parking_lot = "0.12" 14 | rlp = "0.5" 15 | rlp-derive = "0.1" 16 | 17 | common-apm = { path = "../../common/apm" } 18 | common-apm-derive = { path = "../../common/apm-derive" } 19 | common-config-parser = { path = "../../common/config-parser" } 20 | common-crypto = { path = "../../common/crypto" } 21 | core-executor = { path = "../../core/executor" } 22 | core-interoperation = { path = "../../core/interoperation" } 23 | core-network = { path = "../../core/network" } 24 | protocol = { path = "../../protocol", package = "axon-protocol" } 25 | 26 | [dev-dependencies] 27 | criterion = { version = "0.5", features = ["async_tokio"] } 28 | parking_lot = "0.12" 29 | 30 | [[bench]] 31 | harness = false 32 | name = "bench" 33 | -------------------------------------------------------------------------------- /core/mempool/src/context.rs: -------------------------------------------------------------------------------- 1 | use protocol::traits::Context; 2 | 3 | const TXS_ORIGINAL_KEY: &str = "txs_original"; 4 | const NETWORK_TXS: usize = 1; 5 | 6 | pub(crate) trait TxContext { 7 | fn mark_network_origin_new_txs(&self) -> Self; 8 | 9 | fn is_network_origin_txs(&self) -> bool; 10 | } 11 | 12 | impl TxContext for Context { 13 | fn mark_network_origin_new_txs(&self) -> Self { 14 | self.with_value::(TXS_ORIGINAL_KEY, NETWORK_TXS) 15 | } 16 | 17 | fn is_network_origin_txs(&self) -> bool { 18 | self.get::(TXS_ORIGINAL_KEY) == Some(&NETWORK_TXS) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/network/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-network" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | bloom-filters = "0.1" 9 | derive_more = "0.99" 10 | faketime = "0.2" 11 | futures = "0.3" 12 | ipnetwork = "0.20" 13 | log = "0.4" 14 | parking_lot = "0.12" 15 | prost = "0.11" 16 | rlp = "0.5" 17 | serde = { version = "1.0", features = ["derive"] } 18 | serde_json = "1.0" 19 | snap = "1.0" 20 | socket2 = "0.4" 21 | tentacle = { version = "0.5.0-alpha.1", features = ["parking_lot", "secio-async-trait"] } 22 | tokio-util = { version = "0.7", features = ["codec"] } 23 | 24 | common-apm = { path = "../../common/apm" } 25 | common-apm-derive = { path = "../../common/apm-derive" } 26 | common-config-parser = { path = "../../common/config-parser" } 27 | protocol = { path = "../../protocol", package = "axon-protocol" } 28 | 29 | [dev-dependencies] 30 | env_logger = "0.10" 31 | -------------------------------------------------------------------------------- /core/network/src/common.rs: -------------------------------------------------------------------------------- 1 | use derive_more::Display; 2 | use serde::{Deserialize, Serialize}; 3 | use tentacle::multiaddr::Multiaddr; 4 | 5 | #[derive(Debug, Display, PartialEq, Eq, Serialize, Deserialize, Clone, Hash)] 6 | #[display(fmt = "{}:{}", host, port)] 7 | pub struct ConnectedAddr { 8 | pub host: String, 9 | pub port: u16, 10 | } 11 | 12 | impl From<&Multiaddr> for ConnectedAddr { 13 | fn from(multiaddr: &Multiaddr) -> Self { 14 | use tentacle::multiaddr::Protocol::{Dns4, Dns6, Ip4, Ip6, Tcp, Tls}; 15 | 16 | let mut host = None; 17 | let mut port = 0u16; 18 | 19 | for comp in multiaddr.iter() { 20 | match comp { 21 | Ip4(ip_addr) => host = Some(ip_addr.to_string()), 22 | Ip6(ip_addr) => host = Some(ip_addr.to_string()), 23 | Dns4(dns_addr) | Dns6(dns_addr) => host = Some(dns_addr.to_string()), 24 | Tls(tls_addr) => host = Some(tls_addr.to_string()), 25 | Tcp(p) => port = p, 26 | _ => (), 27 | } 28 | } 29 | 30 | let host = host.unwrap_or_else(|| multiaddr.to_string()); 31 | ConnectedAddr { host, port } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/network/src/outbound/mod.rs: -------------------------------------------------------------------------------- 1 | mod gossip; 2 | mod rpc; 3 | pub use gossip::NetworkGossip; 4 | pub use rpc::NetworkRpc; 5 | -------------------------------------------------------------------------------- /core/network/src/protocols/feeler.rs: -------------------------------------------------------------------------------- 1 | use crate::peer_manager::PeerManager; 2 | use std::sync::Arc; 3 | use tentacle::{ 4 | async_trait, 5 | context::{ProtocolContext, ProtocolContextMutRef}, 6 | traits::ServiceProtocol, 7 | }; 8 | 9 | /// Feeler 10 | /// Currently do nothing, CKBProtocol auto refresh peer_store after connected. 11 | pub struct Feeler { 12 | network_state: Arc, 13 | } 14 | 15 | impl Feeler { 16 | pub fn new(network_state: Arc) -> Self { 17 | Feeler { network_state } 18 | } 19 | } 20 | 21 | #[async_trait] 22 | impl ServiceProtocol for Feeler { 23 | async fn init(&mut self, _context: &mut ProtocolContext) {} 24 | 25 | async fn connected(&mut self, context: ProtocolContextMutRef<'_>, _: &str) { 26 | let session = context.session; 27 | if context.session.ty.is_outbound() { 28 | self.network_state.with_peer_store_mut(|peer_store| { 29 | peer_store.add_outbound_addr(session.address.clone()); 30 | }); 31 | } 32 | 33 | log::debug!("peer={} FeelerProtocol.connected", session.address); 34 | if let Err(err) = context.control().disconnect(session.id).await { 35 | log::debug!("Disconnect failed {:?}, error: {:?}", session.id, err); 36 | } 37 | } 38 | 39 | async fn disconnected(&mut self, context: ProtocolContextMutRef<'_>) { 40 | let session = context.session; 41 | self.network_state.with_registry_mut(|reg| { 42 | reg.remove_feeler(&session.address); 43 | }); 44 | log::debug!("peer={} FeelerProtocol.disconnected", session.address); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/network/src/protocols/identify/protocol.rs: -------------------------------------------------------------------------------- 1 | use prost::Message; 2 | use std::convert::TryFrom; 3 | use tentacle::{ 4 | bytes::{Bytes, BytesMut}, 5 | multiaddr::Multiaddr, 6 | }; 7 | 8 | #[derive(Message)] 9 | pub struct AddressInfo { 10 | #[prost(bytes, repeated, tag = "1")] 11 | pub listen_addrs: Vec>, 12 | #[prost(bytes, tag = "2")] 13 | pub observed_addr: Vec, 14 | } 15 | 16 | impl AddressInfo { 17 | pub fn new(listen_addrs: Vec, observed_addr: Multiaddr) -> Self { 18 | AddressInfo { 19 | listen_addrs: listen_addrs.into_iter().map(|addr| addr.to_vec()).collect(), 20 | observed_addr: observed_addr.to_vec(), 21 | } 22 | } 23 | 24 | pub fn listen_addrs(&self) -> Vec { 25 | let addrs = self.listen_addrs.iter().cloned(); 26 | let to_multiaddrs = addrs.filter_map(|bytes| Multiaddr::try_from(bytes).ok()); 27 | to_multiaddrs.collect() 28 | } 29 | 30 | pub fn observed_addr(&self) -> Option { 31 | Multiaddr::try_from(self.observed_addr.clone()).ok() 32 | } 33 | } 34 | 35 | #[derive(Message)] 36 | pub struct Identity { 37 | #[prost(string, tag = "1")] 38 | pub chain_id: String, 39 | #[prost(message, tag = "2")] 40 | pub addr_info: Option, 41 | } 42 | 43 | impl Identity { 44 | pub fn new(chain_id: String, addr_info: AddressInfo) -> Self { 45 | Identity { 46 | chain_id, 47 | addr_info: Some(addr_info), 48 | } 49 | } 50 | 51 | pub fn into_bytes(self) -> Bytes { 52 | let mut buf = BytesMut::with_capacity(self.encoded_len()); 53 | self.encode(&mut buf).unwrap(); 54 | 55 | buf.freeze() 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/network/src/protocols/transmitter/protocol.rs: -------------------------------------------------------------------------------- 1 | use tentacle::{bytes::Bytes, secio::PeerId, SessionId}; 2 | 3 | #[derive(Debug)] 4 | pub struct ReceivedMessage { 5 | pub session_id: SessionId, 6 | pub peer_id: PeerId, 7 | pub data: Bytes, 8 | } 9 | -------------------------------------------------------------------------------- /core/network/src/rpc.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use protocol::types::{BufMut, Bytes, BytesMut}; 4 | 5 | #[derive(Debug, Deserialize, Serialize)] 6 | pub enum RpcResponse { 7 | Success(Bytes), 8 | Error(String), 9 | } 10 | 11 | impl RpcResponse { 12 | pub fn encode(&self) -> Bytes { 13 | match self { 14 | RpcResponse::Success(bytes) => { 15 | let mut b = BytesMut::with_capacity(bytes.len() + 1); 16 | b.put_u8(0); 17 | b.put(bytes.as_ref()); 18 | b.freeze() 19 | } 20 | RpcResponse::Error(e) => { 21 | let mut b = BytesMut::with_capacity(e.len() + 1); 22 | b.put_u8(1); 23 | b.put(e.as_bytes()); 24 | b.freeze() 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/rpc-client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-rpc-client" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | ckb-jsonrpc-types = "0.111" 9 | ckb-sdk = "3.0" 10 | ckb-types = "0.111" 11 | futures = "0.3" 12 | jsonrpc-core = "18.0" 13 | reqwest = { version = "0.11", features = ["json"] } 14 | serde = { version = "1.0", features = ["derive"] } 15 | serde_json = "1.0" 16 | 17 | protocol = { path = "../../protocol", package = "axon-protocol" } 18 | -------------------------------------------------------------------------------- /core/rpc-client/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod client; 2 | 3 | pub use client::RpcClient; 4 | -------------------------------------------------------------------------------- /core/run/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core-run" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | backtrace = "0.3" 9 | ethers-core = "2.0" 10 | futures = "0.3" 11 | log = "0.4" 12 | rlp = "0.5" 13 | serde = "1.0" 14 | serde_derive = "1.0" 15 | serde_json = "1.0" 16 | toml = "0.8" 17 | 18 | common-apm = { path = "../../common/apm" } 19 | common-apm-derive = { path = "../../common/apm-derive" } 20 | common-config-parser = { path = "../../common/config-parser" } 21 | common-crypto = { path = "../../common/crypto" } 22 | common-logger = { path = "../../common/logger" } 23 | common-memory-tracker = { path = "../../common/memory-tracker", optional = true } 24 | core-api = { path = "../../core/api" } 25 | core-consensus = { path = "../../core/consensus" } 26 | core-db = { path = "../../core/db" } 27 | core-executor = { path = "../../core/executor" } 28 | core-interoperation = { path = "../../core/interoperation" } 29 | core-mempool = { path = "../../core/mempool" } 30 | core-network = { path = "../../core/network" } 31 | core-rpc-client = { path = "../../core/rpc-client" } 32 | core-storage = { path = "../../core/storage" } 33 | protocol = { path = "../../protocol", package = "axon-protocol" } 34 | 35 | [target.'cfg(all(not(target_env = "msvc"), not(target_os="macos")))'.dependencies] 36 | jemalloc-ctl = { version = "0.5", package = "tikv-jemalloc-ctl", optional = true } 37 | jemallocator = { version = "0.5", features = ["profiling", "stats", "unprefixed_malloc_on_supported_platforms"], package = "tikv-jemallocator", optional = true } 38 | 39 | [dev-dependencies] 40 | clap = "4.4" 41 | hasher = "0.1" 42 | tempfile = "3.6" 43 | 44 | [features] 45 | jemalloc = ["dep:jemallocator", "dep:jemalloc-ctl", "dep:common-memory-tracker"] 46 | -------------------------------------------------------------------------------- /core/run/src/components/chain_spec.rs: -------------------------------------------------------------------------------- 1 | use common_config_parser::types::spec::ChainSpec; 2 | 3 | use protocol::constants::BASE_FEE_PER_GAS; 4 | use protocol::types::{ 5 | Block, Eip1559Transaction, RichBlock, TransactionAction, UnsignedTransaction, 6 | }; 7 | 8 | pub(crate) trait ChainSpecExt { 9 | //! Generate the genesis block. 10 | fn generate_genesis_block(&self) -> RichBlock; 11 | } 12 | 13 | impl ChainSpecExt for ChainSpec { 14 | fn generate_genesis_block(&self) -> RichBlock { 15 | let txs = vec![]; 16 | let block = Block { 17 | header: self.genesis.build_header(), 18 | tx_hashes: vec![], 19 | }; 20 | 21 | RichBlock { block, txs } 22 | } 23 | } 24 | 25 | #[allow(dead_code)] 26 | fn build_unverified_transaction( 27 | nonce: u64, 28 | action: TransactionAction, 29 | data: Vec, 30 | ) -> UnsignedTransaction { 31 | let tx = Eip1559Transaction { 32 | nonce: nonce.into(), 33 | max_priority_fee_per_gas: BASE_FEE_PER_GAS.into(), 34 | gas_price: 0u64.into(), 35 | gas_limit: 30000000u64.into(), 36 | value: 0u64.into(), 37 | data: data.into(), 38 | access_list: vec![], 39 | action, 40 | }; 41 | UnsignedTransaction::Eip1559(tx) 42 | } 43 | -------------------------------------------------------------------------------- /core/run/src/components/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod chain_spec; 2 | pub(crate) mod extensions; 3 | pub(crate) mod network; 4 | pub(crate) mod storage; 5 | pub(crate) mod system; 6 | 7 | #[cfg(all( 8 | not(target_env = "msvc"), 9 | not(target_os = "macos"), 10 | feature = "jemalloc" 11 | ))] 12 | pub(crate) mod profiling; 13 | 14 | #[cfg(not(all( 15 | not(target_env = "msvc"), 16 | not(target_os = "macos"), 17 | feature = "jemalloc" 18 | )))] 19 | pub(crate) mod profiling { 20 | use std::sync::Arc; 21 | 22 | pub(crate) fn start() { 23 | log::warn!("profiling is not supported, so it doesn't start"); 24 | } 25 | pub(crate) fn stop() { 26 | log::warn!("profiling is not supported, so it doesn't require stopping"); 27 | } 28 | pub(crate) fn track_current_process() { 29 | log::warn!("profiling is not supported, so it doesn't track current process"); 30 | } 31 | pub(crate) fn track_db_process(typ: &str, _db: &Arc) { 32 | log::warn!("profiling is not supported, so it doesn't track db process for [{typ}]"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/run/src/components/profiling.rs: -------------------------------------------------------------------------------- 1 | //! Control the profiling related features. 2 | 3 | use std::sync::Arc; 4 | 5 | use common_memory_tracker::{GetColumnFamilys, GetProperty, GetPropertyCF}; 6 | use jemalloc_ctl::{Access, AsName}; 7 | use jemallocator::Jemalloc; 8 | use protocol::tokio; 9 | 10 | #[global_allocator] 11 | pub static JEMALLOC: Jemalloc = Jemalloc; 12 | 13 | pub(crate) fn start() { 14 | set_profile(true); 15 | } 16 | 17 | pub(crate) fn stop() { 18 | set_profile(false); 19 | dump_profile(); 20 | } 21 | 22 | pub(crate) fn track_current_process() { 23 | tokio::spawn(common_memory_tracker::track_current_process()); 24 | } 25 | 26 | pub(crate) fn track_db_process(typ: &'static str, db_ref: &Arc) 27 | where 28 | DB: GetColumnFamilys + GetProperty + GetPropertyCF + Send + Sync + 'static, 29 | { 30 | let db = Arc::clone(db_ref); 31 | tokio::spawn(common_memory_tracker::track_db_process::(typ, db)); 32 | } 33 | 34 | fn set_profile(is_active: bool) { 35 | let _ = b"prof.active\0" 36 | .name() 37 | .write(is_active) 38 | .map_err(|e| panic!("Set jemalloc profile error {:?}", e)); 39 | } 40 | 41 | fn dump_profile() { 42 | let name = b"profile.out\0".as_ref(); 43 | b"prof.dump\0" 44 | .name() 45 | .write(name) 46 | .expect("Should succeed to dump profile") 47 | } 48 | -------------------------------------------------------------------------------- /core/run/src/error.rs: -------------------------------------------------------------------------------- 1 | use protocol::{Display, From, ProtocolError, ProtocolErrorKind}; 2 | 3 | #[derive(Debug, Display, From)] 4 | pub enum MainError { 5 | #[display(fmt = "The axon configuration read failed {:?}", _0)] 6 | ConfigParse(common_config_parser::ParseError), 7 | 8 | #[display(fmt = "{:?}", _0)] 9 | Io(std::io::Error), 10 | 11 | #[display(fmt = "Toml fails to parse genesis {:?}", _0)] 12 | GenesisTomlDe(toml::de::Error), 13 | 14 | #[display(fmt = "crypto error {:?}", _0)] 15 | Crypto(common_crypto::Error), 16 | 17 | #[display(fmt = "{:?}", _0)] 18 | Utf8(std::string::FromUtf8Error), 19 | 20 | #[display(fmt = "{:?}", _0)] 21 | JSONParse(serde_json::error::Error), 22 | 23 | #[display(fmt = "other error {:?}", _0)] 24 | Other(String), 25 | } 26 | 27 | impl std::error::Error for MainError {} 28 | 29 | impl From for ProtocolError { 30 | fn from(error: MainError) -> ProtocolError { 31 | ProtocolError::new(ProtocolErrorKind::Main, Box::new(error)) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/storage/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = "2021" 3 | name = "core-storage" 4 | version = "0.1.0" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | arc-swap = "1.6" 9 | futures = "0.3" 10 | lazy_static = "1.4" 11 | log = "0.4" 12 | lru = "0.12" 13 | parking_lot = "0.12" 14 | 15 | common-apm = { path = "../../common/apm" } 16 | common-apm-derive = { path = "../../common/apm-derive" } 17 | core-db ={ path = "../../core/db" } 18 | protocol = { path = "../../protocol", package = "axon-protocol" } 19 | 20 | [dev-dependencies] 21 | common-crypto = { path = "../../common/crypto" } 22 | criterion = "0.5" 23 | num-traits = "0.2" 24 | 25 | [[bench]] 26 | harness = false 27 | name = "bench" 28 | -------------------------------------------------------------------------------- /core/storage/src/cache.rs: -------------------------------------------------------------------------------- 1 | use std::num::NonZeroUsize; 2 | 3 | use lru::LruCache; 4 | use parking_lot::Mutex; 5 | 6 | use protocol::types::{Block, Bytes, Hash, Header, Receipt, SignedTransaction}; 7 | 8 | #[derive(Debug)] 9 | pub struct StorageCache { 10 | pub blocks: Mutex>, 11 | pub block_numbers: Mutex>, 12 | pub headers: Mutex>, 13 | pub transactions: Mutex>, 14 | pub codes: Mutex>, 15 | pub receipts: Mutex>, 16 | } 17 | 18 | impl StorageCache { 19 | pub fn new(size: usize) -> Self { 20 | let size = NonZeroUsize::new(size).unwrap(); 21 | StorageCache { 22 | blocks: Mutex::new(LruCache::new(size)), 23 | block_numbers: Mutex::new(LruCache::new(size)), 24 | headers: Mutex::new(LruCache::new(size)), 25 | transactions: Mutex::new(LruCache::new(size)), 26 | codes: Mutex::new(LruCache::new(size)), 27 | receipts: Mutex::new(LruCache::new(size)), 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/storage/src/schema.rs: -------------------------------------------------------------------------------- 1 | use protocol::traits::{StorageCategory, StorageSchema}; 2 | use protocol::types::{ 3 | Block, Bytes, DBBytes, HardforkInfoInner, Hash, Header, Proof, Receipt, SignedTransaction, 4 | }; 5 | 6 | use crate::hash_key::{BlockKey, CommonHashKey}; 7 | 8 | macro_rules! impl_storage_schema_for { 9 | ($name: ident, $key: ty, $val: ty, $category: ident) => { 10 | pub struct $name; 11 | 12 | impl StorageSchema for $name { 13 | type Key = $key; 14 | type Value = $val; 15 | 16 | fn category() -> StorageCategory { 17 | StorageCategory::$category 18 | } 19 | } 20 | }; 21 | } 22 | 23 | impl_storage_schema_for!( 24 | TransactionSchema, 25 | CommonHashKey, 26 | SignedTransaction, 27 | SignedTransaction 28 | ); 29 | impl_storage_schema_for!( 30 | TransactionBytesSchema, 31 | CommonHashKey, 32 | DBBytes, 33 | SignedTransaction 34 | ); 35 | impl_storage_schema_for!(BlockSchema, BlockKey, Block, Block); 36 | impl_storage_schema_for!(BlockHeaderSchema, BlockKey, Header, BlockHeader); 37 | impl_storage_schema_for!(BlockHashNumberSchema, Hash, u64, HashHeight); 38 | impl_storage_schema_for!(ReceiptSchema, CommonHashKey, Receipt, Receipt); 39 | impl_storage_schema_for!(ReceiptBytesSchema, CommonHashKey, DBBytes, Receipt); 40 | impl_storage_schema_for!(TxHashNumberSchema, Hash, u64, HashHeight); 41 | impl_storage_schema_for!(LatestBlockSchema, Hash, Block, Block); 42 | impl_storage_schema_for!(LatestProofSchema, Hash, Proof, Block); 43 | impl_storage_schema_for!(OverlordWalSchema, Hash, Bytes, Wal); 44 | impl_storage_schema_for!(EvmCodeSchema, Hash, Bytes, Code); 45 | impl_storage_schema_for!(EvmCodeAddressSchema, Hash, Hash, Code); 46 | impl_storage_schema_for!(HardforkSchema, Hash, HardforkInfoInner, Version); 47 | -------------------------------------------------------------------------------- /devtools/abi-generator/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "abi-generator" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | clap = { version = "4.3", features = ["derive"] } 9 | ethers = "2.0" 10 | -------------------------------------------------------------------------------- /devtools/abi-generator/abi_generate.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | 4 | def main(): 5 | cmd_args = [ 6 | [ 7 | "MetadataContract", 8 | "../../core/executor/src/system_contract/metadata/abi/metadata_abi.json", 9 | "../../core/executor/src/system_contract/metadata/abi/metadata_abi.rs", 10 | ], 11 | [ 12 | "CkbLightClientContract", 13 | "../../core/executor/src/system_contract/ckb_light_client/abi/ckb_light_client_abi.json", 14 | "../../core/executor/src/system_contract/ckb_light_client/abi/ckb_light_client_abi.rs", 15 | ], 16 | [ 17 | "ImageCellContract", 18 | "../../core/executor/src/system_contract/image_cell/abi/image_cell_abi.json", 19 | "../../core/executor/src/system_contract/image_cell/abi/image_cell_abi.rs", 20 | ], 21 | ] 22 | cargo_run = "cargo run --".split(" ") 23 | for args in cmd_args: 24 | subprocess.Popen(cargo_run + ["-c", args[0], "-j", args[1], "-o", args[2]]) 25 | 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /devtools/abi-generator/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | 3 | use clap::Parser; 4 | use ethers::contract::Abigen; 5 | 6 | #[derive(Clone, Debug, Parser)] 7 | struct Args { 8 | #[arg(short = 'c', long)] 9 | contract_name: String, 10 | 11 | #[arg(short = 'j', long)] 12 | json_abi_path: String, 13 | 14 | #[arg(short = 'o', long)] 15 | output_file_path: String, 16 | } 17 | 18 | fn main() -> Result<(), Box> { 19 | let args = Args::parse(); 20 | Abigen::new(args.contract_name, args.json_abi_path)? 21 | .generate()? 22 | .write_to_file(args.output_file_path)?; 23 | Ok(()) 24 | } 25 | -------------------------------------------------------------------------------- /devtools/axon-tools/README.md: -------------------------------------------------------------------------------- 1 | This crate is used by forcerelay. 2 | - Data structures like Block, Proposal etc. 3 | - Block and Transaction verification APIs. -------------------------------------------------------------------------------- /devtools/axon-tools/src/consts.rs: -------------------------------------------------------------------------------- 1 | use ethereum_types::H160; 2 | 3 | pub const METADATA_CONTRACT_ADDRESS: H160 = H160([ 4 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 5 | 0xff, 0xff, 0xff, 0x01, 6 | ]); 7 | 8 | pub const CKB_LIGHT_CLIENT_CONTRACT_ADDRESS: H160 = H160([ 9 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 10 | 0xff, 0xff, 0xff, 0x02, 11 | ]); 12 | 13 | pub const IMAGE_CELL_CONTRACT_ADDRESS: H160 = H160([ 14 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 15 | 0xff, 0xff, 0xff, 0x03, 16 | ]); 17 | -------------------------------------------------------------------------------- /devtools/axon-tools/src/hash.rs: -------------------------------------------------------------------------------- 1 | use tiny_keccak::{Hasher, Keccak}; 2 | 3 | #[cfg(feature = "hash")] 4 | #[cfg_attr(doc_cfg, doc(cfg(feature = "hash")))] 5 | pub fn keccak_256(data: &[u8]) -> [u8; 32] { 6 | let mut ret = [0u8; 32]; 7 | let mut hasher = Keccak::v256(); 8 | hasher.update(data); 9 | hasher.finalize(&mut ret); 10 | ret 11 | } 12 | 13 | #[derive(Default)] 14 | pub(crate) struct InnerKeccak; 15 | 16 | #[cfg(all(feature = "proof", feature = "std"))] 17 | impl cita_trie::Hasher for InnerKeccak { 18 | const LENGTH: usize = 32; 19 | 20 | fn digest(&self, data: &[u8]) -> Vec { 21 | keccak_256(data).to_vec() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /devtools/axon-tools/src/hex.rs: -------------------------------------------------------------------------------- 1 | use alloc::string::String; 2 | use alloc::vec; 3 | use alloc::vec::Vec; 4 | 5 | use crate::Error; 6 | 7 | pub fn hex_encode>(src: T) -> String { 8 | faster_hex::hex_string(src.as_ref()) 9 | } 10 | 11 | pub fn hex_decode(src: &str) -> Result, Error> { 12 | if src.is_empty() { 13 | return Ok(Vec::new()); 14 | } 15 | 16 | let src = if src.starts_with("0x") { 17 | src.split_at(2).1 18 | } else { 19 | src 20 | }; 21 | 22 | let src = src.as_bytes(); 23 | let mut ret = vec![0u8; src.len() / 2]; 24 | faster_hex::hex_decode(src, &mut ret)?; 25 | 26 | Ok(ret) 27 | } 28 | -------------------------------------------------------------------------------- /devtools/axon-tools/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | // #![no_std] 3 | #![cfg_attr(doc_cfg, feature(doc_cfg))] 4 | 5 | extern crate alloc; 6 | 7 | mod error; 8 | #[cfg(feature = "hash")] 9 | pub mod hash; 10 | #[cfg(feature = "hex")] 11 | #[cfg_attr(doc_cfg, doc(cfg(feature = "hex")))] 12 | pub mod hex; 13 | #[cfg(feature = "precompile")] 14 | pub mod precompile; 15 | #[cfg(feature = "proof")] 16 | mod proof; 17 | #[cfg(feature = "impl-rlp")] 18 | mod rlp_codec; 19 | pub mod types; 20 | 21 | pub use error::Error; 22 | 23 | #[cfg(feature = "proof")] 24 | #[cfg_attr(doc_cfg, doc(cfg(feature = "proof")))] 25 | pub use proof::verify_proof; 26 | 27 | #[cfg(all(feature = "proof", feature = "std"))] 28 | pub use proof::verify_trie_proof; 29 | 30 | #[cfg(feature = "hash")] 31 | #[cfg_attr(doc_cfg, doc(cfg(feature = "hash")))] 32 | pub use hash::keccak_256; 33 | 34 | pub mod consts; 35 | 36 | #[cfg(test)] 37 | mod tests; 38 | -------------------------------------------------------------------------------- /devtools/axon-tools/src/rlp_codec.rs: -------------------------------------------------------------------------------- 1 | use crate::types::BlockVersion; 2 | #[cfg(feature = "proof")] 3 | use crate::types::{Proposal, Vote}; 4 | use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; 5 | 6 | impl Encodable for BlockVersion { 7 | fn rlp_append(&self, s: &mut RlpStream) { 8 | let ver: u8 = (*self).into(); 9 | s.begin_list(1).append(&ver); 10 | } 11 | } 12 | 13 | impl Decodable for BlockVersion { 14 | fn decode(r: &Rlp) -> Result { 15 | let ver: u8 = r.val_at(0)?; 16 | ver.try_into() 17 | .map_err(|_| DecoderError::Custom("Invalid block version")) 18 | } 19 | } 20 | 21 | #[cfg(feature = "proof")] 22 | impl Encodable for Vote { 23 | fn rlp_append(&self, s: &mut RlpStream) { 24 | let vote_type: u8 = self.vote_type; 25 | s.begin_list(4) 26 | .append(&self.height) 27 | .append(&self.round) 28 | .append(&vote_type) 29 | .append(&self.proposal_hash.to_vec()); 30 | } 31 | } 32 | 33 | #[cfg(feature = "proof")] 34 | impl Encodable for Proposal { 35 | fn rlp_append(&self, s: &mut RlpStream) { 36 | s.begin_list(13) 37 | .append(&self.version) 38 | .append(&self.prev_hash) 39 | .append(&self.proposer) 40 | .append(&self.prev_state_root) 41 | .append(&self.transactions_root) 42 | .append(&self.signed_txs_hash) 43 | .append(&self.timestamp) 44 | .append(&self.number) 45 | .append(&self.gas_limit.low_u64()) 46 | .append_list(&self.extra_data) 47 | .append(&self.proof) 48 | .append(&self.call_system_script_count) 49 | .append_list(&self.tx_hashes); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /devtools/axon-tools/src/tests/mod.rs: -------------------------------------------------------------------------------- 1 | mod verify_proof; 2 | mod verify_trie_proof; 3 | -------------------------------------------------------------------------------- /devtools/axon-tools/src/tests/proof.json: -------------------------------------------------------------------------------- 1 | { 2 | "number": "0xe7c3", 3 | "round": "0x0", 4 | "proposal_hash": "0x6e48fa2d2002453abd9b51e4ac0342abb1f027b8272d6e27ce79a630b3f26673", 5 | "signature": "0xb3e8e27db04baec18c04bc0b8ffe7fdbf2b5f7d6ef243c8be02bfd75defee32f1c0ff73a9fa67fee24630d2da5aa70f111ba41c0212be5d91b95f3bb84e5c0406b4742cca8c8f8362c07024fd8081d16875b01f43c6aa11c60b196af8c671a9b", 6 | "bitmap": "0x70" 7 | } 8 | -------------------------------------------------------------------------------- /devtools/chain/blockscan-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/blockscan-screenshot.png -------------------------------------------------------------------------------- /devtools/chain/bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/bls.key -------------------------------------------------------------------------------- /devtools/chain/default.db-options: -------------------------------------------------------------------------------- 1 | # This is a RocksDB option file. 2 | # 3 | # For detailed file format spec, please refer to the official documents 4 | # in https://rocksdb.org/docs/ 5 | # 6 | 7 | [DBOptions] 8 | bytes_per_sync=1048576 9 | max_background_compactions=4 10 | max_background_flushes=2 11 | max_total_wal_size=134217728 12 | keep_log_file_num=32 13 | 14 | [CFOptions "default"] 15 | level_compaction_dynamic_level_bytes=true 16 | write_buffer_size=8388608 17 | min_write_buffer_number_to_merge=1 18 | max_write_buffer_number=2 19 | max_write_buffer_size_to_maintain=-1 20 | 21 | [TableOptions/BlockBasedTable "default"] 22 | cache_index_and_filter_blocks=true 23 | pin_l0_filter_and_index_blocks_in_cache=true 24 | -------------------------------------------------------------------------------- /devtools/chain/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | axon: 5 | image: ghcr.io/axonweb3/axon:dev 6 | ports: 7 | - 8000:8000 8 | - 127.0.0.1:8100:8100 9 | networks: 10 | - axon-net 11 | restart: unless-stopped 12 | # https://docs.docker.com/compose/compose-file/05-services/#healthcheck 13 | healthcheck: 14 | test: /app/devtools/docker/health_check.sh 15 | start_period: 10s 16 | timeout: 62s 17 | # CMD: see https://github.com/axonweb3/axon/blob/dev/devtools/docker/docker-entrypoint.sh 18 | 19 | explorer: 20 | container_name: blockscan 21 | # TODO: update blockscan image 22 | # Dockerfile: https://github.com/Simon-Tl/blockscan/blob/a60dd45ca8577f97683f89c8a372508a84b74e24/docker/Dockerfile#L56 23 | image: ghcr.io/simon-tl/blockscan:latest 24 | depends_on: 25 | - axon 26 | - explorer-db 27 | env_file: 28 | - ./blockscan-explorer.env 29 | ports: 30 | - 4020:4020 31 | networks: 32 | - axon-net 33 | restart: unless-stopped 34 | command: sh -c "bin/blockscout eval \"Elixir.Explorer.ReleaseTasks.create_and_migrate()\" && bin/blockscout start" 35 | 36 | explorer-db: 37 | container_name: postgres 38 | image: postgres:15.2 39 | environment: 40 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-b%rnGL8ps} 41 | POSTGRES_USER: ${POSTGRES_USER:-blockscan} 42 | expose: 43 | - 5432 44 | networks: 45 | - axon-net 46 | restart: unless-stopped 47 | command: postgres -c 'max_connections=250' 48 | 49 | networks: 50 | axon-net: 51 | -------------------------------------------------------------------------------- /devtools/chain/k8s/node_1_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_1_bls.key -------------------------------------------------------------------------------- /devtools/chain/k8s/node_1_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_1_net.key -------------------------------------------------------------------------------- /devtools/chain/k8s/node_2_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_2_bls.key -------------------------------------------------------------------------------- /devtools/chain/k8s/node_2_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_2_net.key -------------------------------------------------------------------------------- /devtools/chain/k8s/node_3_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_3_bls.key -------------------------------------------------------------------------------- /devtools/chain/k8s/node_3_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_3_net.key -------------------------------------------------------------------------------- /devtools/chain/k8s/node_4_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_4_bls.key -------------------------------------------------------------------------------- /devtools/chain/k8s/node_4_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/k8s/node_4_net.key -------------------------------------------------------------------------------- /devtools/chain/net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/net.key -------------------------------------------------------------------------------- /devtools/chain/nodes/default.db-options: -------------------------------------------------------------------------------- 1 | # This is a RocksDB option file. 2 | # 3 | # For detailed file format spec, please refer to the official documents 4 | # in https://rocksdb.org/docs/ 5 | # 6 | 7 | [DBOptions] 8 | bytes_per_sync=1048576 9 | max_background_compactions=4 10 | max_background_flushes=2 11 | max_total_wal_size=134217728 12 | keep_log_file_num=32 13 | 14 | [CFOptions "default"] 15 | level_compaction_dynamic_level_bytes=true 16 | write_buffer_size=8388608 17 | min_write_buffer_number_to_merge=1 18 | max_write_buffer_number=2 19 | max_write_buffer_size_to_maintain=-1 20 | 21 | [TableOptions/BlockBasedTable "default"] 22 | cache_index_and_filter_blocks=true 23 | pin_l0_filter_and_index_blocks_in_cache=true 24 | -------------------------------------------------------------------------------- /devtools/chain/nodes/node_1_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_1_bls.key -------------------------------------------------------------------------------- /devtools/chain/nodes/node_1_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_1_net.key -------------------------------------------------------------------------------- /devtools/chain/nodes/node_2_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_2_bls.key -------------------------------------------------------------------------------- /devtools/chain/nodes/node_2_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_2_net.key -------------------------------------------------------------------------------- /devtools/chain/nodes/node_3_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_3_bls.key -------------------------------------------------------------------------------- /devtools/chain/nodes/node_3_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_3_net.key -------------------------------------------------------------------------------- /devtools/chain/nodes/node_4_bls.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_4_bls.key -------------------------------------------------------------------------------- /devtools/chain/nodes/node_4_net.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/devtools/chain/nodes/node_4_net.key -------------------------------------------------------------------------------- /devtools/ci/ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | host_key_checking = False 3 | inventory = hosts 4 | -------------------------------------------------------------------------------- /devtools/ci/ansible/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: "{{ hostname }}" 3 | remote_user: ec2-user 4 | become: yes 5 | become_method: sudo 6 | vars_files: 7 | - config.yml 8 | tasks: 9 | - name: Install git && docker 10 | shell: sudo yum install git docker -y && sudo service docker start 11 | become: yes 12 | become_method: sudo 13 | tags: 14 | - build 15 | - name: Pull code 16 | git: 17 | repo: "https://github.com/axonweb3/axon.git" 18 | dest: "axon" 19 | version: "main" 20 | force: yes 21 | become: yes 22 | become_method: sudo 23 | tags: 24 | - build 25 | 26 | - name: docker build 27 | shell: cd axon && docker build -t axonweb3/axon:{{ image_tag }} . 28 | become: yes 29 | become_method: sudo 30 | tags: 31 | - build 32 | 33 | 34 | - name: docker login and push image 35 | shell: docker login -u {{ docker_user }} -p {{ docker_password }} && docker push axonweb3/axon:{{ image_tag }} 36 | become: yes 37 | become_method: sudo 38 | tags: 39 | - build 40 | -------------------------------------------------------------------------------- /devtools/ci/scripts/helper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the number of most recent block 3 | * 4 | * cmd: 5 | * curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params": [],"id":2}' 6 | * 7 | * @param {String} rpcUrl default to http://localhost:8000 8 | * @returns {Number} the current block number the client is on. 9 | */ 10 | async function getLatestBlockNum(rpcUrl) { 11 | const rawResponse = await fetch(rpcUrl || 'http://localhost:8000', { 12 | method: 'POST', 13 | headers: { 14 | 'Content-Type': 'application/json' 15 | }, 16 | body: '{"jsonrpc":"2.0", "method":"eth_blockNumber", "params": [], "id":42}' 17 | }); 18 | const content = await rawResponse.json(); 19 | 20 | const tipBlockNumber = Number(content.result); 21 | return tipBlockNumber; 22 | } 23 | 24 | const asyncSleep = (ms = 0) => { 25 | return new Promise((r) => setTimeout(r, ms)); 26 | }; 27 | 28 | /** 29 | * wait N blocks passed 30 | * 31 | * @param {string} [rpcUrl] 32 | * @param {number} [waitBlocks=1] 33 | * @param {undefined} [start=undefined] 34 | */ 35 | async function waitXBlocksPassed(rpcUrl, waitBlocks = 2, start = undefined) { 36 | let curBlockNum = await getLatestBlockNum(rpcUrl); 37 | const startBlockNum = start || curBlockNum; 38 | const endBlockNum = startBlockNum + waitBlocks; 39 | 40 | while (curBlockNum < endBlockNum) { 41 | console.log(`The current block number is ${curBlockNum}`) 42 | console.log(`Wait until Block#${endBlockNum} produced...`); 43 | await asyncSleep(2000); 44 | curBlockNum = await getLatestBlockNum(rpcUrl); 45 | } 46 | } 47 | 48 | module.exports = { getLatestBlockNum, waitXBlocksPassed }; 49 | -------------------------------------------------------------------------------- /devtools/ci/terraform/.gitignore: -------------------------------------------------------------------------------- 1 | /.terraform 2 | /terraform.tfstate 3 | /terraform.tfstate.backup 4 | /terraform.tfvars 5 | -------------------------------------------------------------------------------- /devtools/ci/terraform/README.md: -------------------------------------------------------------------------------- 1 | # Terraform Configuration Files Used For Build arm64 image Workflow 2 | 3 | These Terraform configuration files are part of the ["Build arm64 image" workflow](../../../.github/workflows/build-arm64-image.yml). 4 | 5 | ## AMI 6 | 7 | Read [`ami.tf`](./ami.tf) 8 | 9 | ## Variables 10 | 11 | Read [`variables.tf`](./variables.tf) 12 | 13 | ## Resources 14 | 15 | * instances nodes named `"instance-*"` 16 | * `aws_vpc` 17 | * `aws_key_pair` 18 | 19 | ## Outputs 20 | 21 | * [`ansible_hosts`](./main.tf#L101) 22 | -------------------------------------------------------------------------------- /devtools/ci/terraform/ami.tf: -------------------------------------------------------------------------------- 1 | data "aws_ami" "amazon2" { 2 | most_recent = true 3 | 4 | filter { 5 | name = "name" 6 | values = ["amzn2-ami-*-hvm-*-arm64-gp2"] 7 | } 8 | 9 | filter { 10 | name = "architecture" 11 | values = ["arm64"] 12 | } 13 | 14 | owners = ["amazon"] 15 | } 16 | -------------------------------------------------------------------------------- /devtools/ci/terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "access_key" { 2 | type = string 3 | description = "AWS access key" 4 | } 5 | 6 | variable "secret_key" { 7 | type = string 8 | description = "AWS secret key" 9 | } 10 | 11 | variable "region" { 12 | type = string 13 | default = "ap-southeast-1" 14 | description = "AWS region" 15 | } 16 | 17 | variable "public_key_path" { 18 | type = string 19 | description = "local path to ssh public key" 20 | } 21 | 22 | variable "private_key_path" { 23 | type = string 24 | description = "local path to ssh private key" 25 | } 26 | 27 | variable "prefix" { 28 | type = string 29 | description = "prefix attach to resource names" 30 | } 31 | 32 | variable "instance_type" { 33 | type = string 34 | default = "c6g.xlarge" 35 | } 36 | 37 | variable "username" { 38 | type = string 39 | default = "ec2-user" 40 | } 41 | 42 | variable "private_ip_prefix" { 43 | type = string 44 | default = "10.0.1" 45 | } 46 | -------------------------------------------------------------------------------- /devtools/ci/terraform/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | aws = "~> 2.53" 4 | null = "~> 2.1" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /devtools/docker/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BASE_DIR="/app/devtools/chain" 4 | DATA_DIR="${BASE_DIR}/data" 5 | CONFIG_FILE="${BASE_DIR}/config.toml" 6 | CHAIN_SPEC_FILE="${BASE_DIR}/specs/single_node/chain-spec.toml" 7 | 8 | if [ ! -e "${DATA_DIR}" ]; then 9 | /app/axon init --config "${CONFIG_FILE}" --chain-spec "${CHAIN_SPEC_FILE}" 10 | fi 11 | /app/axon run --config "${CONFIG_FILE}" 12 | -------------------------------------------------------------------------------- /devtools/docker/health_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | block_number() { 3 | block=$(curl -s 'http://127.0.0.1:8000' \ 4 | --header 'Content-Type: application/json' \ 5 | --data '{"jsonrpc":"2.0", "method":"eth_blockNumber", "params": [], "id":42}' | jq '.result' |xargs printf %d 0xF) 6 | echo $block 7 | } 8 | 9 | block_stats() { 10 | current_block=$(block_number) 11 | start_time=$(date +%s) 12 | wait_seconds=60 13 | 14 | while true; do 15 | latest_block=$(block_number) 16 | if [ $current_block -lt $latest_block ] 17 | then 18 | return 0 19 | fi 20 | 21 | current_time=$(date +%s) 22 | elapsed_seconds=$((current_time - start_time)) 23 | if [ $elapsed_seconds -ge $wait_seconds ] 24 | then 25 | break 26 | fi 27 | 28 | sleep 1 29 | done 30 | 31 | echo "block does not grow in one minute, please check" 32 | return 1 33 | } 34 | 35 | 36 | block_stats 37 | -------------------------------------------------------------------------------- /devtools/metadata-cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "metadata-cli" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [[bin]] 8 | name = "axon-metadata" 9 | path = "src/main.rs" 10 | 11 | [dependencies] 12 | anyhow = "1.0.75" 13 | axon-protocol = { path = "../../protocol" } 14 | axon-types = { git = "https://github.com/axonweb3/axon-contract.git", rev = "b82a843" } 15 | clap = { version = "4.4.6", features = ["derive"] } 16 | hex = "0.4.3" 17 | molecule = "0.7.5" 18 | serde = { version = "1.0.193", features = ["derive"] } 19 | serde_json = "1.0.108" 20 | serde_with = "3.4.0" 21 | toml = "0.8.2" 22 | -------------------------------------------------------------------------------- /devtools/metadata-cli/README.md: -------------------------------------------------------------------------------- 1 | # Metadata Cli 2 | 3 | Cli for working with axon metadata cell. 4 | 5 | ## Get Data 6 | 7 | Generate `MetadataCellData` from validators. 8 | 9 | Usage: 10 | 11 | From a chain spec file or input file: 12 | 13 | ```command 14 | $ axon-metadata get-data -i input.example.toml 15 | ``` 16 | 17 | ```command 18 | $ axon-metadata get-data -i chain-spec.toml 19 | ``` 20 | 21 | From JSONRPC metadata result: 22 | 23 | ```command 24 | $ curl 'https://rpc-alphanet-axon.ckbapp.dev/' --header 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"axon_getCurrentMetadata","id":3}' | jq '.result' | axon-metadata get-data -i /dev/stdin 25 | ``` 26 | 27 | ### Deploy the Metadata Cell 28 | 29 | After generating the cell data, you can deploy a metadata type-id cell with e.g. `ckb-cli wallet transfer` or `ckb-cli deploy`. 30 | 31 | ## Parse Data 32 | 33 | Parse `MetadataCellData` to get validators. 34 | 35 | Usage: 36 | 37 | ```command 38 | $ axon-metadata parse-data -i data.example.hex 39 | ``` 40 | 41 | From JSONRPC cell data: 42 | 43 | ```command 44 | $ curl 'https://testnet.ckbapp.dev/' --header 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"get_live_cell","params":[{"index":"0x0","tx_hash":"0x8a37967294c40da9ede155156bfe87d4b4e644c2b7f3275dd2ec4ebe4d695e24"},true],"id":3}' | jq -r '.result.cell.data.content' | axon-metadata parse-data -i /dev/stdin 45 | ``` 46 | -------------------------------------------------------------------------------- /devtools/metadata-cli/input.example.toml: -------------------------------------------------------------------------------- 1 | [[verifier_list]] 2 | bls_pub_key = "0xa26e3fe1cf51bd4822072c61bdc315ac32e3d3c2e2484bb92942666399e863b4bf56cf2926383cc706ffc15dfebc85c6" 3 | pub_key = "0x031ddc35212b7fc7ff6685b17d91f77c972535aee5c7ae5684d3e72b986f08834b" 4 | propose_weight = "0x1" 5 | vote_weight = 1 6 | 7 | [[verifier_list]] 8 | bls_pub_key = "0x80310fa9df724b5603d283b472ed3bf85254a8a4ceda8a274b421f6cf2be1d9184267cdfe9a199d36ff14e57668a55d0" 9 | pub_key = "0x02b77c74eb68af3d4d6cc7884ed6709f1a2a1af0f713382a4438ec2ea3a70d4d7f" 10 | propose_weight = 1 11 | vote_weight = 1 12 | 13 | [[verifier_list]] 14 | bls_pub_key = "0x897721e9016864141a8b982a48217f66ef318ce598aa31842cddaaebe3cd7feab17050022afa6c2123aba39938fe4142" 15 | pub_key = "0x027ffd6a6a231561f2afe5878b1c743323b34263d16787130b1815fe35649b0bf5" 16 | propose_weight = 1 17 | vote_weight = "0x01" 18 | 19 | [[verifier_list]] 20 | bls_pub_key = "0x98eef09a3927acb225191101a1d9aa85775fdcdc87b9ba36898f6c132b485d66aef91c0f51cda331be4f985c3be6761c" 21 | pub_key = "0x0232c489c23b1207107e9a24648c1e4754a8c1c0b38db96df57a526201035058cb" 22 | -------------------------------------------------------------------------------- /docs/assets/logo/axon-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axonweb3/axon/69f1a4f98b4ae7734bbd239c9ae02691bd1e6568/docs/assets/logo/axon-01.png -------------------------------------------------------------------------------- /examples/custom_chain.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::diverging_sub_expression)] 2 | 3 | use axon::{async_trait, FeeAllocate, FeeInlet, KeyProvider, ValidatorExtend, H160, U256}; 4 | 5 | #[derive(Default, Clone, Debug)] 6 | struct CustomFeeAllocator; 7 | 8 | impl FeeAllocate for CustomFeeAllocator { 9 | fn allocate( 10 | &self, 11 | _block_number: U256, 12 | _fee_collect: U256, 13 | _proposer: H160, 14 | _validators: &[ValidatorExtend], 15 | ) -> Vec { 16 | // Write your custom fee allocation process below. 17 | todo!() 18 | } 19 | } 20 | 21 | #[derive(Default, Clone, Debug)] 22 | struct CustomKey; 23 | 24 | #[async_trait] 25 | impl KeyProvider for CustomKey { 26 | type Error = std::io::Error; 27 | 28 | async fn sign_ecdsa_async + Send>( 29 | &self, 30 | _message: T, 31 | ) -> Result, Self::Error> { 32 | todo!() 33 | } 34 | 35 | fn sign_ecdsa>(&self, _message: T) -> Result, Self::Error> { 36 | todo!() 37 | } 38 | 39 | fn pubkey(&self) -> Vec { 40 | todo!() 41 | } 42 | 43 | fn verify_ecdsa(&self, _pubkey: P, _message: T, _signature: F) -> bool 44 | where 45 | P: AsRef<[u8]>, 46 | T: AsRef<[u8]>, 47 | F: AsRef<[u8]>, 48 | { 49 | todo!() 50 | } 51 | } 52 | 53 | fn main() { 54 | let result = axon::run(CustomFeeAllocator, CustomKey, "0.1.0"); 55 | if let Err(e) = result { 56 | eprintln!("Error {e}"); 57 | std::process::exit(1); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/solidity/CallCkbVm.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.9; 3 | 4 | import "./Types.sol"; 5 | 6 | contract CallCkbVm { 7 | event CallCkbVmEvent(int8); 8 | event NotGetCellEvent(); 9 | 10 | int8 ret; 11 | 12 | function testCallCkbVm( 13 | bytes32 txHash, 14 | uint32 index, 15 | uint8 depType, 16 | bytes[] memory input_args 17 | ) public { 18 | OutPoint memory outPoint = OutPoint(txHash, index); 19 | (bool isSuccess, bytes memory res) = address(0x0104).staticcall( 20 | abi.encode(CellDep(outPoint, depType), input_args) 21 | ); 22 | 23 | if (isSuccess) { 24 | ret = int8(uint8(res[0])); 25 | emit CallCkbVmEvent(ret); 26 | } else { 27 | emit NotGetCellEvent(); 28 | } 29 | } 30 | 31 | function callCkbVm() public view returns (int8) { 32 | return ret; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/solidity/GetCell.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.9; 3 | 4 | import "./Types.sol"; 5 | 6 | contract GetCell { 7 | event GetCellEvent(Cell); 8 | event NotGetCellEvent(); 9 | 10 | Cell cell; 11 | 12 | function testGetCell(bytes32 txHash, uint32 index) public { 13 | (bool isSuccess, bytes memory res) = address(0x0103).staticcall( 14 | abi.encode(OutPoint(txHash, index)) 15 | ); 16 | 17 | if (isSuccess) { 18 | cell = abi.decode(res, (Cell)); 19 | emit GetCellEvent(cell); 20 | } else { 21 | emit NotGetCellEvent(); 22 | } 23 | } 24 | 25 | function getCell() public view returns (Cell memory) { 26 | return cell; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/solidity/GetHeader.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.9; 3 | 4 | import "./Types.sol"; 5 | 6 | contract GetHeader { 7 | event GetHeaderEvent(Header); 8 | event NotGetHeaderEvent(); 9 | 10 | Header header; 11 | 12 | function testGetHeader(bytes32 blockHash) public { 13 | (bool isSuccess, bytes memory res) = address(0x0102).staticcall(abi.encode(blockHash)); 14 | 15 | if (isSuccess) { 16 | header = abi.decode(res, (Header)); 17 | emit GetHeaderEvent(header); 18 | } else { 19 | emit NotGetHeaderEvent(); 20 | } 21 | } 22 | 23 | function getHeader() public view returns (Header memory) { 24 | return header; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/solidity/Types.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.8.0; 3 | 4 | struct VerifyPayload { 5 | CellDep[] cellDeps; 6 | HeaderDep[] headerDeps; 7 | OutPoint[] inputs; 8 | WitnessArgs[] witnesses; 9 | } 10 | 11 | struct OutPoint { 12 | bytes32 txHash; 13 | uint32 index; 14 | } 15 | 16 | struct CellDep { 17 | OutPoint outPoint; 18 | uint8 index; 19 | } 20 | 21 | struct HeaderDep { 22 | bytes32 headerHash; 23 | } 24 | 25 | struct Cell { 26 | CellOutput cellOutput; 27 | bytes cellData; 28 | bool isConsumed; 29 | uint64 createdNumber; 30 | uint64 consumedNumber; 31 | } 32 | 33 | struct CellOutput { 34 | uint64 capacity; 35 | Script lock; 36 | Script[] type_; 37 | } 38 | 39 | struct Script { 40 | ScriptHashType hashType; 41 | bytes32 codeHash; 42 | bytes args; 43 | } 44 | 45 | struct WitnessArgs { 46 | bytes lock; 47 | bytes inputType; 48 | bytes outputType; 49 | } 50 | 51 | enum ScriptHashType { 52 | Data, 53 | Type, 54 | Data1 55 | } 56 | 57 | struct Header { 58 | uint32 version; 59 | uint32 compactTarget; 60 | uint64 timestamp; 61 | uint64 number; 62 | uint64 epch; 63 | bytes32 parentHash; 64 | bytes32 transactionsRoot; 65 | bytes32 proposalsHash; 66 | bytes32 extraHash; 67 | bytes32 dao; 68 | uint128 nonce; 69 | bytes extension; 70 | bytes32 blockHash; 71 | } 72 | -------------------------------------------------------------------------------- /examples/solidity/VerifyByCKb.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.9; 3 | 4 | import "./Types.sol"; 5 | 6 | contract VerifyByCkb { 7 | event VerifyByCkbEvent(uint64); 8 | event NotGetCellEvent(); 9 | 10 | uint64 ret; 11 | 12 | function testVerifyByCkb( 13 | CellDep[] memory cellDeps, 14 | HeaderDep[] memory HeaderDeps, 15 | OutPoint[] memory inputs, 16 | WitnessArgs[] memory witnesses 17 | ) public { 18 | VerifyPayload memory payload = VerifyPayload( 19 | cellDeps, 20 | HeaderDeps, 21 | inputs, 22 | witnesses 23 | ); 24 | (bool isSuccess, bytes memory res) = address(0x0105).staticcall( 25 | abi.encode(payload) 26 | ); 27 | 28 | if (isSuccess) { 29 | ret = bytesToUint64(res); 30 | emit VerifyByCkbEvent(ret); 31 | } else { 32 | emit NotGetCellEvent(); 33 | } 34 | } 35 | 36 | function callCkbVm() public view returns (uint64) { 37 | return ret; 38 | } 39 | 40 | function bytesToUint64(bytes memory b) public pure returns (uint64) { 41 | uint64 number; 42 | 43 | for (uint i = 0; i < 8; i++) { 44 | number = number + uint8(b[i]); 45 | } 46 | 47 | return number; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /protocol/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "axon-protocol" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | arc-swap = "1.6" 9 | async-trait = "0.1" 10 | bincode = "1.3" 11 | bytes = { version = "1.5", features = ["serde"] } 12 | ckb-hash = "0.111" 13 | ckb-jsonrpc-types = "0.111" 14 | ckb-sdk = "3.0" 15 | ckb-traits = "0.111" 16 | ckb-types = "0.111" 17 | creep = "0.2" 18 | derive_more = "0.99" 19 | ethereum = { version = "0.14", features = ["with-codec", "with-serde"] } 20 | ethereum-types = { version = "0.14", features = [ 21 | "arbitrary", 22 | "codec", 23 | "rlp", 24 | "serialize", 25 | "std", 26 | ] } 27 | ethers-core = "2.0" 28 | evm = { version = "0.37", features = ["with-serde"] } 29 | faster-hex = "0.8" 30 | hasher = "0.1" 31 | lazy_static = "1.4" 32 | ophelia = "0.3" 33 | overlord = "0.4" 34 | rand = "0.7" 35 | rlp = "0.5" 36 | rlp-derive = "0.1" 37 | serde = { version = "1.0", features = ["derive"] } 38 | thiserror = "1.0" 39 | tokio = { version = "1.34", features = ["full"] } 40 | trie = { package = "cita_trie", version = "5.0" } 41 | zeroize = "1.6.0" 42 | 43 | common-crypto = { path = "../common/crypto" } 44 | common-hasher = { path = "../common/hasher" } 45 | 46 | [dev-dependencies] 47 | hex = "0.4" 48 | serde_json = "1.0" 49 | toml = "0.8" 50 | 51 | common-merkle = { path = "../common/merkle" } 52 | 53 | [features] 54 | default = ["hex-serialize"] 55 | hex-serialize = [] 56 | -------------------------------------------------------------------------------- /protocol/src/codec/error.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | 3 | use derive_more::Display; 4 | 5 | use crate::{ProtocolError, ProtocolErrorKind}; 6 | 7 | #[derive(Debug, Display)] 8 | pub enum CodecError { 9 | #[display(fmt = "rlp: from string {}", _0)] 10 | Rlp(String), 11 | } 12 | 13 | impl Error for CodecError {} 14 | 15 | impl From for ProtocolError { 16 | fn from(err: CodecError) -> ProtocolError { 17 | ProtocolError::new(ProtocolErrorKind::Codec, Box::new(err)) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /protocol/src/constants/configs.rs: -------------------------------------------------------------------------------- 1 | use crate::types::U64; 2 | 3 | /// There is not a standard for the maximum gas limit, as long as the account 4 | /// balance can pay the `gas_limit * gas_price`. For reduce some useless 5 | /// calculation, `30_000_000` is large enough to cover the transaction usage. 6 | pub const MAX_GAS_LIMIT: u64 = 30_000_000; 7 | /// According to [go-ethereum](https://github.com/ethereum/go-ethereum/blob/be65b47/eth/gasprice/gasprice.go#L38), 8 | /// the maximum gas price is 500 Gwei. 9 | pub const MAX_GAS_PRICE: U64 = U64([500 * GWEI]); 10 | pub const MIN_TRANSACTION_GAS_LIMIT: u64 = 21_000; 11 | /// The mempool refresh timeout is 50 milliseconds. 12 | pub const MEMPOOL_REFRESH_TIMEOUT: u64 = 50; 13 | pub const MAX_BLOCK_GAS_LIMIT: u64 = 30_000_000; 14 | // MAX_FEE_HISTORY is the maximum number of blocks that can be retrieved for a 15 | // fee history request. Between 1 and 1024 blocks can be requested in a single 16 | // query. reference: https://docs.infura.io/infura/networks/ethereum/json-rpc-methods/eth_feehistory/ 17 | pub const MAX_FEE_HISTORY: u64 = 1024; 18 | pub const BASE_FEE_PER_GAS: u64 = 0x539; 19 | 20 | const GWEI: u64 = 1_000_000_000; 21 | -------------------------------------------------------------------------------- /protocol/src/constants/endpoints.rs: -------------------------------------------------------------------------------- 1 | pub const END_GOSSIP_NEW_TXS: &str = "/gossip/mempool/new_txs"; 2 | pub const RPC_PULL_TXS: &str = "/rpc_call/mempool/pull_txs"; 3 | pub const RPC_RESP_PULL_TXS: &str = "/rpc_resp/mempool/pull_txs"; 4 | pub const RPC_RESP_PULL_TXS_SYNC: &str = "/rpc_resp/mempool/pull_txs_sync"; 5 | 6 | pub const END_GOSSIP_SIGNED_PROPOSAL: &str = "/gossip/consensus/signed_proposal"; 7 | pub const END_GOSSIP_SIGNED_VOTE: &str = "/gossip/consensus/signed_vote"; 8 | pub const END_GOSSIP_AGGREGATED_VOTE: &str = "/gossip/consensus/qc"; 9 | pub const END_GOSSIP_SIGNED_CHOKE: &str = "/gossip/consensus/signed_choke"; 10 | pub const RPC_SYNC_PULL_BLOCK: &str = "/rpc_call/consensus/sync_pull_block"; 11 | pub const RPC_RESP_SYNC_PULL_BLOCK: &str = "/rpc_resp/consensus/sync_pull_block"; 12 | pub const RPC_SYNC_PULL_TXS: &str = "/rpc_call/consensus/sync_pull_txs"; 13 | pub const RPC_RESP_SYNC_PULL_TXS: &str = "/rpc_resp/consensus/sync_pull_txs"; 14 | pub const BROADCAST_HEIGHT: &str = "/gossip/consensus/broadcast_height"; 15 | pub const RPC_SYNC_PULL_PROOF: &str = "/rpc_call/consensus/sync_pull_proof"; 16 | pub const RPC_RESP_SYNC_PULL_PROOF: &str = "/rpc_resp/consensus/sync_pull_proof"; 17 | -------------------------------------------------------------------------------- /protocol/src/constants/mod.rs: -------------------------------------------------------------------------------- 1 | mod configs; 2 | pub mod endpoints; 3 | 4 | pub use configs::*; 5 | -------------------------------------------------------------------------------- /protocol/src/lazy.rs: -------------------------------------------------------------------------------- 1 | use arc_swap::ArcSwap; 2 | use ckb_types::{packed, prelude::*}; 3 | 4 | use crate::{ckb_blake2b_256, types::Hex}; 5 | 6 | lazy_static::lazy_static! { 7 | pub static ref CHAIN_ID: ArcSwap = ArcSwap::from_pointee(Default::default()); 8 | pub static ref PROTOCOL_VERSION: ArcSwap = ArcSwap::from_pointee(Hex::with_length(8)); 9 | 10 | pub static ref DUMMY_INPUT_OUT_POINT: packed::OutPoint 11 | = packed::OutPointBuilder::default() 12 | .tx_hash(ckb_blake2b_256("DummyInputOutpointTxHash").pack()) 13 | .index(0u32.pack()) 14 | .build(); 15 | } 16 | -------------------------------------------------------------------------------- /protocol/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod codec; 2 | pub mod constants; 3 | pub mod lazy; 4 | pub mod traits; 5 | pub mod types; 6 | 7 | use std::error::Error; 8 | 9 | pub use derive_more::{Constructor, Display, From}; 10 | pub use { 11 | async_trait::async_trait, ckb_hash::blake2b_256 as ckb_blake2b_256, rand, thiserror, tokio, 12 | trie, 13 | }; 14 | 15 | #[derive(Copy, Clone, Debug)] 16 | pub enum ProtocolErrorKind { 17 | // traits 18 | API, 19 | Cli, 20 | CkbClient, 21 | Consensus, 22 | Contract, 23 | CrossChain, 24 | DB, 25 | Executor, 26 | Interoperation, 27 | Mempool, 28 | Network, 29 | Storage, 30 | Service, 31 | TxAssembler, 32 | Main, 33 | 34 | // types 35 | Types, 36 | Codec, 37 | 38 | // metric 39 | Metric, 40 | } 41 | 42 | // refer to https://github.com/rust-lang/rust/blob/a17951c4f80eb5208030f91fdb4ae93919fa6b12/src/libstd/io/error.rs#L73 43 | #[derive(Debug, Constructor, Display)] 44 | #[display(fmt = "[ProtocolError] Kind: {:?}, Error: {}", kind, error)] 45 | pub struct ProtocolError { 46 | kind: ProtocolErrorKind, 47 | error: Box, 48 | } 49 | 50 | impl From for Box { 51 | fn from(error: ProtocolError) -> Self { 52 | Box::new(error) as Box 53 | } 54 | } 55 | 56 | impl From for String { 57 | fn from(error: ProtocolError) -> String { 58 | error.to_string() 59 | } 60 | } 61 | 62 | impl From for ProtocolError { 63 | fn from(error: trie::TrieError) -> Self { 64 | ProtocolError { 65 | kind: ProtocolErrorKind::DB, 66 | error: Box::new(error), 67 | } 68 | } 69 | } 70 | 71 | impl Error for ProtocolError {} 72 | 73 | pub type ProtocolResult = Result; 74 | -------------------------------------------------------------------------------- /protocol/src/traits/interoperation.rs: -------------------------------------------------------------------------------- 1 | use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider}; 2 | use ckb_types::core::cell::CellProvider; 3 | 4 | use crate::types::{Bytes, CellDep, VMResp}; 5 | use crate::{traits::Context, ProtocolResult}; 6 | 7 | pub const BYTE_SHANNONS: u64 = 100_000_000; 8 | pub const SIGNATURE_HASH_CELL_OCCUPIED_CAPACITY: u64 = signature_hash_cell_bytes() * BYTE_SHANNONS; 9 | 10 | /// The always success cell structure: 11 | /// ```yml 12 | /// type: 13 | /// Null 14 | /// lock: 15 | /// code_hash: H256::zero() 16 | /// args: 0x 17 | /// hash_type: data 18 | /// data: signature hash(32 bytes) 19 | /// capacity: 1b31d2900 20 | /// ``` 21 | /// So the occupied bytes is 32 + 32 + 1 + 8 = 73 bytes. 22 | const fn signature_hash_cell_bytes() -> u64 { 23 | 32 + 32 + 1 + 8 24 | } 25 | 26 | pub trait CkbDataProvider: 27 | Clone + CellDataProvider + CellProvider + HeaderProvider + ExtensionProvider 28 | { 29 | } 30 | 31 | pub trait Interoperation: Sync + Send { 32 | fn call_ckb_vm( 33 | ctx: Context, 34 | data_loader: &DL, 35 | data_cell_dep: CellDep, 36 | args: &[Bytes], 37 | max_cycles: u64, 38 | ) -> ProtocolResult; 39 | } 40 | -------------------------------------------------------------------------------- /protocol/src/traits/mod.rs: -------------------------------------------------------------------------------- 1 | mod api; 2 | mod ckb_client; 3 | mod consensus; 4 | mod executor; 5 | mod interoperation; 6 | mod mempool; 7 | mod network; 8 | mod storage; 9 | 10 | pub use api::APIAdapter; 11 | pub use ckb_client::{CkbClient, RPC}; 12 | pub use consensus::{ 13 | CommonConsensusAdapter, Consensus, ConsensusAdapter, MessageTarget, NodeInfo, Synchronization, 14 | SynchronizationAdapter, 15 | }; 16 | pub use creep::{Cloneable, Context}; 17 | pub use executor::{ApplyBackend, Backend, Executor, ExecutorAdapter, ExecutorReadOnlyAdapter}; 18 | pub use interoperation::{ 19 | CkbDataProvider, Interoperation, BYTE_SHANNONS, SIGNATURE_HASH_CELL_OCCUPIED_CAPACITY, 20 | }; 21 | pub use mempool::{MemPool, MemPoolAdapter}; 22 | pub use network::{ 23 | Gossip, MessageCodec, MessageHandler, Network, PeerTag, PeerTrust, Priority, Rpc, TrustFeedback, 24 | }; 25 | pub use storage::{ 26 | IntoIteratorByRef, ReadOnlyStorage, StateStorageCategory, Storage, StorageAdapter, 27 | StorageBatchModify, StorageCategory, StorageIterator, StorageSchema, 28 | }; 29 | -------------------------------------------------------------------------------- /protocol/src/types/receipt.rs: -------------------------------------------------------------------------------- 1 | pub use ethereum::Log; 2 | pub use ethereum_types::BloomInput; 3 | 4 | use crate::types::{Bloom, ExitReason, ExitSucceed, Hash, MerkleRoot, H160, U64}; 5 | 6 | #[derive(Clone, Debug, PartialEq, Eq)] 7 | pub struct Receipt { 8 | pub tx_hash: Hash, 9 | pub block_number: u64, 10 | pub block_hash: Hash, 11 | pub tx_index: u32, 12 | pub state_root: MerkleRoot, 13 | pub used_gas: U64, 14 | pub logs_bloom: Bloom, 15 | pub logs: Vec, 16 | pub log_index: u32, 17 | pub code_address: Option, 18 | pub sender: H160, 19 | pub ret: ExitReason, 20 | pub removed: bool, 21 | } 22 | 23 | impl Default for Receipt { 24 | fn default() -> Self { 25 | Receipt { 26 | tx_hash: Default::default(), 27 | block_number: Default::default(), 28 | block_hash: Default::default(), 29 | tx_index: Default::default(), 30 | state_root: Default::default(), 31 | used_gas: Default::default(), 32 | logs_bloom: Default::default(), 33 | logs: Default::default(), 34 | log_index: Default::default(), 35 | code_address: Default::default(), 36 | sender: Default::default(), 37 | ret: ExitReason::Succeed(ExitSucceed::Stopped), 38 | removed: Default::default(), 39 | } 40 | } 41 | } 42 | 43 | impl Receipt { 44 | pub fn status(&self) -> U64 { 45 | match self.ret { 46 | ExitReason::Succeed(_) => U64::one(), 47 | _ => U64::zero(), 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | 1.72 2 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub use core_executor::{DefaultFeeAllocator, FeeAllocate, FeeInlet}; 2 | pub use core_run::KeyProvider; 3 | pub use protocol::{ 4 | async_trait, 5 | types::{ValidatorExtend, H160, U256}, 6 | }; 7 | 8 | use std::sync::Arc; 9 | 10 | use core_cli::{AxonCli, Result}; 11 | use core_executor::FEE_ALLOCATOR; 12 | 13 | pub fn run( 14 | fee_allocator: impl FeeAllocate + 'static, 15 | key_provider: impl KeyProvider, 16 | app_version: &'static str, 17 | ) -> Result<()> { 18 | FEE_ALLOCATOR.swap(Arc::new(Box::new(fee_allocator))); 19 | 20 | AxonCli::init( 21 | clap::crate_version!() 22 | .parse() 23 | .expect("Parse kernel version"), 24 | app_version.parse().expect("Parse application version"), 25 | ) 26 | .start_with_custom_key_provider(Some(key_provider)) 27 | } 28 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::crate_version; 2 | 3 | use common_version::Version; 4 | use core_cli::AxonCli; 5 | 6 | fn main() { 7 | let crate_version = crate_version!(); 8 | let kernel_version = option_env!("AXON_COMMIT_ID") 9 | .map(|commit_id| Version::new_with_commit_id(crate_version, commit_id)) 10 | .unwrap_or_else(|| Version::new(crate_version)); 11 | 12 | if let Err(e) = AxonCli::init(kernel_version.clone(), kernel_version).start() { 13 | eprintln!("Error {e}"); 14 | std::process::exit(1); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/e2e/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "plugins": ["@babel/plugin-transform-modules-commonjs"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/e2e/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | es2022: true, 5 | jest: true, 6 | browser: true, 7 | }, 8 | globals: { 9 | browser: "writable", 10 | metamask: "writable", 11 | page: "writable", 12 | }, 13 | extends: ["eslint:recommended", "airbnb-base", "plugin:sonarjs/recommended"], 14 | plugins: ["sonarjs"], 15 | parserOptions: { 16 | sourceType: "module", 17 | }, 18 | rules: { 19 | indent: [ 20 | "error", 21 | 2, 22 | ], 23 | "linebreak-style": [ 24 | "error", 25 | "unix", 26 | ], 27 | quotes: [ 28 | "error", 29 | "double", 30 | ], 31 | semi: [ 32 | "error", 33 | "always", 34 | ], 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /tests/e2e/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | [English](./CONTRIBUTING_en-Hans.md) 2 | -------------------------------------------------------------------------------- /tests/e2e/config.js: -------------------------------------------------------------------------------- 1 | import configSetting from "./config.json"; 2 | 3 | export default class Config { 4 | constructor() { 5 | this.axonRpc = configSetting.axonRpc; 6 | this.httpServer = configSetting.httpServer; 7 | this.hexPrivateKey = configSetting.hexPrivateKey; 8 | this.account1 = configSetting.account1; 9 | this.account2 = configSetting.account2; 10 | } 11 | 12 | static getIns() { 13 | if (!Config.ins) { 14 | Config.ins = new Config(); 15 | } 16 | return Config.ins; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/e2e/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "httpServer": "http://localhost:8080", 3 | "axonRpc": { 4 | "netWorkName": "axon", 5 | "url": "http://localhost:8000", 6 | "chainId": 1098411886 7 | }, 8 | "hexPrivateKey": "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", 9 | "account1": "0x8ab0CF264DF99D83525e9E11c7e4db01558AE1b1", 10 | "account2": "0xF386573563C3a75dBbd269FCe9782620826dDAc2" 11 | } -------------------------------------------------------------------------------- /tests/e2e/jest/dappeteer_environment.js: -------------------------------------------------------------------------------- 1 | import NodeEnvironment from "jest-environment-node"; 2 | 3 | export default class DappeteerEnvironment extends NodeEnvironment { 4 | async setup() { 5 | await super.setup(); 6 | 7 | this.global.browser = global.browser; 8 | this.global.metamask = global.metamask; 9 | this.global.page = global.page; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/e2e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "axon-e2e-tests", 3 | "scripts": { 4 | "http-server": "cd src && http-server &", 5 | "test": "jest --runInBand", 6 | "test-single": "jest", 7 | "posttest": "pkill -2 http-server || echo no http-server running", 8 | "lint": "eslint src/*.js ./*.js" 9 | }, 10 | "license": "MIT", 11 | "dependencies": { 12 | "dappeteer-new": "^5.2.1", 13 | "@chainsafe/dappeteer": "^5.2.0", 14 | "@ethereumjs/common": "^3.1.1", 15 | "@ethereumjs/tx": "^4.2.0", 16 | "puppeteer": "^21.2.1", 17 | "web3": "^1.8.2", 18 | "xhr2": "^0.2.1" 19 | }, 20 | "devDependencies": { 21 | "@babel/plugin-transform-modules-commonjs": "^7.21.5", 22 | "eslint": "^8.49.0", 23 | "eslint-config-airbnb": "^19.0.4", 24 | "eslint-plugin-import": "^2.27.5", 25 | "eslint-plugin-sonarjs": "^0.19.0", 26 | "http-server": "^14.1.1", 27 | "jest": "^29.5.0" 28 | }, 29 | "jest": { 30 | "preset": "@chainsafe/dappeteer", 31 | "globalSetup": "./jest/setup.js", 32 | "testEnvironment": "./jest/dappeteer_environment.js" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_blockNumber.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_blockNumber.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_blockNumber.html"; 4 | beforeEach(async () => { 5 | await goto.goto(page, pageName); 6 | }); 7 | describe("eth_blockNumber", () => { 8 | /** 9 | * real common request 10 | */ 11 | it("eth_blockNumber_1", async () => { 12 | const testType = await page.$(goto.pageIds.testTypeId); 13 | await testType.type("1"); // 0: none params 1: common params to request 2: more params 14 | await goto.check(page, "0x"); 15 | }); 16 | /** 17 | * param: one more param 18 | */ 19 | it("eth_blockNumber_2", async () => { 20 | const testType = await page.$(goto.pageIds.testTypeId); 21 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 22 | await goto.check(page, "0x"); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_coinBase.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_coinBase.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_coinBase.html"; 4 | beforeEach(async () => { 5 | await goto.goto(page, pageName); 6 | }); 7 | describe("eth_coinBase", () => { 8 | /** 9 | * common real test 10 | * axon haven't wallet now. so skip this test case 11 | */ 12 | it("eth_coinBase_1", async () => { 13 | const testType = await page.$(goto.pageIds.testTypeId); 14 | await testType.type("1"); 15 | await goto.check(page, "null"); 16 | }); 17 | 18 | /** 19 | * more params 20 | */ 21 | it("eth_coinBase_2", async () => { 22 | const testType = await page.$(goto.pageIds.testTypeId); 23 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 24 | await goto.check(page, "null"); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_feeHistory.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
value:
6 | 7 | 8 | 45 | 46 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_gasPrice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_gasPrice.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_gasPrice.html"; 4 | beforeEach(async () => { 5 | await goto.goto(page, pageName); 6 | }); 7 | describe("eth_gasPrice", () => { 8 | /** 9 | * common real test 10 | */ 11 | it("eth_gasPrice_1", async () => { 12 | const testType = await page.$(goto.pageIds.testTypeId); 13 | await testType.type("1"); 14 | await goto.check(page, "0x8"); 15 | }); 16 | 17 | /** 18 | * more params 19 | */ 20 | it("eth_gasPrice_2", async () => { 21 | const testType = await page.$(goto.pageIds.testTypeId); 22 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 23 | await goto.check(page, "0x8"); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getBalance.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getBlockByHash.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getBlockByNumber.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getBlockTransactionCountByHash.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
value:
8 | 9 | 10 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getBlockTransactionCountByNumber.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
value:
8 | 9 | 10 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getCode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getFilterChanges.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
value:
8 | 9 | 10 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getStorageAt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
9 |
value:
10 | 11 | 12 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getTransactionByBlockHashAndIndex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getTransactionByBlockNumberAndIndex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getTransactionByHash.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
value:
8 | 9 | 10 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getTransactionCount.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_getTransactionReceipt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_hasHrate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_hasHrate.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_hasHrate.html"; 4 | beforeEach(async () => { 5 | await goto.goto(page, pageName); 6 | }); 7 | describe("eth_hasHrate", () => { 8 | /** 9 | * common real test 10 | */ 11 | it("eth_hasHrate_1", async () => { 12 | const testType = await page.$(goto.pageIds.testTypeId); 13 | await testType.type("1"); 14 | await goto.check(page, "0x1"); 15 | }); 16 | 17 | /** 18 | * more params 19 | */ 20 | it("eth_hasHrate_2", async () => { 21 | const testType = await page.$(goto.pageIds.testTypeId); 22 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 23 | await goto.check(page, "0x1"); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_mining.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
Mining:
6 |
7 | 8 | 21 | 22 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_mining.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_mining.html"; 4 | 5 | describe("eth_mining", () => { 6 | beforeAll(async () => { 7 | await goto.goto(page, pageName); 8 | }); 9 | 10 | it("should returns false", async () => { 11 | await page.click("#getMining"); 12 | 13 | await page.waitForFunction( 14 | () => document.getElementById("mining").innerText !== "", 15 | ); 16 | 17 | await expect(page.$eval("#mining", (e) => e.innerText)).resolves.toBe("false"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_newBlockFilter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
value:
7 | 8 | 9 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_newBlockFilter.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_newBlockFilter.html"; 4 | beforeEach(async () => { 5 | await goto.goto(page, pageName); 6 | }); 7 | describe("eth_newBlockFilter", () => { 8 | /** 9 | * none param 10 | */ 11 | it("eth_newBlockFilter_1", async () => { 12 | const testType = await page.$(goto.pageIds.testTypeId); 13 | await testType.type("1"); // 0: none params 1: common params to request 2: more params 14 | await goto.check(page, "0x"); 15 | }); 16 | /** 17 | * param: one more param 18 | */ 19 | it("eth_newBlockFilter_2", async () => { 20 | const testType = await page.$(goto.pageIds.testTypeId); 21 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 22 | await goto.check(page, "0x"); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_newPendingTransactionFilter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
value:
7 | 8 | 9 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_newPendingTransactionFilter.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_newPendingTransactionFilter.html"; 4 | beforeEach(async () => { 5 | await goto.goto(page, pageName); 6 | }); 7 | describe("eth_newPendingTransactionFilter", () => { 8 | /** 9 | * none param 10 | */ 11 | it("eth_newPendingTransactionFilter_1", async () => { 12 | const testType = await page.$(goto.pageIds.testTypeId); 13 | await testType.type("1"); // 0: none params 1: common params to request 2: more params 14 | await goto.check(page, "0x"); 15 | }); 16 | /** 17 | * param: one more param 18 | */ 19 | it("eth_newPendingTransactionFilter_2", async () => { 20 | const testType = await page.$(goto.pageIds.testTypeId); 21 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 22 | await goto.check(page, "0x"); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_sendRawTransaction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_sendRawTransaction.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | import createTransactionData from "./create_test_data/createTestDataManage"; 3 | 4 | const pageName = "eth_sendRawTransaction.html"; 5 | beforeEach(async () => { 6 | await goto.goto(page, pageName); 7 | }); 8 | describe("eth_sendRawTransaction", () => { 9 | /** 10 | * real common request,common transaction 11 | */ 12 | it("eth_sendRawTransaction_1", async () => { 13 | const tx = await createTransactionData.sendRawTestTx(); 14 | const testType = await page.$(goto.pageIds.testTypeId); 15 | const param1 = await page.$(goto.pageIds.param1Id); 16 | await testType.type("1"); // 0: none params 1: common params to request 2: more params 17 | await param1.type(tx); 18 | await goto.check(page, "0x"); 19 | }); 20 | 21 | /** 22 | * real common request,common transaction 23 | */ 24 | it("eth_sendRawTransaction_2", async () => { 25 | const tx = await createTransactionData.sendPreEip155RawTestTx(); 26 | const testType = await page.$(goto.pageIds.testTypeId); 27 | const param1 = await page.$(goto.pageIds.param1Id); 28 | await testType.type("1"); // 0: none params 1: common params to request 2: more params 29 | await param1.type(tx); 30 | await goto.check(page, "0x"); 31 | }); 32 | 33 | /** 34 | * param: one more param 35 | */ 36 | it("eth_sendRawTransaction_3", async () => { 37 | const testType = await page.$(goto.pageIds.testTypeId); 38 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 39 | await goto.check(page, "32603"); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_submitHashrate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_submitWork.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
9 |
value:
10 | 11 | 12 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_subscribe.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_subscribe.html"; 4 | 5 | async function subscribe(buttonId, resultId) { 6 | await page.click(`#${buttonId}`); 7 | 8 | await page.waitForFunction( 9 | (id) => document.getElementById(id).innerText !== "", 10 | {}, 11 | resultId, 12 | ); 13 | 14 | const request = page.$eval(`#${resultId}`, (e) => e.innerText); 15 | await expect(request).resolves.not.toThrow(); 16 | 17 | const result = await request; 18 | expect(result).toHaveLength(34); 19 | expect(result.substr(0, 2)).toBe("0x"); 20 | 21 | return result; 22 | } 23 | 24 | async function unsubscribe(id) { 25 | await page.type("#unsubscribeId", id); 26 | await page.click("#unsubscribe"); 27 | 28 | await page.waitForFunction( 29 | () => document.getElementById("unsubscribeResult").innerText !== "", 30 | ); 31 | 32 | await expect(page.$eval("#unsubscribeResult", (e) => e.innerText)).resolves.toBe("true"); 33 | } 34 | 35 | describe("eth_subscribe", () => { 36 | beforeAll(async () => { 37 | await goto.goto(page, pageName); 38 | }); 39 | 40 | it("should successfully subscribe new heads", async () => { 41 | const result = await subscribe("subscribeNewHeads", "newHeads"); 42 | await unsubscribe(result); 43 | }); 44 | 45 | it.skip("should successfully subscribe syncing", async () => { 46 | const result = await subscribe("subscribeSyncing", "syncing"); 47 | await unsubscribe(result); 48 | }); 49 | 50 | it.skip("should successfully subscribe logs", async () => { 51 | const result = await subscribe("subscribeLogs", "logs"); 52 | await unsubscribe(result); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_syncing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
Syncing:
7 |
8 | 9 | 22 | 23 | -------------------------------------------------------------------------------- /tests/e2e/src/eth_syncing.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "eth_syncing.html"; 4 | 5 | describe("eth_syncing", () => { 6 | beforeAll(async () => { 7 | await goto.goto(page, pageName); 8 | }); 9 | 10 | it("should returns false", async () => { 11 | await page.click("#getSyncing"); 12 | 13 | await page.waitForFunction( 14 | () => document.getElementById("syncing").innerText !== "", 15 | ); 16 | 17 | await expect(page.$eval("#syncing", (e) => e.innerText)).resolves.toBe("false"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/e2e/src/goto.js: -------------------------------------------------------------------------------- 1 | import Config from "../config"; 2 | 3 | const goto = { 4 | pageIds: { 5 | btnId: "#btn", testTypeId: "#testType", param1Id: "#param1", param2Id: "#param2", param3Id: "#param3", param4Id: "#param4", param5Id: "#param5", param6Id: "#param6", param7Id: "#param7", param8Id: "#param8", 6 | }, 7 | async goto(currentpage, pageName) { 8 | try { 9 | // await currentpage.goto(`${Config.getIns().httpServer}/src/${pageName}`); 10 | await currentpage.goto(`${Config.getIns().httpServer}/${pageName}`); 11 | } catch (err) { 12 | // eslint-disable-next-line no-console 13 | console.log(err); 14 | throw err; 15 | } 16 | }, 17 | 18 | async check(currentpage, expectedValue) { 19 | await currentpage.click(goto.pageIds.btnId); 20 | await currentpage.waitForFunction(() => document.getElementById("ret").innerText !== ""); 21 | await expect(currentpage.$eval("#ret", (e) => e.innerText)).resolves.toMatch(expectedValue); 22 | }, 23 | 24 | async checkAndWait(currentpage, expectedValue, second) { 25 | await currentpage.click(goto.pageIds.btnId); 26 | await currentpage.waitForFunction(() => document.getElementById("ret").innerText !== ""); 27 | await new Promise((resolve) => { setTimeout(resolve, second * 1000); }); 28 | await expect(currentpage.$eval("#ret", (e) => e.innerText)).resolves.toMatch(expectedValue); 29 | }, 30 | 31 | // get the value 32 | async value(currentpage) { 33 | await currentpage.click(goto.pageIds.btnId); 34 | await currentpage.waitForFunction(() => document.getElementById("ret").innerText !== ""); 35 | return currentpage.$eval("#ret", (e) => e.innerText); 36 | }, 37 | }; 38 | export default goto; 39 | -------------------------------------------------------------------------------- /tests/e2e/src/net_listening.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
value:
9 | 10 | 11 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/e2e/src/net_listening.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "net_listening.html"; 4 | beforeEach(async () => { 5 | await goto.goto(page, pageName); 6 | }); 7 | describe("net_listening", () => { 8 | /** 9 | * real common request 10 | */ 11 | it("net_listening_1", async () => { 12 | const testType = await page.$(goto.pageIds.testTypeId); 13 | await testType.type("1"); // 0: none params 1: common params to request 2: more params 14 | await goto.check(page, "true"); 15 | }); 16 | /** 17 | * param: one more param 18 | */ 19 | it("net_listening_2", async () => { 20 | const testType = await page.$(goto.pageIds.testTypeId); 21 | await testType.type("2"); // 0: none params 1: common params to request 2: more params 22 | await goto.check(page, "true"); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /tests/e2e/src/net_peerCount.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
Peer count:
6 |
7 | 8 | 21 | 22 | -------------------------------------------------------------------------------- /tests/e2e/src/net_peerCount.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "net_peerCount.html"; 4 | 5 | describe("net_peerCount", () => { 6 | beforeAll(async () => { 7 | await goto.goto(page, pageName); 8 | }); 9 | 10 | it("should returns 0x0", async () => { 11 | await page.click("#getPeerCount"); 12 | 13 | await page.waitForFunction( 14 | () => document.getElementById("peerCount").innerText !== "", 15 | ); 16 | 17 | await expect(page.$eval("#peerCount", (e) => e.innerText)).resolves.toBe("0x0"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/e2e/src/net_version.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
Chain id:
6 |
7 | 8 | 21 | 22 | -------------------------------------------------------------------------------- /tests/e2e/src/net_version.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "net_version.html"; 4 | 5 | describe("net_version", () => { 6 | beforeAll(async () => { 7 | await goto.goto(page, pageName); 8 | }); 9 | 10 | it("should returns version", async () => { 11 | await page.click("#getChainId"); 12 | 13 | await page.waitForFunction( 14 | () => document.getElementById("chainId").innerText !== "", 15 | ); 16 | 17 | await expect(page.$eval("#chainId", (e) => e.innerText)).resolves.toBe("1098411886"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/e2e/src/web3_clientVersion.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
Client version:
6 |
7 | 8 | 21 | 22 | -------------------------------------------------------------------------------- /tests/e2e/src/web3_clientVersion.test.js: -------------------------------------------------------------------------------- 1 | import goto from "./goto"; 2 | 3 | const pageName = "web3_clientVersion.html"; 4 | 5 | describe("web3_clientVersion", () => { 6 | beforeAll(async () => { 7 | await goto.goto(page, pageName); 8 | }); 9 | 10 | it("should returns right MetaMask version", async () => { 11 | await page.click("#getClientVersion"); 12 | 13 | await page.waitForFunction( 14 | () => document.getElementById("clientVersion").innerText !== "", 15 | ); 16 | 17 | await expect(page.$eval("#clientVersion", (e) => e.innerText)).resolves.toBe("MetaMask/v11.0.0"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/e2e/src/web3_sha3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |
sha value:
7 | 8 | 9 | 31 | 32 | --------------------------------------------------------------------------------