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

Rpc server encode decode bug fixes #62

Merged
merged 10 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

- RPC server interface is disabled by default
- It can be enabled by a feature flag

## [0.0.10] - 2024-09-04

### Changed
Expand Down Expand Up @@ -141,6 +148,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `generate_to_address`
- `get_balance`

[Unreleased]: https://github.com/chainwayxyz/bitcoin-mock-rpc/compare/v0.0.10...HEAD
[0.0.10]: https://github.com/chainwayxyz/bitcoin-mock-rpc/compare/v0.0.9...v0.0.10
[0.0.9]: https://github.com/chainwayxyz/bitcoin-mock-rpc/compare/v0.0.8...v0.0.9
[0.0.8]: https://github.com/chainwayxyz/bitcoin-mock-rpc/compare/v0.0.7...v0.0.8
Expand Down
14 changes: 9 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ thiserror = "1.0.63"
bitcoin-scriptexec = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/rust-bitcoin-scriptexec" }
rusqlite = { version = "0.32.1", features = ["bundled"] }
rs_merkle = "1.4"
jsonrpsee = { version = "0.24.3", features = ["server", "client", "macros"], default-features = false }
tokio = { version = "1.39.3", features = ["full"]}
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tower = "0.4.13"
clap = { version = "4.5.16", features = ["derive"] }
jsonrpsee = { version = "0.24.3", features = ["server", "client", "macros"], default-features = false, optional = true }
tokio = { version = "1.39.3", features = ["full"], optional = true }
tower = { version = "0.4.13", optional = true }

[[bin]]
name = "bitcoin_mock_rpc"
[dev-dependencies]
tokio = { version = "1.39.3", features = ["full"] }

[features]
# Enables RPC server interface. Note: Not stable nor complete. Use it in your own caution.
rpc_server = ["dep:jsonrpsee", "dep:tokio", "dep:tower"]
75 changes: 18 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
# Bitcoin Mock Remote Procedure Call

Bitcoin-mock-rpc is a mock Bitcoin ledger with RPC interface but without a
wallet support. Meaning there are only checks for consensus details of an
operation. This library can be used to test Bitcoin applications, without
needing to set up Bitcoin and with a **sandboxed environment**, for each test.

Bitcoin-mock-rpc is built on
[bitcoincore-rpc's](https://github.com/rust-bitcoin/rust-bitcoincore-rpc)
`RpcApi` trait. Meaning no real servers are needed for Rust applications. There
is also an RPC server that can communicate with any application: No rust
dependencies!
`bitcoin-mock-rpc` is a mock Bitcoin ledger without a wallet support built on
`RpcApi` trait in
[bitcoincore-rpc](https://github.com/rust-bitcoin/rust-bitcoincore-rpc) library.
Meaning there are only checks for consensus details of an operation. This
library can be used to test Bitcoin applications, without needing to set up
Bitcoin and with a **sandboxed environment**, for each test.

This library is aimed to help the development of
[Clementine](https://github.com/chainwayxyz/clementine). Therefore, it's usage
Expand All @@ -19,55 +15,8 @@ of this library can be taken as a reference.
not gives any guarantee to act as the Bitcoin itself at any scale. Use it at
your own risk.

## Differences Between Real Bitcoin RPC and Feature Set

This library is currently **under heavy development**. And it is not expected to
provide a full Bitcoin experience. Code needs to be checked for what really is
available as futures. Also, [changelog](CHANGELOG.md) is a great summary for
what's available.

Some of the RPC functions behave similarly with real RPC while some of them are
not (mostly wallet operations). To check if an RPC function behaves different
than the real one, please check function comments in
[`src/client/rpc_api.rs`](src/client/rpc_api.rs).

## Usage

### RPC Server

RPC server can be spawned as long as there are available ports for them. Each
server will have an independent blockchain.

To run from CLI:

```bash
$ cargo run
Server started at 127.0.0.1:1024
# ^^^^^^^^^^^^^^
# Use this address in applications
$ cargo run -- --help # Prints usage information
```

To run in a Rust application:

```rust
#[test]
fn test() {
// Calling `spawn_rpc_server` in a different test while this test is running
// is OK and will spawn another blockchain. If parameters are the same
// however, they will operate on the same blockchain. Note: (None, None)
// will result to pick random values.
let address = bitcoin_mock_rpc::spawn_rpc_server(None, None).await.unwrap();

let rpc =
bitcoincore_rpc::Client::new(&address.to_string(), bitcoincore_rpc::Auth::None).unwrap();

// Use `bitcoincore_rpc` as is from now on. No code change is needed.
}
```

### `RpcApiWrapper` Trait For Rust Applications

`RpcApiWrapper` trait can be used to select between real and mock RPC:

```rust
Expand Down Expand Up @@ -98,6 +47,18 @@ fn test() {
}
```

## Differences Between Real Bitcoin RPC and Feature Set

This library is currently **under heavy development**. And it is not expected to
provide a full Bitcoin experience. Code needs to be checked for what really is
available as futures. Also, [changelog](CHANGELOG.md) is a great summary for
what's available.

Some of the RPC functions behave similarly with real RPC while some of them are
not (mostly wallet operations). To check if an RPC function behaves different
than the real one, please check function comments in
[`src/client/rpc_api.rs`](src/client/rpc_api.rs).

## Testing

Standard Rust tools are sufficient for testing:
Expand Down
61 changes: 0 additions & 61 deletions src/bin/bitcoin_mock_rpc.rs

This file was deleted.

4 changes: 2 additions & 2 deletions src/client/rpc_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ impl RpcApi for Client {

#[cfg(test)]
mod tests {
use crate::{ledger::Ledger, utils::decode_from_hex, Client, RpcApiWrapper};
use crate::{ledger::Ledger, utils::_decode_from_hex, Client, RpcApiWrapper};
use bitcoin::{
consensus::{deserialize, Decodable},
Amount, Network, OutPoint, Transaction, TxIn,
Expand Down Expand Up @@ -936,7 +936,7 @@ mod tests {

let res = rpc.fund_raw_transaction(&tx, None, None).unwrap();
let new_tx = String::consensus_decode(&mut res.hex.as_slice()).unwrap();
let new_tx = decode_from_hex::<Transaction>(new_tx).unwrap();
let new_tx = _decode_from_hex::<Transaction>(new_tx).unwrap();

assert_eq!(tx, new_tx);
assert_eq!(res.change_position, -1);
Expand Down
2 changes: 1 addition & 1 deletion src/ledger/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl Ledger {
/// # Panics
///
/// Will panic if there was a problem writing data to ledger.
#[tracing::instrument]
#[tracing::instrument(skip(self))]
pub fn mine_block(&self, address: &Address) -> Result<BlockHash, LedgerError> {
let mut transactions = self.get_mempool_transactions();
let coinbase_transaction = self.create_coinbase_transaction(
Expand Down
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
//! # Bitcoin Mock Remote Procedure Call
//!
//! This library mocks [bitcoincore-rpc](https://github.com/rust-bitcoin/rust-bitcoincore-rpc)
//! library. This mock takes the advantage of `bitcoincore-rpc` trait interface
//! called `RpcApi`.
//! library. This mock takes advantage of `RpcApi` trait.
//!
//! Applications can implement another trait that will switch between this mock
//! and the real RPC interface, for tests and production respectively.

pub mod client;
mod ledger;
pub mod rpc;
mod utils;

// Re-imports.
pub use client::*;

#[cfg(feature = "rpc_server")]
pub mod rpc;
6 changes: 3 additions & 3 deletions src/rpc/adapter/blockchain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! # Blockchain RPCs

use crate::utils::{decode_from_hex, encode_to_hex};
use crate::utils::{_decode_from_hex, encode_to_hex};
use crate::Client;
use bitcoin::{BlockHash, Txid};
use bitcoincore_rpc::{json, Error, RpcApi};
Expand All @@ -18,7 +18,7 @@ pub fn getblock(
blockhash: String,
verbosity: Option<usize>,
) -> Result<String, Error> {
let blockhash = decode_from_hex::<BlockHash>(blockhash)?;
let blockhash = _decode_from_hex::<BlockHash>(blockhash)?;
tracing::trace!("Decoded block hash: {blockhash:?}");

let block = client.get_block(&blockhash)?;
Expand Down Expand Up @@ -48,7 +48,7 @@ pub fn getblockheader(
blockhash: String,
verbose: Option<bool>,
) -> Result<String, Error> {
let blockhash = decode_from_hex::<BlockHash>(blockhash)?;
let blockhash = _decode_from_hex::<BlockHash>(blockhash)?;
let header = client.get_block_header(&blockhash)?;

match verbose {
Expand Down
Loading
Loading