Skip to content

thread local chain type vs global chain type#3327

Merged
antiochp merged 8 commits into
mimblewimble:masterfrom
antiochp:threadlocal_chain_type
May 22, 2020
Merged

thread local chain type vs global chain type#3327
antiochp merged 8 commits into
mimblewimble:masterfrom
antiochp:threadlocal_chain_type

Conversation

@antiochp
Copy link
Copy Markdown
Member

@antiochp antiochp commented May 15, 2020

Our global CHAIN_TYPE config has been driving me crazy for a while now.
We have tests that do not reliably run in parallel in separate threads due to the global CHAIN_TYPE being overwritten by other tests. Some tests require Mainnet as we test specific PoW params etc.

This PR breaks out the following -

  • GLOBAL_CHAIN_TYPE
    • set once and only once at node startup based on config
    • not used in tests
  • thread local CHAIN_TYPE
    • "inherits" GLOBAL_CHAIN_TYPE in threads via thread local
    • must be explicitly set on a per-test basis

Reads via get_chain_type() always go via the thread local CHAIN_TYPE.
This will be lazily initialized based on GLOBAL_CHAIN_TYPE is not explicitly set.

  • introduced init_global_chain_type() to be called (once) during node startup
    • this uses our OneTime util internally
  • get_chain_type() reads the thread local, lazily inits it from global chain type
  • renamed set_mining_mode() to set_local_chain_type()
    • tests are free to call set_local_chain_type() within the context of a single test thread
    • tests must explicitly call this and we panic with a useful msg if not set
  • cleaned up POW_CONTEXT_TYPE and PowContextType (seemingly unused)

TODO

  • corresponding changes in grin-wallet (set_mining_mode() called in various tests)

Related: mimblewimble/grin-wallet#409

@antiochp antiochp changed the title [WIP] thread local chain type vs global chain type thread local chain type vs global chain type May 16, 2020
@antiochp antiochp marked this pull request as ready for review May 16, 2020 10:54
@antiochp antiochp requested a review from hashmap May 16, 2020 10:55
@antiochp antiochp added this to the 4.0.0 milestone May 16, 2020
@antiochp antiochp requested a review from quentinlesceller May 16, 2020 12:05
Copy link
Copy Markdown
Member

@quentinlesceller quentinlesceller left a comment

Choose a reason for hiding this comment

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

Found no issues. So 👍. Couple minor comments.

Comment thread core/src/global.rs

/// PoW test mining and verifier context
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum PoWContextTypes {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch 👍

Comment thread core/src/global.rs
/// The mining parameter mode
pub static ref CHAIN_TYPE: RwLock<ChainTypes> =
RwLock::new(ChainTypes::Mainnet);
thread_local! {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice didn't know about that macro.

Comment thread core/tests/block.rs Outdated
#[test]
fn too_large_block() {
global::set_mining_mode(ChainTypes::AutomatedTesting);
global::set_local_chain_type(ChainTypes::AutomatedTesting);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

test_setup()or global::set_local_chain_type(global::ChainTypes::AutomatedTesting);?

Overall test_setup() don't seems necessary no?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good catch. I just want to use test_setup() to avoid all the repeated calls to set_local_chain_type() as this should be common across all the tests.

Comment thread core/tests/block.rs Outdated
#[test]
fn compact_block_single_tx_serialized_size() {
global::set_mining_mode(ChainTypes::AutomatedTesting);
global::set_local_chain_type(ChainTypes::AutomatedTesting);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same comment as above.

Comment thread core/tests/block.rs Outdated
#[test]
fn empty_compact_block_serialized_size() {
global::set_mining_mode(ChainTypes::AutomatedTesting);
global::set_local_chain_type(ChainTypes::AutomatedTesting);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same comment as above.

Comment thread pool/src/types.rs
}
fn default_mineable_max_weight() -> usize {
global::max_block_weight()
consensus::MAX_BLOCK_WEIGHT
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why?

Copy link
Copy Markdown
Member Author

@antiochp antiochp May 22, 2020

Choose a reason for hiding this comment

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

Ah good catch. This was necessary because max_block_weight() relies on chain_type internally. So we have a default value that cannot be used until we know (and have configured) the chain_type itself.
The default config needs to be genuine defaults, without any dependencies on other, possibly external, configuration.

In many tests this actually used Mainnet chain_type to determine default_max_weight before we set chain_type to AutomatedTesting because some other config value was read.

Comment thread core/src/global.rs
None => {
if GLOBAL_CHAIN_TYPE.is_init() {
let chain_type = GLOBAL_CHAIN_TYPE.borrow();
set_local_chain_type(chain_type);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Out of curiosity, why do we need to set a per thread value here? Wouldn't returning GLOBAL_CHAIN_TYPE.borrow() enough?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah we technically don't need to use the thread local in the case where the global is set.
But I think its better for -

  • consistency (tests share the same code path for more code)
  • possibly performance as once the value is "cached" in the thread we no longer need to acquire a read lock on the global RwLock when reading this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Makes sense 👍

@antiochp antiochp merged commit 6faa0e8 into mimblewimble:master May 22, 2020
@antiochp antiochp deleted the threadlocal_chain_type branch May 22, 2020 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants