GithubHelp home page GithubHelp logo

rust-bitcoincore-rpc's Introduction

Rust Bitcoin

Rust Bitcoin logo by Hunter Trujillo, see license and source files under /logo

Library with support for de/serialization, parsing and executing on data-structures and network messages related to Bitcoin.

Crate Info CC0 1.0 Universal Licensed CI Status API Docs Rustc Version 1.56.1+ Chat on IRC

Documentation

Supports (or should support)

  • De/serialization of Bitcoin protocol network messages
  • De/serialization of blocks and transactions
  • Script de/serialization
  • Private keys and address creation, de/serialization and validation (including full BIP32 support)
  • PSBT v0 de/serialization and all but the Input Finalizer role. Use rust-miniscript to finalize.

For JSONRPC interaction with Bitcoin Core, it is recommended to use rust-bitcoincore-rpc.

It is recommended to always use cargo-crev to verify the trustworthiness of each of your dependencies, including this one.

Known limitations

Consensus

This library must not be used for consensus code (i.e. fully validating blockchain data). It technically supports doing this, but doing so is very ill-advised because there are many deviations, known and unknown, between this library and the Bitcoin Core reference implementation. In a consensus based cryptocurrency such as Bitcoin it is critical that all parties are using the same rules to validate data, and this library is simply unable to implement the same rules as Core.

Given the complexity of both C++ and Rust, it is unlikely that this will ever be fixed, and there are no plans to do so. Of course, patches to fix specific consensus incompatibilities are welcome.

Support for 16-bit pointer sizes

16-bit pointer sizes are not supported and we can't promise they will be. If you care about them please let us know, so we can know how large the interest is and possibly decide to support them.

Documentation

Currently can be found on docs.rs/bitcoin. Patches to add usage examples and to expand on existing docs would be extremely appreciated.

Contributing

Contributions are generally welcome. If you intend to make larger changes please discuss them in an issue before PRing them to avoid duplicate work and architectural mismatches. If you have any questions or ideas you want to discuss please join us in #bitcoin-rust on libera.chat.

For more information please see ./CONTRIBUTING.md.

Minimum Supported Rust Version (MSRV)

This library should always compile with any combination of features on Rust 1.56.1.

Use Cargo-minimal.lock to build the MSRV by copying to Cargo.lock and building.

External dependencies

We integrate with a few external libraries, most notably serde. These are available via feature flags. To ensure compatibility and MSRV stability we provide two lock files as a means of inspecting compatible versions: Cargo-minimal.lock containing minimal versions of dependencies and Cargo-recent.lock containing recent versions of dependencies tested in our CI.

We do not provide any guarantees about the content of these lock files outside of "our CI didn't fail with these versions". Specifically, we do not guarantee that the committed hashes are free from malware. It is your responsibility to review them.

Installing Rust

Rust can be installed using your package manager of choice or rustup.rs. The former way is considered more secure since it typically doesn't involve trust in the CA system. But you should be aware that the version of Rust shipped by your distribution might be out of date. Generally this isn't a problem for rust-bitcoin since we support much older versions than the current stable one (see MSRV section).

Building

The cargo feature std is enabled by default. At least one of the features std or no-std or both must be enabled.

Enabling the no-std feature does not disable std. To disable the std feature you must disable default features. The no-std feature only enables additional features required for this crate to be usable without std. Both can be enabled without conflict.

The library can be built and tested using cargo:

git clone [email protected]:rust-bitcoin/rust-bitcoin.git
cd rust-bitcoin
cargo build

You can run tests with:

cargo test

Please refer to the cargo documentation for more detailed instructions.

Just

We support just for running dev workflow commands. Run just from your shell to see list available sub-commands.

Building the docs

We build docs with the nightly toolchain, you may wish to use the following shell alias to check your documentation changes build correctly.

alias build-docs='RUSTDOCFLAGS="--cfg docsrs" cargo +nightly rustdoc --features="$FEATURES" -- -D rustdoc::broken-intra-doc-links'

Testing

Unit and integration tests are available for those interested, along with benchmarks. For project developers, especially new contributors looking for something to work on, we do:

There are always more tests to write and more bugs to find, contributions to our testing efforts extremely welcomed. Please consider testing code a first class citizen, we definitely do take PRs improving and cleaning up test code.

Unit/Integration tests

Run as for any other Rust project cargo test --all-features.

Benchmarks

We use a custom Rust compiler configuration conditional to guard the bench mark code. To run the bench marks use: RUSTFLAGS='--cfg=bench' cargo +nightly bench.

Mutation tests

We have started doing mutation testing with mutagen. To run these tests first install the latest dev version with cargo +nightly install --git https://github.com/llogiq/mutagen then run with RUSTFLAGS='--cfg=mutate' cargo +nightly mutagen.

Code verification

We have started using kani, install with cargo install --locked kani-verifier (no need to run cargo kani setup). Run the tests with cargo kani.

Pull Requests

Every PR needs at least two reviews to get merged. During the review phase maintainers and contributors are likely to leave comments and request changes. Please try to address them, otherwise your PR might get closed without merging after a longer time of inactivity. If your PR isn't ready for review yet please mark it by prefixing the title with WIP: .

CI Pipeline

The CI pipeline requires approval before being run on each MR.

In order to speed up the review process the CI pipeline can be run locally using act. The fuzz and Cross jobs will be skipped when using act due to caching being unsupported at this time. We do not actively support act but will merge PRs fixing act issues.

Githooks

To assist devs in catching errors before running CI we provide some githooks. Copy the hooks in githooks/ to your githooks folder or run just githooks-install to copy them all.

Policy on Altcoins/Altchains

Since the altcoin landscape includes projects which frequently appear and disappear, and are poorly designed anyway we do not support any altcoins. Supporting Bitcoin properly is already difficult enough and we do not want to increase the maintenance burden and decrease API stability by adding support for other coins.

Our code is public domain so by all means fork it and go wild :)

Release Notes

Release notes are done per crate, see:

Licensing

The code in this project is licensed under the Creative Commons CC0 1.0 Universal license. We use the SPDX license list and SPDX IDs.

rust-bitcoincore-rpc's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-bitcoincore-rpc's Issues

Update `gettxoutsetinfo` with Coinstats Index (Core 22.0)

As of 22.0 Core supports the Coinstats Index and return faster and more detailed results for gettxoutsetinfo. The RPC call should be updated to reflect the latest behavior.

gettxoutsetinfo ( "hash_type" hash_or_height use_index )

Returns statistics about the unspent transaction output set.
Note this call may take some time if you are not using coinstatsindex.

Arguments:
1. hash_type         (string, optional, default="hash_serialized_2") Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'muhash', 'none'.
2. hash_or_height    (string or numeric, optional) The block hash or height of the target height (only available with coinstatsindex).
3. use_index         (boolean, optional, default=true) Use coinstatsindex, if available.

Result:
{                                     (json object)
  "height" : n,                       (numeric) The block height (index) of the returned statistics
  "bestblock" : "hex",                (string) The hash of the block at which these statistics are calculated
  "txouts" : n,                       (numeric) The number of unspent transaction outputs
  "bogosize" : n,                     (numeric) Database-independent, meaningless metric indicating the UTXO set size
  "hash_serialized_2" : "hex",        (string, optional) The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)
  "muhash" : "hex",                   (string, optional) The serialized hash (only present if 'muhash' hash_type is chosen)
  "transactions" : n,                 (numeric) The number of transactions with unspent outputs (not available when coinstatsindex is used)
  "disk_size" : n,                    (numeric) The estimated size of the chainstate on disk (not available when coinstatsindex is used)
  "total_amount" : n,                 (numeric) The total amount of coins in the UTXO set
  "total_unspendable_amount" : n,     (numeric) The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)
  "block_info" : {                    (json object) Info on amounts in the block at this block height (only available if coinstatsindex is used)
    "prevout_spent" : n,              (numeric)
    "coinbase" : n,                   (numeric)
    "new_outputs_ex_coinbase" : n,    (numeric)
    "unspendable" : n,                (numeric)
    "unspendables" : {                (json object) Detailed view of the unspendable categories
      "genesis_block" : n,            (numeric)
      "bip30" : n,                    (numeric) Transactions overridden by duplicates (no longer possible with BIP30)
      "scripts" : n,                  (numeric) Amounts sent to scripts that are unspendable (for example OP_RETURN outputs)
      "unclaimed_rewards" : n         (numeric) Fee rewards that miners did not claim in their coinbase transaction
    }
  }
}

Examples:
> bitcoin-cli gettxoutsetinfo 
> bitcoin-cli gettxoutsetinfo "none"
> bitcoin-cli gettxoutsetinfo "none" 1000
> bitcoin-cli gettxoutsetinfo "none" '"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"'

Using import_multi with a descriptor and a large range returns a socket error, but only on version 0.14

This code works for version 0.13 or below, once I upgrade to 0.14 this error started happening.

Here is code demonstrating the bug

const RPC_CREDENTIALS: Option<(&str, &str)> = Some(("regtestrpcuser", "regtestrpcpass"));

const RPC_HOSTPORT: &str = "localhost:18443";
const RPC_WALLET: &str = "teleport";

const ADDRESS_IMPORT_COUNT: usize = 5000;

use bitcoincore_rpc::json::{
    ImportMultiOptions, ImportMultiRequest, ImportMultiRescanSince,
};
use bitcoincore_rpc::{Client, RpcApi, Auth};


fn main() -> Result<(), bitcoincore_rpc::Error> {

    let descs = [
        "wpkh(tpubDCph6XxkYmXpittC1dKgfNU2wTuq3JbpDNqJRwB1zpEZHJZBgdk1nxtn4p4TiF6ydvJH4BFbPwHMf8gGZ85DSLDfqKGRLtLeyuWs9hBeHvo/0/*)#fymqnm93",
        "wpkh(tpubDCph6XxkYmXpittC1dKgfNU2wTuq3JbpDNqJRwB1zpEZHJZBgdk1nxtn4p4TiF6ydvJH4BFbPwHMf8gGZ85DSLDfqKGRLtLeyuWs9hBeHvo/1/*)#cs7pww4f"
    ];

    let auth = match RPC_CREDENTIALS {
        Some((user, pass)) => Auth::UserPass(user.to_string(), pass.to_string()),
        None => panic!(""),
    };
    let rpc = Client::new(
        &format!("http://{}/wallet/{}", RPC_HOSTPORT, RPC_WALLET),
        auth,
    )?;
    rpc.get_blockchain_info()?;

    let address_label = "somelabel";

    let import_requests = descs 
        .iter()
        .map(|desc| ImportMultiRequest {
            timestamp: ImportMultiRescanSince::Now,
            descriptor: Some(desc),
            range: Some((0, ADDRESS_IMPORT_COUNT - 1)),
            watchonly: Some(true),
            label: Some(&address_label),
            ..Default::default()
        })
        .collect::<Vec<ImportMultiRequest>>();

    let result = rpc.import_multi(
        &import_requests,
        Some(&ImportMultiOptions {
            rescan: Some(false),
        }),
    )?;
    for r in result {
        if !r.success {
            return Err(bitcoincore_rpc::Error::UnexpectedStructure);
        }
    }

    println!("Hello, world!");

    Ok(())
}

This results in an error: Error: JsonRpc(Transport(SocketError(Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" })))

The cargo.toml file:

[package]
name = "rpc-bitcoincore-0-14-importmulti"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bitcoincore-rpc = "0.14"

Changing to bitcoincore-rpc = "0.13" or below stops the error from happening.

Reducing the value of ADDRESS_IMPORT_COUNT down to something like 500 or 50 instead of 5000 also makes the error disappear, indicating that the cause is the long runtime of importmulti, possibly version 0.14 reduced a timeout somewhere.

`Auth` is not very convenient

<'a> is meh, especially if one doesn't want to use it all.

I started updating to rust-bicoin 0.18, so I'll probably create more issues like this. Excuse my terseness.

`RpcApi::create_wallet()` not working with Core v0.23.0

We found in the BDK test module that RpcApi::create_wallet() isn't working as expected with core v0.23.0..
bitcoindevkit/bdk#598

The same call that was creating a legacy wallet for core v0.22.0 and before, is now creating a descriptor wallet in v0.23.0.

The workaround fix for now is to make the manual call() with "createwallet" command as done in this PR bitcoindevkit/bdk#613.

I also noticed that the create_wallet() arg list here (including defaults) are not consistent with bitcoin-cli creatwallet args as per v0.23.0.

$ bitcoin-cli help createwallet
createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse descriptors load_on_startup external_signer )

Creates and loads a new wallet.

Arguments:
1. wallet_name             (string, required) The name for the new wallet. If this is a path, the wallet will be created at the path location.
2. disable_private_keys    (boolean, optional, default=false) Disable the possibility of private keys (only watchonlys are possible in this mode).
3. blank                   (boolean, optional, default=false) Create a blank wallet. A blank wallet has no keys or HD seed. One can be set using sethdseed.
4. passphrase              (string, optional) Encrypt the wallet with this passphrase.
5. avoid_reuse             (boolean, optional, default=false) Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind.
6. descriptors             (boolean, optional, default=true) Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation
7. load_on_startup         (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged.
8. external_signer         (boolean, optional, default=false) Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true.

It takes 8 args, but the function is passing in 9 args..

So most probably something is going wrong in parsing the args, and createwallet is not reading the descriptor flag. And as per v0.23.0 descriptors are default wallets in core.

Release 0.14

There is a RUSTSEC advisory for hyper. rust-bitcoincore-rpc depends on a recent version of hyper that is not effected by the advisory. However there has been no release since the update to hyper was merged [1].

Can we have a v0.14 release please so downstream users of this library can avoid the security advisory.

Thanks,
Tobin.

[1] commit: 54a427f Merge pull request #180 from Start9Labs/dependencies/jsonrpc

issue with PublicKey deserialize

I've been trying to add a new result struct that required deserialising secp256k1::PublicKey but it seems to fail with "expected a borrowed byte array".

Are you aware of any way around this? I see it's serialised in PubKeyOrAddress but not deserialised anywhere.

Support getblocktemplate and submitwork

I've been messing around with some mining stuff. It would be useful to support getblocktemplate and submitwork without using them manually with client.call().

I'll try and add a pr that implements this, the only issue is figuring out the exact format of each field for getblocktemplate because of all the different bips

BUG: Can't create_raw_transaction without inputs

Because the rust-bitcoin tx deserialization doesn't support zero-input transactions, we also can't parse them as a return value from createrawtransaction. So when trying to invoke create_raw_transaction with no inputs, we will always fail.

Serialized json of `GetRawTransactionResult` returns empty `Addresses` in Vout

When im trying to get serde_json::json!(raw_tx) of GetRawTransactionResult it's returning this:

{"blockhash":"00000000000000000000bd8bcb350bc9e1fa6c24eb790d2e88bd1946199dd9f3","blocktime":1647948159,"confirmations":8,"hash":"79e416c20620a812919051c6f3602f3eeed23aab23654a7fdb5e1ec8de11e817","hex":"0200000001f5c4ef6a6159572bdb0267207507cd8198c262d2b20e598f288645c580bebd09000000006a47304402206db3dbeb918c2adddcd72a1ae529e7795bd4929dc843bb7116bb5b5279ed09ef022038992388a783d53ef65acaa56a601c2571d63b070dc3478ea4afd9d6c4681177012103892f7df4ad7e5b718e46f755458dc9fba6397973e0497057cf34f357bf265857fdffffff01b2a60000000000001976a9146676cd11247e8b94d7d7471c6ef311397a56ef3088ac00000000","in_active_chain":null,"locktime":0,"size":191,"time":1647948159,"txid":"79e416c20620a812919051c6f3602f3eeed23aab23654a7fdb5e1ec8de11e817","version":2,"vin":[{"coinbase":null,"scriptSig":{"asm":"304402206db3dbeb918c2adddcd72a1ae529e7795bd4929dc843bb7116bb5b5279ed09ef022038992388a783d53ef65acaa56a601c2571d63b070dc3478ea4afd9d6c4681177[ALL] 03892f7df4ad7e5b718e46f755458dc9fba6397973e0497057cf34f357bf265857","hex":"47304402206db3dbeb918c2adddcd72a1ae529e7795bd4929dc843bb7116bb5b5279ed09ef022038992388a783d53ef65acaa56a601c2571d63b070dc3478ea4afd9d6c4681177012103892f7df4ad7e5b718e46f755458dc9fba6397973e0497057cf34f357bf265857"},"sequence":4294967293,"txid":"09bdbe80c54586288f590eb2d262c29881cd0775206702db2b5759616aefc4f5","txinwitness":null,"vout":0}],"vout":[{"n":0,"scriptPubKey":{"addresses":null,"asm":"OP_DUP OP_HASH160 6676cd11247e8b94d7d7471c6ef311397a56ef30 OP_EQUALVERIFY OP_CHECKSIG","hex":"76a9146676cd11247e8b94d7d7471c6ef311397a56ef3088ac","reqSigs":null,"type":"pubkeyhash"},"value":0.00042674}],"vsize":191}

addresses field in vout is null.
But when if i call bitcoin-cli getrawtransaction 79e416c20620a812919051c6f3602f3eeed23aab23654a7fdb5e1ec8de11e817 true Address is exists in vout.

getaddressinfo "labels" field

It seems like right now this field contains mixed content:

  "labels" : [                      (json array) Array of labels associated with the address. Currently limited to one label but returned
                                    as an array to keep the API stable if multiple labels are enabled in the future.
    "str",                          (string) The label name. Defaults to "".
    {                               (json object) label data, DEPRECATED, will be removed in 0.21. To re-enable, launch bitcoind with `-deprecatedrpc=labelspurpose`
      "name" : "str",               (string) The label name. Defaults to "".
      "purpose" : "str"             (string) The purpose of the associated address (send or receive).
    },
    ...
  ]

Right now my 0.20 node causes a bad response because rust-bitcoincore-rpc can't interpret the leading "string" value.

Support JSONRPC request batching

Depends on apoelstra/rust-jsonrpc#24.

I'm thinking about what would be the best way to implement this. Given the fact that calls have different ways to post-process response messages.

I'm thinking of something like this:

Create a Batch type that has a similar API to Client, but returns generic BatchResult types. The BatchResult types carry a reference to the batch and information on how to postprocess.

Usage would look more or less like this:

let client = bitcoincore_rpc::Client::new("http://localhost:8332/", None, None);
let batch: bitcoincore_rpc::Batch = client.start_batch();

let block1 = batch.get_block("00000000000000000001c6458ed068b7d2dc10fe360155d2762c79ecf380ed2d".parse().unwrap());
let block2 = batch.get_block("000000000000000000205dc3ad635402aedc8aeead11f98d85d91513a992c55b".parse().unwrap());

println!("block1.get before batch execution: {}", block1.get());
// will be Err(Error::BatchNotExecuted)

batch.execute().expect("error executing batch");

println!("block1.get after batch execution: {}", block1.get());
// will be Ok(bitcoin::Block { ... })

This will require us to have all API methods in two places, though, but I think that's unavoidable.

client hyper connectivity error

Sorry wasn't sure if this is more related to this repo or rust-jsonrpc but I've noticed that if you do an rpc call, sleep for some time (say 60 sec) and then attempt another call you almost always get the following error:

JSON-RPC error: Hyper error: Connection reset by peer (os error 54)

Do you know if this is related to bitcoin or hyper or something else?

Would the best way be to implement a RetryClient like the one you recently added in the examples or something else?

Thanks

Move lightning-block-sync's HTTP logic into here

Because we also support Bitcoin Core REST and potentially nginx/Cloudflare-proxied REST, we ended up with our own one-dependency HTTP client in rust-lightning. We currently use it with our own JSON parsing, though switching to this crate instead may be nice. In order to do that, we'd need to move the HTTP bits to here (they support async, but without the tokio feature, the "async" keyword on the functions is unused, just need a macro to figure out how to insert-or-not an async keyword), maybe in its own subcrate.

The current HTTP/RPC/REST client stuff is at https://github.com/rust-bitcoin/rust-lightning/tree/main/lightning-block-sync/src

Use named arguments for all calls

We can use slices of tuples to avoid allocating HashMaps for each call. However, this library is far from memory-efficient and can use a bunch of improvements, especially to its use of serde for JSON.

Allow descriptor wallet creation

The current RpcApi defaults to creating legacy wallet. Is it possible to set an extra option to choose to create a descriptor wallet instead??

fn create_wallet(
&self,
wallet: &str,
disable_private_keys: Option<bool>,
blank: Option<bool>,
passphrase: Option<&str>,
avoid_reuse: Option<bool>,
) -> Result<json::LoadWalletResult> {
let mut args = [
wallet.into(),
opt_into_json(disable_private_keys)?,
opt_into_json(blank)?,
opt_into_json(passphrase)?,
opt_into_json(avoid_reuse)?,
];
self.call(
"createwallet",
handle_defaults(&mut args, &[false.into(), false.into(), into_json("")?, false.into()]),
)
}

Also would be really helpful to open up importdescriptors call to RpcApi..

Donating my crate name to rust-bitcoin

Long time ago like one year or so I used to be to involved with some projects of mine related to bitcoin and even rust-bitcoin, and like so I tried to write a crate that did RPC stuff using rust-jsonrpc, never finished it, and now that there is an official rust-bitcoin project that does RPC with the bitcoind daemon I would like to donate the bitcoin-rpc crate name. Of course, I'll remove myself from the crate owners if you accept it.

getmininginfo always return an error

"missing field currentblockweight".

My bitcoin node (Bitcoin Core 0.18) returns this response for "getmininginfo" request:

{
  "blocks": 585966,
  "difficulty": 9064159826491.41,
  "networkhashps": 5.276674407862246e+19,
  "pooledtx": 48870,
  "chain": "main",
  "warnings": ""
}

Looks like currentblockweight and currentblocktx fields are not present.

My node "-getinfo":

{
  "version": 180000,
  "protocolversion": 70015,
  ...
}

Remove dependence on rust-bitcoin

On several projects, we are not able to upgrade to the latest rust-bitcoin version because we use rust-bitcoincore-rpc in some automated tests and it has a later version.

I am contemplating/working on the idea of removing the dependency.
It works pretty well, replacing rust-bitcoin types with type parameters that can then be passed at the call site by the user.

There are less obvious changes such as some helper outpoint From implementations that I am thinking of moving to a separate sub-crate that will be the only subcrate to depend on rust-bitcoin (or provide a FromStr/Display trait implementations for JsonOutpoint that renders in the Outpoint format txidhex:vout):

impl From<OutPoint> for JsonOutPoint {

What is the maintainers' take on the idea?

Error when requesting `getblockheader` for orphaned header

Bitcoin Core responds to getblockheader requests with a value of -1 for the "confirmations" field if the block is not in the highest-work chain. However, this library expects that field to be a u32 and errors with the following: JsonRpc(Json(Error("invalid value: integer '-1', expected u32", line: 1, column: 93))).

To reproduce, try calling the get_block_header_info method with hash "00000000b8a88e4a03be52082902d123b979d0079c92379187fa6d8213f84d2e" on testnet.

CI migration

I just noticed we completely lost all automatic testing with travis going into read-only mode. We should migrate our test suite to another service. Looking at the rust-bitcoin ecosystem GithubActions seem most popular. Without working CI our whole merge process becomes much more cumbersome.

Bitcoin v0.17 onward doesn't need defaults to be set

I believe since 0.17, Bitcoin Core doesn't use the number of arguments to check whether an argument is set, but the isNull checker instead. This means we don't have to provide default values for the unset optionals before the last set optional. We should just be able to pass serde_json::Value::Null instead.

Zero-Input transactions may fail to deserialize

I haven't tested this, just going off rust-bitcoin's deserialization code. rust-bitcoin seems to reject the segwit ambiguity cases around zero-input as otherwise you have to resort to some heuristic to determine how to de-serialize such transactions (and maybe Do The Wrong Thing). This is fine in most cases, and because rust-bitcoin does the sane thing of including the segwit magic byte for zero-input transactions this isn't an issue for other sane segwit-only implementations. Except that when Bitcoin Core is returning a 0-input transaction it doesn't do this for backwards compatibility reasons. I think rust-bitcoincore-rpc should work around this at a higher level, looking at calls like createrawtransaction and checking the input count to determine how the transaction should be deserialized.

Re-export types from dependencies used in public APIs

The Error enum has variants for JsonRpc, FromHexError etc.

Especially for the JsonRpc one, it would be handy if the crate would re-export the type so that it is accessible for downstream crates without having to add a dependency on jsonrpc itself.

Error message for invalid auth credentials could be more helpful

This script uses an incorrect password:

extern crate bitcoincore_rpc;                                                   
use bitcoincore_rpc::{Client, Error, RpcApi, Auth};                             
                                                                                
fn main() -> Result<(), Error> {                                                
                                                                                
    let auth = Auth::UserPass(                                                  
        "regtest-username".to_string(),                                           
        "incorrect-password".to_string()                                           
    );                                                                          
    let rpc = Client::new("http://localhost:18443".to_string(), auth)?;         
                                                                                
    let info = rpc.get_blockchain_info()?;                                      
    println!("info = {:#?}", info);                                             
    println!("best block hash = {}", info.best_block_hash);                     
    Ok(())                                                                      
}

And it produces this error:

Error: JsonRpc(Json(Error("EOF while parsing a value", line: 1, column: 0)))

The error message doesn't mention anything about invalid credentials.

I think what's happening is Bitcoin Core is sending back a HTTP 401 Unauthorized reply, but the rust library still tries to read from the HTTP body. As there's no body it results in a confusing EOF error instead.

I may code a PR myself which fixes this by checking for 401 (I only just started learning rust so this may take a while)

MSRV of `proc_macro2` is 1.31

Currently, the build against Rust 1.24 fails because proc_macro2 requires Rust 1.31.

The dependency is brought in by serde_derive:

image

If we want to keep supporting Rust 1.24, it seems like the options are:

  • drop serde_derive (and reimplement the serialization manually)
  • pin it to a version that compiles on Rust 1.24 (rust-bitcoin pins it to <1.0.99)

Neither of them seem to be like a great idea:

  • dropping serde_derive means we'd have to write a lot of boilerplate
  • pinning the version limits downstream users in which features of serde_derive they can access

What are your thoughts on supporting Rust 1.24 in this repo @stevenroose ?
Currently, none of the PRs (like #80) can be merged because of the failing build for Rust 1.24.

What this library is capable of and what is missing

This library is great but it's missing quite a bit of functionality and it's hard to track down what's implemented and what not.

I decided to compile a list of all available and missing features.

Blockchain RPCs
Control RPCs
Generating RPCs
Mining RPCs
Network RPCs

soon

Rawtransactions RPCs

soon

Util RPCs

soon

Wallet RPCs

soon

The list is not complete yet because it take a bit of time to write everything down. Nonetheless I'm sharing what I've done so far.
I feel something like this is essential to build a roadmap and actually get an understanding of the progress of the library

RBF Enabled

When using getmempoolentry the bip-125-replaceable enabled field inherits from ancestors. Wondering if this value has potential to change if ancestors are confirmed? Also is there any other way to confirm if the transaction itself has RBF enabled or if it inherits from parents RBF Enabeld?

Unable to unlock every UTXO using `lockunspent`

The call lockunspent allows unlocking every UTXO, but I think this cant be done with rust-bitcoincore-rpc.

The way to unlock everything is to just pass true, but the way the call is currently implemented always passes another list (e.g. true []). Even if that list is empty Core will not unlock everything.

Examples:

let rpc: Client;
rpc.unlock_unspent(&[]); //does not unlock every UTXO
rpc.call("lockunspent", &[Value::Bool(true)]); //does unlock every UTXO

MSRV requirement failures

Two of the current MSRV requirements fail on my computer with the following errors:

$cargo update --package "log:0.4.x" --precise "0.4.13" # x being the highest patch version, currently 14
error: invalid package ID specification: `log:0.4.x`

Caused by:
  cannot parse '0.4.x' as a semver

And

$cargo update --package "cfg-if" --precise "0.1.9"
    Updating crates.io index
error: failed to select a version for the requirement `cfg-if = "^1.0"`
candidate versions found which didn't match: 0.1.9
location searched: crates.io index
required by package `log v0.4.16`
    ... which satisfies dependency `log = "^0.4.5"` (locked to 0.4.16) of package `bitcoincore-rpc v0.14.0 (]...]/rust-bitcoincore-rpc/client)`

How to get value to put in &[GetBlockTemplateCapabilities] as an argument for get_block_template()?

I am trying to get the block template of my core node so I can implement this in rust.

https://code.samourai.io/oxt/one_dollar_fee_estimator/-/blob/master/one_dollar_fee_estimator/estimator.py

Below is my code that wont compile and I can't figure out how to use the rpc call correctly just from looking at the docs.

How would I supply the get block template call with the correct capabilities? Looks like I need to get a value from the enum to put in the array but I can't figure out how to invoke one from the docs.

This is the function signature that I copied from the docs.
fn get_block_template(
&self,
mode: GetBlockTemplateModes,
rules: &GetBlockTemplateRules[],
capabilities: &GetBlockTemplateCapabilities[]
) -> Result<GetBlockTemplateResult>

This is my code that I am trying to get running.

use std::error::Error;
use bitcoincore_rpc::RpcApi;
fn main() -> Result<(), Box<dyn Error>> {
    let client = bitcoincore_rpc::Client::new("http://127.0.0.1:38333",bitcoincore_rpc::Auth::UserPass("".to_string(), "".to_string()))?;
    let mode = bitcoincore_rpc::json::GetBlockTemplateModes::Template;
    let rules = &[bitcoincore_rpc::json::GetBlockTemplateRules::Signet, bitcoincore_rpc::json::GetBlockTemplateRules::Taproot, bitcoincore_rpc::json::GetBlockTemplateRules::SegWit, bitcoincore_rpc::json::GetBlockTemplateRules::Csv];
    let capabilities = bitcoincore_rpc::json::GetBlockTemplateCapabilities;
    let rpc = client.get_block_template(mode, rules, capabilities);
    Ok(())
}

I also tried lookind up this example but I think its no longer valid (or at least it wont compile for me.

#163 (comment)

this is my cargo.toml for reference

[package]
name = "one-dollar-estimator"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
statistical = "1.0.0"
ringbuf = "0.2.8"
bitcoincore-rpc = "0.14.0"
bitcoincore-rpc-json = "0.14.0"

Appreciate any pointers, not sure what I am doing wrong here.

Decoding/encoding PSBT

I looked at changing the API to encode/decode PSBTs, which would be much more convenient and less error-prone, however I hit this problem:

the trait `Eq` is not implemented for `PartiallySignedTransaction`

So it seems requests and responses derive Eq. I'm not sure what's the best way to approach this:

  • Remove Eq from requests and responses - hopefully nobody uses them as keys into maps?
  • impl Eq for PartiallySignedTransaction in rust-bitcoin, but why it isn't there already?
  • impl Eq for ... manually (no derive), but maybe it's incorrect for the same reason it's already not present on PartiallySignedTransaction?
  • Give up - maybe what I'm doing is not that great idea? :)

Error when initially connecting peers

It is sometimes the case that when initially connecting to peers they report a startingheight of -1. Also, the pingtime field can occasionally be entirely absent. Here is an example peer that causes both problems. These usually resolve after a few seconds to minutes but in both cases there will be a JSON parse error and the entire get_peer_info() fails and becomes useless until they establish fully or are removed.

The pingtime field should be optional and the startingheight should be able to cope with a value of -1 (eg not u64).

  {
    "id": 15,
    "addr": "95.216.100.186:18333",
    "addrbind": "172.17.0.13:37250",
    "services": "0000000000000000",
    "servicesnames": [
    ],
    "relaytxes": false,
    "lastsend": 1590116798,
    "lastrecv": 0,
    "bytessent": 128,
    "bytesrecv": 0,
    "conntime": 1590116798,
    "timeoffset": 0,
    "version": 0,
    "subver": "",
    "inbound": false,
    "addnode": false,
    "startingheight": -1,
    "banscore": 0,
    "synced_headers": -1,
    "synced_blocks": -1,
    "inflight": [
    ],
    "whitelisted": false,
    "permissions": [
    ],
    "minfeefilter": 0.00000000,
    "bytessent_per_msg": {
      "version": 128
    },
    "bytesrecv_per_msg": {
    }
  }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.