Giter Site home page Giter Site logo

davidson-souza / floresta Goto Github PK

View Code? Open in Web Editor NEW
129.0 7.0 27.0 1.79 MB

A fully-validating Bitcoin node powered by Utreexo, with an integrated Electrum Server

License: MIT License

Rust 92.03% Dockerfile 0.07% Python 7.22% Just 0.13% Shell 0.12% Nix 0.43%
rust bitcoin wallet

floresta's Introduction

Floresta

Welcome to Floresta, a lightweight Bitcoin full node implementation written in Rust, powered by Utreexo a novel dynamic accumulator designed for the Bitcoin UTXO set.

This project is composed of two parts, libfloresta and florestad. libfloresta is a set of reusable components that can be used to build Bitcoin applications. florestad is built on top of libfloresta to provide a full node implementation, including a watch-only wallet and an Electrum server. If you just want to run a full node, you can use florestad directly, either by building it from source or by downloading a pre-built binary from the releases.

If you want to use libfloresta to build your own Bitcoin application, you can find the documentation here.

Community

If you want to discuss this project, you can join our Discord server here.

Building

You'll need Rust and Cargo, refer to this for more details. Minimum support version is rustc 1.74 and newer.

Once you have Cargo, clone the repository with:

git clone https://github.com/Davidson-Souza/Floresta.git

go to the Floresta directory

cd Floresta/

and build with cargo build

cargo build --release --bin florestad
# Optionally, you can add florestad to the path with
cargo install --path ./florestad

Building with nix

If you're using Nix, you can add Florestad to your system with its overlay.

{
  #Here you declare the import for your flake
  inputs.florestad = {
    url = "github:Davidson-Souza/Floresta";
    inputs = {
      nixpkgs.follows = "nixpkgs";
      flake-parts.follows = "flake-parts";
    };
  };

  outputs = inputs @ { self, ... }:
  {
    imports = [
      {
        nixpkgs.overlays = [
          # Here you use the floresta overlay with your others
          inputs.florestad.overlays.default
        ];
      }
    ];
  };

then Florestad will be available just like any other package with

pkgs.florestad

But if you just want to test it or quickly run a instance you can do

$ nix run github:Davidson-Souza/Floresta

Running

Right now, this project is working on signet only. Mainnet support is still a todo thing. You can get some signet coins here and just play around with it. Copy config.toml.sample to config.toml, and fill up your xpubs and addresses that you intend to track, and then run with

florestad -c config.toml --network signet run

or

./target/release/florestad -c config.toml --network signet run

or

cargo run --release -- -c config.toml --network signet run

Running the tests

Requirements

cargo build

There's a set of unit tests that you can run with

cargo test

There's also a set of functional tests that you can run with

pip3 install -r tests/requirements.txt
python tests/run_tests.py

Contributing

Contributions are welcome, feel free to open an issue or a pull request.

If you want to contribute but don't know where to start, take a look at the issues, there's a few of them marked as good first issue.

Here's some Guidelines:

  • Has to compile.
  • Has to run.
  • Use pre-commit for the language that you're using (if possible ๐Ÿ‘).

You can accomplish that using our flake.nix for development.

Using Nix

If you already have Nix you just need to do:

    $ nix develop

and use our flake for development with include

  • nix(fmt) and rust(fmt) pre-commit.
  • Rust Msrv(1.74.0).
  • Clippy and some libs so rust can compile.
  • Typos for good spelling.

If you do not have Nix Check their guide.

License

This project is licensed under the MIT License - see the LICENSE file for details

Acknowledgments

Consensus implementation

One of the most challenging parts of working with Bitcoin is keeping up with the consensus rules. Given it's nature as a consensus protocol, it's very important to make sure that the implementation is correct. Instead of reimplementing a Script interpreter, we use rust-bitcoinconsensus to verify transactions. This is a bind around a shared library that is part of Bitcoin Core. This way, we can be sure that the consensus rules are the same as Bitcoin Core, at least for scripts.

Although tx validation is arguably the hardest part in this process. This integration can be further improved by using libbitcoinkernel, that will increase the scope of libbitcoinconsensus to outside scripts, but this is still a work in progress.

floresta's People

Contributors

a-moreira avatar bitkarrot avatar davidson-souza avatar douglaz avatar guilospanck avatar jaoleal avatar jaonoctus avatar joaothallis avatar josesk999 avatar kcalvinalvin avatar lla-dane avatar lord2anil avatar mystical-prog avatar osauravo avatar vikaass-08 avatar

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

floresta's Issues

Standardize Error Handling

We currently use multiple error handling crates like anyhow, thiserror, and also custom macros.
It'd be good to standardize this and pick one option.

Error running tests

My setup:
OS: Ubuntu 22.04.4 LTS x86_64
Kernel: 5.15.0-105-generic
Intel i7-10610U (8) @ 4.900GHz

cargo version
cargo 1.74.1 (ecb9851af 2023-10-18)

Steps:

cargo build --release --bin florestad
cargo test
warning: skipping duplicate package `embedded` found at `/home/joao/.cargo/git/checkouts/rust-bitcoin-ee9cd636efadd047/eb5d7a3/hashes/embedded`
   Compiling libc v0.2.153
   Compiling syn v2.0.58
   Compiling cc v1.0.92
   Compiling futures v0.1.31
   Compiling hex-conservative v0.1.1
   Compiling concurrent-queue v2.4.0
   Compiling typenum v1.17.0
   Compiling bitcoin v0.31.0 (https://github.com/Davidson-Souza/rust-bitcoin?rev=eb5d7a3896fff0ebf6394dabc882d46e439695be#eb5d7a38)
   Compiling generic-array v0.14.7
   Compiling bech32 v0.10.0-beta
   Compiling parking_lot_core v0.8.6
   Compiling ryu v1.0.17
   Compiling instant v0.1.12
   Compiling fastrand v2.0.2
   Compiling serde_json v1.0.115
   Compiling rustix v0.38.32
   Compiling linux-raw-sys v0.4.13
   Compiling syn v1.0.109
   Compiling num_cpus v1.16.0
   Compiling event-listener v4.0.3
   Compiling parking_lot v0.11.2
   Compiling secp256k1-sys v0.9.2
   Compiling bitcoinconsensus v0.20.2-0.5.0
   Compiling cpufeatures v0.2.12
   Compiling block-buffer v0.10.4
   Compiling crypto-common v0.1.6
   Compiling crc32fast v1.4.0
   Compiling bitcoin-private v0.1.0
   Compiling digest v0.10.7
   Compiling sha2 v0.10.8
   Compiling event-listener-strategy v0.4.0
   Compiling spin v0.9.8
   Compiling thiserror v1.0.58
   Compiling ppv-lite86 v0.2.17
   Compiling byteorder v1.5.0
   Compiling fxhash v0.2.1
   Compiling async-lock v3.3.0
   Compiling fs2 v0.4.3
   Compiling futures-lite v2.3.0
   Compiling event-listener v5.3.0
   Compiling crossbeam-epoch v0.9.18
   Compiling io-lifetimes v1.0.11
   Compiling sled v0.34.7
   Compiling event-listener-strategy v0.5.1
   Compiling bitcoin_hashes v0.12.0
   Compiling polling v2.8.0
   Compiling rustix v0.37.27
   Compiling event-listener v2.5.3
   Compiling serde_derive v1.0.197
   Compiling futures-macro v0.3.30
   Compiling thiserror-impl v1.0.58
   Compiling async-task v4.7.0
   Compiling atomic-waker v1.1.2
   Compiling piper v0.2.1
   Compiling polling v3.6.0
   Compiling futures-util v0.3.30
   Compiling async-channel v2.2.0
   Compiling socket2 v0.4.10
   Compiling async-io v1.13.0
   Compiling bitflags v1.3.2
   Compiling waker-fn v1.1.1
   Compiling linux-raw-sys v0.3.8
   Compiling fastrand v1.9.0
   Compiling futures-lite v1.13.0
   Compiling blocking v1.5.1
   Compiling async-io v2.3.2
   Compiling async-executor v1.10.0
   Compiling async-lock v2.8.0
   Compiling getrandom v0.2.14
   Compiling parking_lot_core v0.9.9
   Compiling serde v1.0.197
   Compiling futures-executor v0.3.30
   Compiling futures v0.3.30
   Compiling rand_core v0.6.4
   Compiling async-global-executor v2.4.1
   Compiling async-attributes v1.1.2
   Compiling async-channel v1.9.0
   Compiling kv-log-macro v1.0.7
   Compiling bytes v1.6.0
   Compiling rand_chacha v0.3.1
   Compiling async-std v1.12.0
   Compiling rustreexo v0.1.0
   Compiling core2 v0.4.0
   Compiling pkg-config v0.3.30
   Compiling parking_lot v0.12.1
   Compiling rand v0.8.5
   Compiling tokio-macros v2.2.0
   Compiling signal-hook-registry v1.4.1
   Compiling socket2 v0.5.6
   Compiling mio v0.8.11
   Compiling hex v0.4.3
   Compiling fnv v1.0.7
   Compiling bitcoin-internals v0.2.0
   Compiling bitcoin_hashes v0.13.0
   Compiling toml v0.5.11
   Compiling tinyvec_macros v0.1.1
   Compiling tinyvec v1.6.0
   Compiling http v0.2.12
   Compiling tokio v1.37.0
   Compiling dns-lookup v1.0.8
   Compiling httparse v1.8.0
   Compiling kv v0.24.0
   Compiling secp256k1 v0.28.2
   Compiling equivalent v1.0.1
   Compiling hashbrown v0.14.3
   Compiling oneshot v0.1.6
   Compiling unicode-normalization v0.1.23
   Compiling try-lock v0.2.5
   Compiling unicode-bidi v0.3.15
   Compiling want v0.3.1
   Compiling http-body v0.4.6
   Compiling indexmap v2.2.6
   Compiling vcpkg v0.2.15
   Compiling httpdate v1.0.3
   Compiling tower-service v0.3.2
   Compiling getrandom v0.1.16
   Compiling utf8parse v0.2.1
   Compiling anstyle-parse v0.2.3
   Compiling anstyle v1.0.6
   Compiling colorchoice v1.0.0
   Compiling anstyle-query v1.0.2
   Compiling lazy_static v1.4.0
   Compiling anstream v0.6.13
   Compiling secp256k1-sys v0.8.1
   Compiling strsim v0.11.1
   Compiling clap_lex v0.7.0
   Compiling foreign-types-shared v0.1.1
   Compiling anyhow v1.0.81
   Compiling openssl-sys v0.9.102
   Compiling heck v0.5.0
   Compiling openssl v0.10.64
   Compiling clap_derive v4.5.4
   Compiling foreign-types v0.3.2
   Compiling clap_builder v4.5.2
   Compiling rand_core v0.5.1
   Compiling jsonrpc-core v18.0.0
   Compiling openssl-macros v0.1.1
   Compiling native-tls v0.2.11
   Compiling tokio-util v0.7.10
   Compiling rand_chacha v0.2.2
   Compiling h2 v0.3.26
   Compiling clap v4.5.4
   Compiling unicase v2.7.0
   Compiling aho-corasick v1.1.3
   Compiling percent-encoding v2.3.1
   Compiling miniscript v11.0.0
   Compiling cfg_aliases v0.1.1
   Compiling hyper v0.14.28
   Compiling matches v0.1.10
   Compiling floresta-common v0.1.0 (/home/joao/Projects/Floresta/crates/floresta-common)
   Compiling openssl-probe v0.1.5
   Compiling bitcoin v0.30.2
   Compiling regex-syntax v0.8.3
   Compiling floresta-watch-only v0.1.0 (/home/joao/Projects/Floresta/crates/floresta-watch-only)
   Compiling idna v0.1.5
   Compiling nix v0.28.0
   Compiling secp256k1 v0.27.0
   Compiling regex-automata v0.4.6
   Compiling form_urlencoded v1.2.1
   Compiling rand v0.7.3
   Compiling zstd-sys v2.0.10+zstd.1.5.6
   Compiling bstr v1.9.1
   Compiling num-traits v0.2.18
   Compiling percent-encoding v1.0.1
   Compiling convert_case v0.4.0
   Compiling bech32 v0.9.1
   Compiling url v1.7.2
   Compiling jsonrpc-pubsub v18.0.0
   Compiling derive_more v0.99.17
   Compiling globset v0.4.14
   Compiling tokio-native-tls v0.3.1
   Compiling tokio-util v0.6.10
   Compiling tokio-stream v0.1.15
   Compiling idna v0.5.0
   Compiling is-terminal v0.4.12
   Compiling cfg-if v0.1.10
   Compiling base64 v0.21.7
   Compiling proc-macro-crate v0.1.5
   Compiling rustls-pemfile v1.0.4
   Compiling net2 v0.2.39
   Compiling colored v1.9.4
   Compiling url v2.5.0
   Compiling jsonrpc-server-utils v18.0.0
   Compiling miniscript v10.0.0
   Compiling hyper-tls v0.5.0
   Compiling jsonrpc-client-transports v18.0.0
   Compiling serde_urlencoded v0.7.1
   Compiling dirs-sys v0.3.7
   Compiling encoding_rs v0.8.33
   Compiling mime v0.3.17
   Compiling iana-time-zone v0.1.60
   Compiling sync_wrapper v0.1.2
   Compiling ipnet v2.9.0
   Compiling zstd-safe v6.0.6
   Compiling ctrlc v3.4.4
   Compiling chrono v0.4.37
   Compiling dirs v4.0.0
   Compiling jsonrpc-core-client v18.0.0
   Compiling jsonrpc-derive v18.0.0
   Compiling jsonrpc-http-server v18.0.0
   Compiling reqwest v0.11.27
   Compiling fern v0.6.2
   Compiling diff v0.1.13
   Compiling latest v0.1.1
   Compiling yansi v0.5.1
   Compiling floresta-chain v0.1.0 (/home/joao/Projects/Floresta/crates/floresta-chain)
   Compiling pretty_assertions v1.4.0
   Compiling tempfile v3.10.1
   Compiling floresta-cli v0.1.0 (/home/joao/Projects/Floresta/crates/floresta-cli)
   Compiling floresta-wire v0.1.0 (/home/joao/Projects/Floresta/crates/floresta-wire)
   Compiling floresta-compact-filters v0.1.0 (/home/joao/Projects/Floresta/crates/floresta-compact-filters)
   Compiling zstd v0.12.4
warning: struct `ReqwestConfig` is never constructed
  --> crates/floresta-cli/src/reqwest_client.rs:15:12
   |
15 | pub struct ReqwestConfig {
   |            ^^^^^^^^^^^^^
   |
   = note: `#[warn(dead_code)]` on by default

warning: associated functions `new` and `new_with_config` are never used
  --> crates/floresta-cli/src/reqwest_client.rs:24:12
   |
23 | impl ReqwestClient {
   | ------------------ associated functions in this implementation
24 |     pub fn new(url: String) -> Self {
   |            ^^^
...
31 |     pub fn new_with_config(config: ReqwestConfig) -> Self {
   |            ^^^^^^^^^^^^^^^

warning: `floresta-cli` (bin "floresta-cli" test) generated 2 warnings
   Compiling floresta-electrum v0.1.0 (/home/joao/Projects/Floresta/crates/floresta-electrum)
   Compiling florestad v0.5.1 (/home/joao/Projects/Floresta/florestad)
   Compiling floresta v0.1.0 (/home/joao/Projects/Floresta/crates/floresta)
warning: use of deprecated method `bitcoin::Block::strippedsize`: use Block::base_size() instead
   --> florestad/src/json_rpc/server.rs:378:41
    |
378 |                     strippedsize: block.strippedsize(),
    |                                         ^^^^^^^^^^^^
    |
    = note: `#[warn(deprecated)]` on by default

warning: `florestad` (lib) generated 1 warning
warning: `florestad` (lib test) generated 1 warning (1 duplicate)
warning: `florestad` (bin "florestad" test) generated 1 warning (1 duplicate)
    Finished test [unoptimized + debuginfo] target(s) in 1m 56s
     Running unittests src/lib.rs (target/debug/deps/floresta-458519f5c59201a2)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running unittests src/lib.rs (target/debug/deps/floresta_chain-ba5f9b27e7a973c2)

running 10 tests
test pruned_utreexo::chain_state::test::test_calc_next_work_required ... ok
test pruned_utreexo::partial_chain::tests::test_with_invalid_block ... ok
test pruned_utreexo::udata::test::test_spk_recovery ... ok
test test::test_network ... ok
test pruned_utreexo::udata::test::test_reconstruct_leaf_data ... ok
test pruned_utreexo::partial_chain::tests::test_updating_single_chain ... ok
test pruned_utreexo::partial_chain::tests::test_updating_multiple_chains ... ok
test pruned_utreexo::chain_state::test::test_reorg ... ok
test pruned_utreexo::chain_state::test::accept_first_signet_headers ... ok
test pruned_utreexo::chain_state::test::accept_mainnet_headers ... ok

test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 22.19s

     Running unittests src/lib.rs (target/debug/deps/floresta_cli-7064cbf3de43361c)

running 11 tests
test tests::test_get_block ... FAILED
test tests::test_get_block_hash ... FAILED
test tests::test_get_block_filter ... FAILED
test tests::test_get_block_header ... FAILED
test tests::test_load_descriptor ... FAILED
test tests::test_get_blockchaininfo ... FAILED
test tests::test_send_raw_transaction ... FAILED
test tests::test_get_height ... FAILED
test tests::test_rescan ... FAILED
test tests::test_stop ... FAILED
test tests::test_get_roots ... FAILED

failures:

---- tests::test_get_block stdout ----
thread 'tests::test_get_block' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- tests::test_get_block_hash stdout ----
thread 'tests::test_get_block_hash' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_get_block_filter stdout ----
thread 'tests::test_get_block_filter' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_get_block_header stdout ----
thread 'tests::test_get_block_header' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_load_descriptor stdout ----
thread 'tests::test_load_descriptor' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_get_blockchaininfo stdout ----
thread 'tests::test_get_blockchaininfo' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_send_raw_transaction stdout ----
thread 'tests::test_send_raw_transaction' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_get_height stdout ----
thread 'tests::test_get_height' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_rescan stdout ----
thread 'tests::test_rescan' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_stop stdout ----
thread 'tests::test_stop' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

---- tests::test_get_roots stdout ----
thread 'tests::test_get_roots' panicked at crates/floresta-cli/src/lib.rs:76:14:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }


failures:
    tests::test_get_block
    tests::test_get_block_filter
    tests::test_get_block_hash
    tests::test_get_block_header
    tests::test_get_blockchaininfo
    tests::test_get_height
    tests::test_get_roots
    tests::test_load_descriptor
    tests::test_rescan
    tests::test_send_raw_transaction
    tests::test_stop

test result: FAILED. 0 passed; 11 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `-p floresta-cli --lib`

I am not running florestad but for what I see in the CI, it is only require to build

Running with log_to_file as false returns the same error

bug: can't parse the udata on a mainnet block

There's something weird with our rust-bitcoin fork that makes it break while processing block 0000000000000000000143b4f110579e1289e6874322cedcb9c6e694f943dff6. It parses the actual block, but it EOF for the udata.

I made it work by not using rust-bitcoin's macros, like this

impl Decodable for UtreexoBlock {
    fn consensus_decode<R: std::io::Read + ?Sized>(
        mut ser_block: &mut R
    ) -> Result<Self, crate::consensus::encode::Error> {
        let block = Block::consensus_decode(&mut ser_block)?; 
        let remember = VarInt::consensus_decode(&mut ser_block)?;
        
        let  n_positions = VarInt::consensus_decode(&mut ser_block)?;
        let mut targets = vec![];
        for _ in 0..n_positions.0 {
            let pos = VarInt::consensus_decode(&mut ser_block)?;
            targets.push(pos);
        }

        let n_hashes  = VarInt::consensus_decode(&mut ser_block)?;
        let mut hashes = vec![];
        for _ in 0..n_hashes.0 {
            let hash = BlockHash::consensus_decode(&mut ser_block)?;
            hashes.push(hash);
        }

        let n_leaves = VarInt::consensus_decode(&mut ser_block)?;
        let mut leaves = vec![];
        for _ in 0..n_leaves.0 {
            let header_code = u32::consensus_decode(&mut ser_block)?;
            let amount = u64::consensus_decode(&mut ser_block)?;
            let spk_ty =  ScriptPubkeyType::consensus_decode(&mut ser_block)?;

            leaves.push(CompactLeafData {
                header_code,
                amount,
                spk_ty,
            });
        }

        Ok(Self {
            block,
            udata:Some(UData {
                remember_idx: vec![],
                proof: BatchProof {
                    targets, 
                    hashes,
                },
                leaves, 
            })
        })
    }
}

But it would be nice to find out why it's not working with the automatic implementations. I think the problem is when parsing the hashes, as things after that get messed-up (like the recovered number of leaf data is small, probably due to reading in the wrong place).

If someone wants to dig this out, here's the message that gave us this block. You can get the actual block by reading from bytes 24 onwards. Here's a small rust code that attempts to decode that block (remember to add bitcoin = { git = "https://github.com/Davidson-Souza/rust-bitcoin", rev = "eb5d7a3896fff0ebf6394dabc882d46e439695be" } to your Cargo.toml)

use bitcoin::{consensus::{deserialize_partial, Decodable}, hex::DisplayHex, p2p::utreexo::UtreexoBlock, Block, VarInt};


fn main() {
    let ser_block = &std::fs::read("./block").unwrap()[24..];
    let (block, len): (UtreexoBlock, usize) = deserialize_partial(ser_block).unwrap();
    assert!(block.udata.is_some()); // <--- this is panic-ing out, but shouldn't
}

Docs link broken

In the readme, the link in

If you want to use libfloresta to build your own Bitcoin application, you can find the documentation [here](https://docs.rs/floresta/).

here is linking to https://docs.rs/floresta/ but it's broken.

Proof-of-Work fraud proof: Tracker issue

Proof-of-work fraud proof is a mechanism to allow light clients to have better security, without requiring full validation. For more info on how it works, take a look at my blogpost. However, the general workflow is rather simple:

  • Client connects with multiple peers
    • Ask what they think is the best chain
    • If they all agree, cool!
    • If they don't agree:
      • Find the fork point and verify the heavier chain candidate:
        • If valid, pick this chain
        • pick the other one otherwise
    • If they all agree, just follow the consensus

This is fundamentally better than simple SPV because even a hashrate majority can't make the client accept invalid blocks because a small (say ~20% of the hashrate) fork off and the light client can spot that. If you want to fool a light client you'd need either (i) 100% majority OR (ii) Sybil attack the light client. Both (i) and (ii) are already assumed to be difficult to pull off, even for full nodes, so the chance of you being successfully attacked is close to negligible.

What do we need?

Currently, neither Chainstate nor UtreexoNode really expects our peers to disagree on what is the best chain, so we need to fix that. We also need to let our client find forks and validate it as we go. A non-exhaustive (may be updated) list of requirements is:

  • During IBD, ask headers for multiple peers
  • IBDNode checks if a header extends our tip, if it does, nbd. If it doesn't then we:
    • Check the depth of this fork, the number of blocks we expect is a configurable parameter
  • If we ever find a fork that may be of interest, we need to:
    • Find the forking point
    • Find the correct state for that block
    • Validate the current best block with this state (we need a validate_with_state method). If this block is valid, nothing changes. If this block is invalid, we need to invalidate it and switch to the new chain
  • Implement a binary search logic to find the current state
  • Implement a new BIP-157 filter type for utreexo roots

Sparrow compatibility

Description

While using Sparrow to sync my wallet, I encountered a few issues with the balance and UTXO history. Specifically, the balance on the Transactions tab was displaying as zero, and there were inconsistencies in the UTXO history. Despite this, my Electrum wallet was working like a charm.

I'm willing to provide any data or assist with testing to help diagnose the problem.

feature: log to file

Right now, we only save our logs to stdout, but it would be useful to log to a log file as well

Error running `floresta`

It worked one time, after it, it is returning this error

My setup:
OS: Ubuntu 22.04.4 LTS x86_64
Kernel: 5.15.0-105-generic
Intel i7-10610U (8) @ 4.900GHz

cargo version
cargo 1.74.1 (ecb9851af 2023-10-18)

Steps:

cp config.toml.sample config.toml
cargo build --release --bin florestad
RUST_BACKTRACE=1 florestad -c config.toml --network signet run
[2024-05-04 09:02:42 INFO florestad::florestad] Wallet setup completed!
[2024-05-04 09:02:42 INFO florestad::florestad] loading blockchain database
[2024-05-04 09:02:42 INFO floresta_chain::pruned_utreexo::chain_state] Chainstate loaded at height: 000000c7fa8f2606058cf5a3f4a5eb343032baff2d89582ad857ae6c87f666c1, checking if we have all blocks
[2024-05-04 09:02:43 INFO florestad::florestad] Starting server
[2024-05-04 09:02:43 INFO florestad::json_rpc::server] Starting JSON-RPC server on 127.0.0.1:38332
[2024-05-04 09:02:43 INFO florestad::florestad] Server running on: 0.0.0.0:50001
[2024-05-04 09:02:43 INFO floresta_wire::p2p_wire::address_man] Peers database found, using it
[2024-05-04 09:02:43 INFO floresta_wire::p2p_wire::chain_selector] Starting ibd, selecting the best chain
[2024-05-04 09:02:43 INFO floresta_wire::p2p_wire::node] New peer id=0 version=/Satoshi:25.0.0/ blocks=194069 services=ServiceFlags(NETWORK|WITNESS|COMPACT_FILTERS|NETWORK_LIMITED)
[2024-05-04 09:02:44 INFO floresta_wire::p2p_wire::chain_selector] Downloading headers from peer=0 at height=194030 hash=0000014bd362a5579a456171652bf60425c3ab9ba2b4a0a2572cbff8fac6cd0c
thread 'async-std/runtime' panicked at /home/joao/Projects/Floresta/crates/floresta-wire/src/p2p_wire/chain_selector.rs:422:9:
assertion `left == right` failed
  left: 0
 right: 1
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
   4: floresta_wire::p2p_wire::chain_selector::<impl floresta_wire::p2p_wire::node::UtreexoNode<floresta_wire::p2p_wire::chain_selector::ChainSelector,Chain>>::find_accumulator_for_block::{{closure}}
   5: floresta_wire::p2p_wire::chain_selector::<impl floresta_wire::p2p_wire::node::UtreexoNode<floresta_wire::p2p_wire::chain_selector::ChainSelector,Chain>>::handle_notification::{{closure}}
   6: floresta_wire::p2p_wire::running_node::<impl floresta_wire::p2p_wire::node::UtreexoNode<floresta_wire::p2p_wire::running_node::RunningNode,Chain>>::run::{{closure}}
   7: <core::pin::Pin<P> as core::future::future::Future>::poll
   8: async_task::raw::RawTask<F,T,S,M>::run
   9: <futures_lite::future::Or<F1,F2> as core::future::future::Future>::poll
  10: async_io::driver::block_on
  11: async_global_executor::threading::thread_main_loop
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

With RUST_BACKTRACE=full:

RUST_BACKTRACE=full florestad -c config.toml --network signet run
[2024-05-04 09:05:55 INFO florestad::florestad] Wallet setup completed!
[2024-05-04 09:05:55 INFO florestad::florestad] loading blockchain database
[2024-05-04 09:05:55 INFO floresta_chain::pruned_utreexo::chain_state] Chainstate loaded at height: 000000c7fa8f2606058cf5a3f4a5eb343032baff2d89582ad857ae6c87f666c1, checking if we have all blocks
[2024-05-04 09:05:55 INFO florestad::florestad] Starting server
[2024-05-04 09:05:55 INFO florestad::json_rpc::server] Starting JSON-RPC server on 127.0.0.1:38332
[2024-05-04 09:05:55 INFO florestad::florestad] Server running on: 0.0.0.0:50001
[2024-05-04 09:05:55 INFO floresta_wire::p2p_wire::address_man] Peers database found, using it
[2024-05-04 09:05:55 INFO floresta_wire::p2p_wire::chain_selector] Starting ibd, selecting the best chain
[2024-05-04 09:05:56 INFO floresta_wire::p2p_wire::node] New peer id=0 version=/Satoshi:26.0.0/ blocks=194069 services=ServiceFlags(NETWORK|WITNESS|NETWORK_LIMITED)
[2024-05-04 09:05:56 INFO floresta_wire::p2p_wire::chain_selector] Downloading headers from peer=0 at height=194030 hash=0000014bd362a5579a456171652bf60425c3ab9ba2b4a0a2572cbff8fac6cd0c
thread 'async-std/runtime' panicked at /home/joao/Projects/Floresta/crates/floresta-wire/src/p2p_wire/chain_selector.rs:422:9:
assertion `left == right` failed
  left: 0
 right: 1
stack backtrace:
   0:     0x55d12bf24e5c - std::backtrace_rs::backtrace::libunwind::trace::ha69d38c49f1bf263
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x55d12bf24e5c - std::backtrace_rs::backtrace::trace_unsynchronized::h93125d0b85fd543c
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x55d12bf24e5c - std::sys_common::backtrace::_print_fmt::h8d65f438e8343444
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x55d12bf24e5c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h41751d2af6c8033a
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x55d12bf51f4c - core::fmt::rt::Argument::fmt::h5db2f552d8a28f63
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/rt.rs:138:9
   5:     0x55d12bf51f4c - core::fmt::write::h99465148a27e4883
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/mod.rs:1114:21
   6:     0x55d12bf2131e - std::io::Write::write_fmt::hee8dfd57bd179ab2
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/io/mod.rs:1763:15
   7:     0x55d12bf24c44 - std::sys_common::backtrace::_print::h019a3cee3e814da4
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x55d12bf24c44 - std::sys_common::backtrace::print::h55694121c2ddf918
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x55d12bf264f3 - std::panicking::default_hook::{{closure}}::h29cbe3da3891b0b0
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:272:22
  10:     0x55d12bf26214 - std::panicking::default_hook::h881e76b2b8c74280
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:292:9
  11:     0x55d12bf26a75 - std::panicking::rust_panic_with_hook::hcc36e25b6e33969c
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:731:13
  12:     0x55d12bf26971 - std::panicking::begin_panic_handler::{{closure}}::ha415efb0f69f41f9
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:609:13
  13:     0x55d12bf25386 - std::sys_common::backtrace::__rust_end_short_backtrace::h395fe90f99451e4e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:170:18
  14:     0x55d12bf266c2 - rust_begin_unwind
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
  15:     0x55d12b950845 - core::panicking::panic_fmt::h452a83e54ecd764e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
  16:     0x55d12b950bab - core::panicking::assert_failed_inner::h878b898cfe1c2eaf
  17:     0x55d12b92874f - core::panicking::assert_failed::h1b208d912c36d142
  18:     0x55d12b9649a1 - floresta_wire::p2p_wire::chain_selector::<impl floresta_wire::p2p_wire::node::UtreexoNode<floresta_wire::p2p_wire::chain_selector::ChainSelector,Chain>>::find_accumulator_for_block::{{closure}}::h280aae44891fe40f
  19:     0x55d12b95ef7d - floresta_wire::p2p_wire::chain_selector::<impl floresta_wire::p2p_wire::node::UtreexoNode<floresta_wire::p2p_wire::chain_selector::ChainSelector,Chain>>::handle_notification::{{closure}}::h5c143850c750cfd8
  20:     0x55d12b956ffe - floresta_wire::p2p_wire::running_node::<impl floresta_wire::p2p_wire::node::UtreexoNode<floresta_wire::p2p_wire::running_node::RunningNode,Chain>>::run::{{closure}}::h70075de3df024f06
  21:     0x55d12ba5295d - <core::pin::Pin<P> as core::future::future::Future>::poll::heb67b3a14be98ffe
  22:     0x55d12b9995c2 - async_task::raw::RawTask<F,T,S,M>::run::h4c96fc353177bcac
  23:     0x55d12bce1baa - <futures_lite::future::Or<F1,F2> as core::future::future::Future>::poll::h35fa019b8124b128
  24:     0x55d12bcdacaa - async_io::driver::block_on::h0c44b0dabde400a8
  25:     0x55d12bcd9b87 - async_global_executor::threading::thread_main_loop::hc4bc2633e4ae1166
  26:     0x55d12bcd8e37 - std::sys_common::backtrace::__rust_begin_short_backtrace::h9a1a53723e7bb6f7
  27:     0x55d12bce4021 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h2c19735db59a3198
  28:     0x55d12bf2a655 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h51435299acd7166e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/boxed.rs:2007:9
  29:     0x55d12bf2a655 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h3f833c0a4926bdd4
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/boxed.rs:2007:9
  30:     0x55d12bf2a655 - std::sys::unix::thread::Thread::new::thread_start::h2c486d0230ab0d99
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys/unix/thread.rs:108:17
  31:     0x7fda4b7c9ac3 - start_thread
                               at ./nptl/pthread_create.c:442:8
  32:     0x7fda4b85b850 - __GI___clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
  33:                0x0 - <unknown>

Assume-Valid should be hardcoded and optional

In Bitcoin Core, Assume-Valid hashes are assessed as valid by the contributors, reviewers and maintainers, which users are already trusting.

It seems however that Floresta allows users to provide their own hashes, without passing the OSS process. This is different from what we call Assume-Valid, as users have to trust other third parties who provided these values. Also in the None case we default to those values from Core.

I think Assume-Valid should be a boolean, if true we should use hardcoded values (perhaps Floresta-specific), else we should validate all scripts.

[SoB]: Move Async-std to Tokio

Summer of Bitcoin 2024 Floresta Proposal

Description

Since Floresta is heavily based on async features to work properly and at the moment is using async-std, moving to Tokio is necessary for better development and maintenance.

Tokio

Is a Rust runtime that improves async in general and is well maintained than async-std. Providing better performance, ecosystem, features, scalability and etc...

Target Modules

the main modules(aka crates) that will avail and will be the focus of this issue is:

  • florestad

At /florestad
Which is the Floresta node itself that implement all the crates in /crates directory.

  • floresta-electrum

At /crates/floresta-electrum/
The Floresta's Electrum implementation based on Electrum Protocol.

  • floresta-wire

At /crates/floresta-wire/
utreexo-aware wire protocol made for floresta, used to fetch blocks and transactions and to broadcast transactions

Good to read about

The State of async Rust
Announcing libfloresta
Floresta's rustdocs
Tokio's docs

Expected results

  • no use of async_std in the mentioned Modules
  • wide use of Tokio crate
  • All test at /tests/run_test.py passes correctly

Mentor(s)

@Davidson-Souza

RPC server connection is erroring out

Cargo version returns 1.66.1. Built with cargo build --release.

When running the following command:

target/release/utreexo-wallet -c config.toml --network signet run

With the following config.toml:

[wallet]
xpubs = ["tpubDD6s1tg6NcMcH9hAkKmPYffDq2g9Uej4zNQzLZnQRuHQhYghCYRn2eduBGupAM1fqdTxdXNGFVbp3AxLBxRXivTHFsajy6ysGREfs6PRiSj"]

[rpc]
rpc_user = "calvin"
rpc_password = "calvin"
rpc_host = "127.0.0.1"
rpc_port = 38332

[misc]
external_sync = ""

I get the following output:

 2023-01-27T07:01:15.357Z INFO  utreexo_wallet > Wallet setup completed!
 2023-01-27T07:01:15.357Z INFO  utreexo_wallet > Unable to connect with rpc

In the test_rpc function, I modified it to print the error and am getting this:

JsonRpcError(Transport(HttpParseError))

The utreexod node responds ok when using the utreexoctl binary so it's not something on the utreexod side.

I recorded my terminal in case this helps. https://asciinema.org/a/92lKhJBQFfN0V2bU0wsbuknxt

Parallel sync. Project issue

One major feature of utreexo is allowing parallel sync efficiently. Parallel sync means that we can validate multiple blocks at the same time. This allows better usage of available resources, if compared to the usual linear syncing.

  • Partial chainstate: We could just use the normal chainstate, but locking would take much of the CPU time anyways. To avoid that, we'll use a smaller, application-specific chainstate, called PartialChain
    • Move some validation code out of chainstate, so we can reduce repetition: #62
    • Implement partial chain states with tests: #63
    • Allow creating multiple partial chain states from a chainstate: #127
  • Use partial chainstates in the node
  • Simplify the IBD node to only use the partial chainstate
  • Do Parallel IBD

Open Questions:

  • Multiple nodes with one chain each, or only one node with multiple chains?

Nixify Floresta

Nix is a package manager that grant to both parties, the user and developer, a more safe, reproducible and easier packaging method to share.

  • Flake for development.
  • Pure nix expression for building configurations. build.nix.
  • Include build.nix as a package output for Floresta's flake.

While making the nix support, is good to document the features and "How to's" with nix.

Feature request: addpeer/connect flag

For testing, it'd be nice to point a floresta node to my own utreexod node. In both btcd and bitcoind there's options to do this so would be nice to do the same for florestad.

Wallet setup errors out with invalid checksum error

I got a wpkh descriptor with bitcoin-cli getdescriptors

    {
      "desc": "wpkh([23d2e8e6/84'/1'/0']tpubDDAxUmWLXokZegPbwwdwEzhq5C6nA5a9osWUzQYGMcfZ2SBnMVKNYyQkAoCwhvYRQ7neUC1TekxFzqtVr7X5t8vEiG7ETU3rRQCmnYEDpKB/0/*)#vspjntgz",
      "timestamp": 1671260072,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },

When I feed this descriptor to bitcoin-cli with getdescriptorinfo, it says checksum is vspjntgz.

[I] calvin@bitcoin ~/b/r/r/t/debug> bitcoin-cli -signet -rpcuser=calvin -rpcpassword=calvin getdescriptorinfo 
"wpkh([23d2e8e6/84'/1'/0']tpubDDAxUmWLXokZegPbwwdwEzhq5C6nA5a9osWUzQYGMcfZ2SBnMVKNYyQkAoCwhvYRQ7neUC1TekxFzqtVr7X5t8vEiG7ETU3rRQCmnYEDpKB/0/*)#vspjntgz"
{
  "descriptor": "wpkh([23d2e8e6/84'/1'/0']tpubDDAxUmWLXokZegPbwwdwEzhq5C6nA5a9osWUzQYGMcfZ2SBnMVKNYyQkAoCwhvYRQ7neUC1TekxFzqtVr7X5t8vEiG7ETU3rRQCmnYEDpKB/0/*)#vspjntgz",          
  "checksum": "vspjntgz",
  "isrange": true,
  "issolvable": true,
  "hasprivatekeys": false
}

However, the utreexo-wallet binary is erroring out with the following error:

[I] calvin@bitcoin ~/b/r/r/t/debug> ./utreexo-wallet setup "wpkh([23d2e8e6/84'/1'/0']tpubDDAxUmWLXokZegPbwwdwEzhq5C6nA5a9osWUzQYGMcfZ2SBnMVKNYyQkAoCwhvYRQ7neUC1TekxFzqtVr7X5t8vEiG7ETU3rRQCmnYEDpKB/0/*)#vspjntgz" walletdir/                                        
thread 'main' panicked at 'Error while parsing descriptor: BadDescriptor("Invalid checksum 'vspjntgz/0/*)', expected 'dcnuq8nn'")', src/main.rs:173:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Fails to build on the latest commit

Cargo build gives me this error. Maybe you've not pushed things on the btcd_rpc repo.

error[E0432]: unresolved import `btcd_rpc::json_types::transaction::VerbosityOutput`
  --> src/blockchain/sync.rs:14:5
   |
14 | use btcd_rpc::json_types::transaction::VerbosityOutput;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `VerbosityOutput` in `transaction`

error[E0432]: unresolved import `btcd_rpc::json_types::transaction::VerbosityOutput`
  --> src/blockchain/mod.rs:17:5
   |
17 |     json_types::transaction::VerbosityOutput,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `VerbosityOutput` in `transaction`

Config files with valid toml files are erroring out

The sample config file contains quotations for all fields and so one may think they should create quotations for all fields.

[wallet]
xpubs = ["tpubDD6s1tg6NcMcH9hAkKmPYffDq2g9Uej4zNQzLZnQRuHQhYghCYRn2eduBGupAM1fqdTxdXNGFVbp3AxLBxRXivTHFsajy6ysGREfs6PRiSj"]

[rpc]
rpc_user = "calvin"
rpc_password = "calvin"
rpc_host = "127.0.0.1"
rpc_port = "38332"

[misc]
external_sync = ""

This however ends in an error:

 2023-01-27T06:54:26.421Z ERROR utreexo_wallet > Error while parsing config file, ignoring it

There's no specific error messages returned so it's hard to know what I'm doing wrong. Error goes away when you remove quotations from the rpc_port.

The below is with [misc] removed because I'm not using it.

[wallet]
xpubs = ["tpubDD6s1tg6NcMcH9hAkKmPYffDq2g9Uej4zNQzLZnQRuHQhYghCYRn2eduBGupAM1fqdTxdXNGFVbp3AxLBxRXivTHFsajy6ysGREfs6PRiSj"]

[rpc]
rpc_user = "calvin"
rpc_password = "calvin"
rpc_host = "127.0.0.1"
rpc_port = 38332

Also results in an error:

 2023-01-27T06:56:26.131Z ERROR utreexo_wallet > Error while parsing config file, ignoring it

Integration and unit tests

Some tests need to be executed outside the code, like the integration of florestad and electrum or unit tests for our json-rpc.

feat: Consensus Rules

After a talk with @Davidson-Souza was noticed that floresta lack "minimum" consensus rules that core has.

TODO:

  • Map implemented and not-implemented rules on floresta in comparison to core
  • Implement that ones that need to
  • implement all core test case about consensus
  • "Fuzz it" with bitcoinfuzz

Development Debts

After #176 i was alarmed by some development debt, which include:

  • Grammatical doc errors(discovered by typos.)
  • Incompatible Versions, such as
    • found crate miniscript compiled by an incompatible version of rustc
    • error: cannot determine resolution for the macro json
    • cannot find attribute serde in this scope
      all that captured by nightly clippy that ran by pre-commit and i wonder if that can be considered a bug since nightly is required for running fmt...

A proper fix to it is changing Actions(which enforce the use of nightly) and Pre-commit(Used so we do not have a surprise while being checked by Actions when pushing) to share the same version and behavior.

Dealing with nigthly directly is rough since is too unstable(Change every day), should we consider the use of beta for fmt ?
If nightly fmt is really required Ill mention the way that rust-bitcoin deal with it by reading their /.github files and scripts.

Declared version normalization

FROM rust:1.66.0@sha256:0067330b7e0eacacc5c32f21b720607c0cd61eda905c8d55e6a745f579ddeee9 as builder at dockerfile
[toolchain] channel = "1.74.1" at rust-toolchain.toml
You'll need Rust and Cargo, refer to [this](https://www.rust-lang.org/) for more details. Minimum support version is rustc 1.64 and newer. at README.md

So, since some dependencies that are already included to Floresta repository at all uses 1.74, Ill include the change of msrv to 1.74 in #159 In the mentioned files above

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.