Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hardfork): ckb2021 hardfork features (vm related part) #2756

Merged
merged 19 commits into from
Jul 1, 2021

Conversation

chaoticlonghair
Copy link
Contributor

@chaoticlonghair chaoticlonghair commented Jun 15, 2021

Changes

CKB Chain Edition

  • If no edition field, the default edition is "2019".

  • After this PR, the default files created by ckb init will be edition "2021" files.

    But the public chains will still use the edition "2019" CKB chain specification as the built-in spec.

    At present, there are only to public chains: "mainnet" and "testnet".

  • The edition "2019" doesn't support hardfork parameters.

  • How to upgrade from edition "2019" to "2021"?

    Modify your spec file (default is specs/dev.toml), ckb.toml and ckb-miner.toml:

    • Update all hash_type = "data" to hash_type.kind = "data" and hash_type.vm_version = 0.

    • Update all hash_type = "type" to hash_type.kind = "type".

    • Insert edition = "2021" into the head of the files.

    After upgrade the edition of chain specification, the first time to run the CKB, you have to use --overwrite-spec parameter. The details of this parameter can be found with ckb run --help.

BREAKING CHANGES

  • The field hash_type in Script is changed from a String to an Object for all JSON RPC methods.

    The details can be found in the latest RFCs.

  • The argument --ba-hash-type for ckb init is split into two arguments: --ba-hash-type-kind and --ba-hash-type-vm-version.

    More details can be found with ckb-release init --help.

@chaoticlonghair chaoticlonghair marked this pull request as ready for review June 15, 2021 14:46
@chaoticlonghair chaoticlonghair requested a review from a team June 15, 2021 14:46
@chaoticlonghair

This comment has been minimized.

@chaoticlonghair

This comment has been minimized.

@chaoticlonghair

This comment has been minimized.

@nervos-bot-user
Copy link
Collaborator

Benchmark Result

  • TPS: 472
  • CKB Version: 6ca81ab
  • Instance Type: c5.xlarge
  • Instances Count: 3
  • Bench Type: In2Out2
  • CKB Logger Filter: info,ckb=debug

@chaoticlonghair

This comment has been minimized.

@nervos-bot-user
Copy link
Collaborator

Sync Test Result

  • CKB Version: 6ca81ab
  • Instance Region: ap-southeast-1
  • Sync Start: 2021-06-16 10:53:41
  • Sync End: 2021-06-16 13:12:16
  • Sync Height: 4568343
  • Sync Speed: 549 blocks/s

@chaoticlonghair chaoticlonghair added the s:hold Status: Put this issue on hold. label Jun 23, 2021
…bject"

BREAKING CHANGE: The field "hash_type" in "Script" is changed from a "String" to an "Object" for all
JSON RPC methods.
@chaoticlonghair chaoticlonghair added s:waiting-on-reviewers Status: Waiting for Review and removed s:hold Status: Put this issue on hold. labels Jun 29, 2021
}
}

fn fetch_witness(&self, source: Source, index: usize) -> Option<PackedBytes> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any code that will decode the witness as molecule table WitnessArgs. If I put the code in witness, will it cause panic because it is not a valid WitnessArgs?

Copy link
Contributor Author

@chaoticlonghair chaoticlonghair Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw the discussion in our internal channel.

I understand the result of that discussion that this is not an issue.

So, I ignore this.

.values()
.map(|entry| entry.transaction().clone())
.collect::<Vec<_>>();
self.inner.clear();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

::std::mem::take maybe better?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is trivial.

So I decide to ignore it.

After all high priority tasks, I will do this replacement for whole workspace.

@doitian doitian added the u:ckb2021 Upgrade: Fork ckb2021 label Jun 30, 2021
Copy link
Contributor

@keroro520 keroro520 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#benchmark

Copy link
Collaborator

@nervos-bot-user nervos-bot-user left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#benchmark

Comment on lines +633 to +659
let txs_opt = {
// This closure is used to limit the lifetime of mutable tx_pool.
let mut tx_pool = self.tx_pool.write().await;

let txs_opt = if hardfork_during_detach || hardfork_during_attach {
// The tx_pool is locked, remove all caches if has any hardfork.
self.txs_verify_cache.write().await.clear();
Some(tx_pool.drain_all_transactions())
} else {
None
};

_update_tx_pool_for_reorg(
&mut tx_pool,
&attached,
detached_proposal_id,
snapshot,
&self.callbacks,
);
self.readd_dettached_tx(&mut tx_pool, retain, fetched_cache);

txs_opt
};

self.readd_dettached_tx(&mut tx_pool, retain, fetched_cache)
if let Some(txs) = txs_opt {
self.try_process_txs(txs).await;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The combination of the try_process_txs and txs_opt naming made me read the code multiple times before I understood the intent, suggest to remove the Option struct and use if/else directly:

        {
            let mut tx_pool = self.tx_pool.write().await;

            if hardfork_during_detach || hardfork_during_attach {
                // The tx_pool is locked, remove all caches if has any hardfork.
                self.txs_verify_cache.write().await.clear();
                let txs = tx_pool.drain_all_transactions();
                _update_tx_pool_for_reorg(
                    &mut tx_pool,
                    &attached,
                    detached_proposal_id,
                    snapshot,
                    &self.callbacks,
                );
                self.readd_dettached_tx(&mut tx_pool, retain, fetched_cache);
                self.try_process_txs(txs).await;
            } else {
                _update_tx_pool_for_reorg(
                    &mut tx_pool,
                    &attached,
                    detached_proposal_id,
                    snapshot,
                    &self.callbacks,
                );
                self.readd_dettached_tx(&mut tx_pool, retain, fetched_cache);
            };
        }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At earlier version, I used empty Vec<_> to present None. May be it's better?

Backup old transactions, reorg, re-process old transactions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is trivial.

Since this PR is hard to get approvals, and I already got one now.
Please let me fix this in one commit with other suggestions above in another PR after this merged.

@chaoticlonghair
Copy link
Contributor Author

bors r=doitian,quake

@bors
Copy link
Contributor

bors bot commented Jul 1, 2021

Build succeeded:

@bors bors bot merged commit 79e47fb into develop Jul 1, 2021
@bors bors bot deleted the ckb2021-develop branch July 1, 2021 03:41
@chaoticlonghair chaoticlonghair removed the s:waiting-on-reviewers Status: Waiting for Review label Jul 1, 2021
bors bot added a commit that referenced this pull request Jul 10, 2021
2818: refactor(hardfork): change field "hash_type" to an enumerated type r=quake,driftluo a=yangby-cryptape

This PR doesn't revert the edition feature for spec files  and config files.
We can do it later, in next PR, after discussions.

**BREAKING CHANGES**: Revert breaking changes which were introduced in #2756.

Co-authored-by: Boyu Yang <[email protected]>
bors bot added a commit that referenced this pull request Jul 12, 2021
2802: refactor(tests): simplify several construction functions and double ckb script tests r=quake,driftluo a=yangby-cryptape

_Fix the issue posted by @doitian in #2756 (comment)

_The best way to review this PR is reviewing each commits._

### Changes

- refactor: simplify vm construction functions which based on versions

  Before this commit, constructing a core vm requires complicated arguments:

  ```rust
  #[cfg(has_asm)]
  let v0_asm_machine = AsmCoreMachine::new(ISA_IMC, VERSION0, max_cycles);

  #[cfg(not(has_asm))]
  let v1_not_asm_machine = DefaultCoreMachine::<u64, WXorXMemory<SparseMemory<u64>>>::new(
      ISA_IMC | ISA_B | ISA_MOP,
      VERSION1,
      u64::max_value(),
  );
  ```

  After this commit, no longer care about cargo features, CKB VM versions or IMC sets:

  ```rust
  let v0_asm_machine = ScriptVersion:V0.init_core_machine(max_cycles);

  let v1_not_asm_machine = ScriptVersion::V1.init_core_machine_without_limit();
  ```

- refactor(tests): simplify tx script verify construction functions

  Before this commit, verifying requires complicated arguments:

  ```rust
  let fork_at = 10;
  let store = new_store();
  let data_loader = DataLoaderWrapper::new(&store);
  let hardfork_switch = HardForkSwitch::new_without_any_enabled()
      .as_builder()
      .rfc_pr_0237(fork_at)
      .rfc_pr_0234(fork_at)
      .build()
      .unwrap();
  let consensus = ConsensusBuilder::default()
      .hardfork_switch(hardfork_switch)
      .build();
  let tx_env0 = {
      let epoch = EpochNumberWithFraction::new(0, 0, 1);
      let header = HeaderView::new_advanced_builder()
          .epoch(epoch.pack())
          .build();
      TxVerifyEnv::new_commit(&header)
  };
  let tx_env1 = {
      let epoch = EpochNumberWithFraction::new(fork_at, 0, 1);
      let header = HeaderView::new_advanced_builder()
          .epoch(epoch.pack())
          .build();
      TxVerifyEnv::new_commit(&header)
  };

  let v0_result = TransactionScriptsVerifier::new(&rtx, &consensus, &data_loader, &tx_env0).verify(100_000_000);
  let v1_result = TransactionScriptsVerifier::new(&rtx, &consensus, &data_loader, &tx_env1).verify(100_000_000);
  ```

  After this commit, no longer care about store, consensus or tx-env:

  ```rust
  let verifier = TransactionScriptsVerifierWithEnv::new();
  let v0_result = verifier.verify_without_limit(ScriptVersion::V0, &rtx);
  let v1_result = verifier.verify_without_limit(ScriptVersion::V1, &rtx);
  ```

  For customize verification rules, try the follow method:
  ```rust
  fn verify_map<R, F>(
      &self,
      version: ScriptVersion,
      rtx: &ResolvedTransaction,
      mut verify_func: F,
  ) -> R
  where
      F: FnMut(TransactionScriptsVerifier<'_, DataLoaderWrapper<'_, ChainDB>>) -> R;
  ```

- test: add more unit tests

  - test: test both vm version 0 and vm version 1 for all syscalls

  - test: test both ckb 2019 and ckb 2021 for ckb script features

  Before this PR, old features are only tested for version 0 and new features are only tested for version 1.

Co-authored-by: Boyu Yang <[email protected]>
bors bot added a commit that referenced this pull request Jul 12, 2021
2802: refactor(tests): simplify several construction functions and double ckb script tests r=quake,driftluo,zhangsoledad a=yangby-cryptape

_Fix the issue posted by @doitian in #2756 (comment)

_The best way to review this PR is reviewing each commits._

### Changes

- refactor: simplify vm construction functions which based on versions

  Before this commit, constructing a core vm requires complicated arguments:

  ```rust
  #[cfg(has_asm)]
  let v0_asm_machine = AsmCoreMachine::new(ISA_IMC, VERSION0, max_cycles);

  #[cfg(not(has_asm))]
  let v1_not_asm_machine = DefaultCoreMachine::<u64, WXorXMemory<SparseMemory<u64>>>::new(
      ISA_IMC | ISA_B | ISA_MOP,
      VERSION1,
      u64::max_value(),
  );
  ```

  After this commit, no longer care about cargo features, CKB VM versions or IMC sets:

  ```rust
  let v0_asm_machine = ScriptVersion:V0.init_core_machine(max_cycles);

  let v1_not_asm_machine = ScriptVersion::V1.init_core_machine_without_limit();
  ```

- refactor(tests): simplify tx script verify construction functions

  Before this commit, verifying requires complicated arguments:

  ```rust
  let fork_at = 10;
  let store = new_store();
  let data_loader = DataLoaderWrapper::new(&store);
  let hardfork_switch = HardForkSwitch::new_without_any_enabled()
      .as_builder()
      .rfc_pr_0237(fork_at)
      .rfc_pr_0234(fork_at)
      .build()
      .unwrap();
  let consensus = ConsensusBuilder::default()
      .hardfork_switch(hardfork_switch)
      .build();
  let tx_env0 = {
      let epoch = EpochNumberWithFraction::new(0, 0, 1);
      let header = HeaderView::new_advanced_builder()
          .epoch(epoch.pack())
          .build();
      TxVerifyEnv::new_commit(&header)
  };
  let tx_env1 = {
      let epoch = EpochNumberWithFraction::new(fork_at, 0, 1);
      let header = HeaderView::new_advanced_builder()
          .epoch(epoch.pack())
          .build();
      TxVerifyEnv::new_commit(&header)
  };

  let v0_result = TransactionScriptsVerifier::new(&rtx, &consensus, &data_loader, &tx_env0).verify(100_000_000);
  let v1_result = TransactionScriptsVerifier::new(&rtx, &consensus, &data_loader, &tx_env1).verify(100_000_000);
  ```

  After this commit, no longer care about store, consensus or tx-env:

  ```rust
  let verifier = TransactionScriptsVerifierWithEnv::new();
  let v0_result = verifier.verify_without_limit(ScriptVersion::V0, &rtx);
  let v1_result = verifier.verify_without_limit(ScriptVersion::V1, &rtx);
  ```

  For customize verification rules, try the follow method:
  ```rust
  fn verify_map<R, F>(
      &self,
      version: ScriptVersion,
      rtx: &ResolvedTransaction,
      mut verify_func: F,
  ) -> R
  where
      F: FnMut(TransactionScriptsVerifier<'_, DataLoaderWrapper<'_, ChainDB>>) -> R;
  ```

- test: add more unit tests

  - test: test both vm version 0 and vm version 1 for all syscalls

  - test: test both ckb 2019 and ckb 2021 for ckb script features

  Before this PR, old features are only tested for version 0 and new features are only tested for version 1.

Co-authored-by: Boyu Yang <[email protected]>
bors bot added a commit that referenced this pull request Jul 22, 2021
2844: chore: log failed transactions results r=doitian,yangby-cryptape a=keroro520

#2756 (comment)

Co-authored-by: keroro <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
b:cli Break cli options and config file b:rpc Break RPC interface breaking change The feature breaks consensus, database, message schema or RPC interface. u:ckb2021 Upgrade: Fork ckb2021
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants