Skip to content

LayerTwo-Labs/bip300301_enforcer

Repository files navigation

Requirements

  1. Bitcoin Core, with ZMQ support. For information on running this on the global signet, see drivechain.info/dev.txt

  2. Rustc & Cargo, version 1.88.0 or higher. Installing via Rustup is recommended.

Supported Bitcoin Core versions

The enforcer supports running against the 3 latest major versions of Bitcoin Core. getnetworkinfo is queried at startup and refuses to run against an unsupported Bitcoin Core version. The supported set lives in lib/version.rs; see --help for the override flags.

Getting started

Building/running:

# Check out git submodules
$ git submodule update --init --recursive
# Compiles the project
$ cargo build

# See available options
$ cargo run -- --help

# Starts the gRPC server at localhost:50001
# Adjust these parameters to match your local Bitcoin
# Core instance
$ cargo run -- \
  --node-rpc-addr=localhost:38332 \
  --node-rpc-user=user \
  --node-rpc-pass=password \
  --node-zmq-addr-sequence=tcp://0.0.0.0:29000

# You should now be able to fetch data from the server!
$ buf curl  --http2-prior-knowledge --protocol grpc \
        http://localhost:50051/cusf.validator.v1.ValidatorService/GetChainInfo
{
  "network": "NETWORK_SIGNET"
}

Interacting with the enforcer

The CUSF enforcer exposes multiple gRPC services. These can be interacted with using a gRPC client of your choice, for example buf curl or grpcurl.

Some examples of interacting with the enforcer using buf curl, assuming you expose the server at the default address localhost:50051:

# Define an alias for ease of use
$ alias buf_curl='buf curl --http2-prior-knowledge --protocol grpc --emit-defaults'

# List all the available RPCs
$ buf_curl --list-methods http://localhost:50051
cusf.mainchain.v1.ValidatorService/GetBlockHeaderInfo
cusf.mainchain.v1.ValidatorService/GetChainInfo
cusf.mainchain.v1.ValidatorService/GetChainTip
cusf.mainchain.v1.ValidatorService/GetSidechains
cusf.mainchain.v1.WalletService/CreateNewAddress
cusf.mainchain.v1.WalletService/CreateSidechainProposal
... list continues

# Fetching data with a RPC that takes no input data
$ buf_curl http://localhost:50051/cusf.mainchain.v1.ValidatorService/GetChainInfo
{
  "network": "NETWORK_SIGNET"
}

# Fetching data with a RPC that takes input data
$ request='{"block_hash": {"hex": "000002a78fc54150bb2d4cdb0fb19bcf744f2877faf90a172972fca5daf5fe92"}}'
$ buf_curl -d "$request" http://localhost:50051/cusf.mainchain.v1.ValidatorService/GetBlockHeaderInfo
{
  "headerInfo": {
    "blockHash": {
      "hex": "000002a78fc54150bb2d4cdb0fb19bcf744f2877faf90a172972fca5daf5fe92"
    },
    "prevBlockHash": {
      "hex": "000002501d569e62a56ea175896d4348dd9cfef1d700e5b06250486df07c9225"
    },
    "height": 34998,
    "work": {
      "hex": "14d4490000000000000000000000000000000000000000000000000000000000"
    }
  }
}

# Note that the request can also be read from a file. This can come in handy if
# you're working on more complex requests that's hard to write out on the terminal
echo "$request" > request.json
$ buf_curl -d @request.json http://localhost:50051/cusf.mainchain.v1.ValidatorService/GetBlockHeaderInfo

Regtest

By default, the enforcer runs against our custom signet. If you instead want to run against a local regtest, you need to also run a local regtest Electrum server. There are multiple implementations of Electrum servers, an easy-to-use one is mempool/electrs.

For complete instructions on how to do this, consult the official docs.

A quickstart (that might not work, in case you're missing some dependencies):

$ git clone https://github.com/mempool/electrs

$ cd electrs

$ cargo run --bin electrs --release -- \
    --network regtest \
    --cookie=user:password \
    --jsonrpc-import

Logging

The application uses the tracing crate for logging. Logging is configured through setting the --log-level argument. Some examples:

# Prints ALL debug logs
$ cargo run ... --log-level DEBUG

Logs can also be configured via env vars, which take precedence over CLI args.

# Prints logs at the "info" level and above, plus our logs the "debug" level and above
$ RUST_LOG=info,bip300301_enforcer=debug cargo run ...

Working with the proto files

Code is generated with protox, and happens automatically as part of the build process.

Files are linted with protolint.

To lint the files, run:

$ protolint lint --fix proto/validator/v1/validator.proto

Code formatting

Rust code is formatted with rustfmt. You need to ensure you have a nightly version of Rust installed on your system. To format the project files from the command line:

$ cargo +nightly fmt --all

Markdown and YAML files are formatted with Prettier. The easiest way to run it is to install the Prettier VSCode extension.

To run it from the command line, install the Prettier CLI and run it from the root of the repo:

$ prettier --write .

Linting Rust code

Rust code is linted with Clippy. We use a specific Clippy lint that's only available on the nightly release channel. Running Clippy therefore looks like this:

$ cargo clippy --all-targets
$ cargo +nightly clippy -- -A clippy::all -D unqualified_local_imports -Zcrate-attr="feature(unqualified_local_imports)"

Integration tests

Integration tests can be run using

$ cargo run --example integration_tests -- <TEST ARGS>

Profiling

# Generate a flamegraph for Rust code. This does NOT
# measure syscalls/IO wait
# https://github.com/flamegraph-rs/flamegraph
$ cargo install flamegraph
$ cargo flamegraph --  --data-dir ./datadir \
          --node-rpc-addr=localhost:38332 \
          --node-rpc-user=user \
          --node-rpc-pass=password \
          --enable-mempool --exit-after-sync 100000

# macOS only
$ ./scripts/trace_enforcer_macos.sh

About

CUSF software enforcing BIP300 and BIP301 rules.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages