Giter Site home page Giter Site logo

anastur / bidirectional-fastbtc Goto Github PK

View Code? Open in Web Editor NEW

This project forked from distributedcollective/bidirectional-fastbtc

0.0 0.0 0.0 1.42 MB

V5+ iteration of FastBTC with rBTC->BTC transfers

Shell 3.50% JavaScript 0.99% Python 1.04% TypeScript 79.08% CSS 0.38% Makefile 0.76% HTML 0.38% Dockerfile 0.61% Solidity 13.27%

bidirectional-fastbtc's Introduction

Bi-directional FastBTC

This repo contains the RSK to Bitcoin (rBTC to BTC) version of FastBTC. Despite the name, it does not (yet) handle Bitcoin to RSK (BTC to rBTC) transfers, as those are handled by the existing FastBTC.

It consists of two major parts:

  • fastbtc-contracts: A set of RSK smart contracts used to accept rBTC transfers and to track the transfer state to the Bitcoin network. Status updates are controlled by a network of federators, where signatures from a majority of federators is needed for new updates.
  • fastbtc-node: The backend service, a federator node that operates in a peer-to-peer network. The network tracks rBTC transfers on the contract and obtains a consensus of actions to do, sending BTC from a Bitcoin multisig wallet and updating status to the RSK smart contract. Signatures are exchanged off-chain to avoid gas costs, and various techniques are used to prevent double-spending.

High-level data flow

high-level data flow

User reclaiming

Users can reclaim sent rBTC back directly from the smart contract, as long as the transfer is still in the NEW state. Transfers in the SENDING state are potentially already sent to the Bitcoin network and thus cannot be reclaimed.

There's a configuration variable requiredBlocksBeforeReclaim that can be set to optionally require that a number of blocks have passed before reclaiming is possible. This is capped to max ~one week worth of RSK blocks (with 30s average block time).

Admins cannot withdraw rBTC still in the NEW state from the contract, but they can initiate a refund to the user.

Unit tests

To run unit tests in all packages, run:

make test

Integration test

The repo contains and integration test setup that deploys the contracts to a local Hardhat network, launches a local Bitcoin network using bitcoind regtest, creates a 2-of-3 multisig wallet on it, and launches a network of 3 federators. It requires docker-compose, and can be launched with:

make run-demo-regtest

For the first run, it can take ~20-30 minutes to build and start everything -- subsequent startups are faster. It will output a lot of logs. To only observe federator node logs, run the command make show-node-logs (in another terminal)

After the network has started, you should see output resembling this (with slight variations):

fastbtc2-node2-1            | node id:          7eNHnBNMeNxQIcetjAno8R
fastbtc2-node2-1            | initiator id:     1ZFfiFbX7kkMTVOkgj7x1D
fastbtc2-node2-1            | is initiator?     false
fastbtc2-node2-1            | nodes online:     3
fastbtc2-node2-1            | transfers total:  12
fastbtc2-node2-1            | not initiator, not doing anything

Note that before the network is fully operational, it's normal to see some messages that look like errors (e.g. "Invalid signature from server") in the logs.

After the startup is done, you can run an example script that sends a mixture of valid and invalid transfers (it requires node.js, yarn and bitcoin-cli (available in PATH either as bitcoin-cli or bitcoin-core.cli):

$ make test-transfers
... some yarn/hardhat logs about building ...
User balance before:        0.00000000 BTC
Multisig balance before:    0.00000000 BTC
Replenisher balance before: 550.00000000 BTC

Sending 5 rBTC (5000000000000000000 wei) to 0xB3b77A8Bc6b6fD93D591C0F34f202eC02e9af2e8
tx hash: 0xd3873623deb510a2c6552b9d5f76952aebae9ac55982e5d1b1b8a32df876e3b9
Sending 0.15 rBTC from 0xB3b77A8Bc6b6fD93D591C0F34f202eC02e9af2e8 to BTC address bcrt1qq8zjw66qrgmynrq3gqdx79n7fcchtaudq4rrf2 4 times
...
4 invalid transfers sent, followed by 4 transfers to proper addresses. They should be visible in a couple of minutes
Polling balances, Ctrl-C to exit
User: 0.00000000  Multisig: 0.00000000  Replenisher: 1100.00000000
User: 0.00000000  Multisig: 0.00000000  Replenisher: 1600.00000000
User: 0.00000000  Multisig: 0.00000000  Replenisher: 2100.00000000
...
User: 0.00000000  Multisig: 49.99997522  Replenisher: 5650.00000000
User: 0.59992000  Multisig: 49.40002110  Replenisher: 6200.00000000
User: 0.59992000  Multisig: 49.40002110  Replenisher: 6700.00000000
User: 0.59992000  Multisig: 49.40002110  Replenisher: 7200.00000000
User: 0.59992000  Multisig: 49.40002110  Replenisher: 7550.00002478

When the user balance increases, it indicates that the transfers went through properly. When the multisig balance icreases, it indicates that the multisig was replenished correctly from the replenisher multisig. The replenisher balance will increase every block.

Hit Ctrl-C to quit it (it doesn't quit automatically).

Other integration test cases

Reclaiming

There's also another script to test user reclaiming (semi-manually). Run it (after starting make run-demo-regtest) with:

$ make test-reclaiming

Observe the output, quit with Ctrl-C (it doesn't quit automatically).

Very small utxos in replenisher wallet

This test tests the case where the replenisher wallet has very small utxos, which would cause a replenisher transaction with 1000+ inputs if no special logic is applied.

# In one tab:
$ make run-demo-regtest-replenisher-very-small-coins
# In another tab
$ make test-transfers

Observe the output, quit with Ctrl-C (it doesn't quit automatically).

Replenisher limit edge cases

This test tests the case where the multisig has enough funds for the replenisher not to trigger, but not enough funds to send a naively-created TransferBatch, causing the whole system to get stuck.

Unlike the other test cases, this test requires ZSH to run and will quit automatically if it succeeds (otherwise it will go on forever).

# In one tab:
$ make run-demo-regtest-replenisher-limits
# In another tab
$ make test-transfers-big-amounts

Observe the output, quit with Ctrl-C if wanted (though it quits automatically on success).

Replenisher balance monitoring

# OPTIONAL
$ export FASTBTC_ALERTER_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/<webhook>/<secrets>
# Then
$ make run-demo-regtest-slow-replenisher

Advanced details

The test setup (launched with make run-demo-regtest) will expose the Hardhat RPC server at http://localhost:18545 and the bitcoind regtest RPC server at http://localhost:18443 (use the user RPC wallet, with authentication fastbtc/hunter2).

The Hardhat RPC can be interacted with the integration-test Hardhat network, e.g.:

$ cd packages/fastbtc-contracts
$ yarn && yarn build  # install and compile everything
$ npx hardhat --network integration-test federators
0x4091663B0a7a14e35Ff1d6d9d0593cE15cE7710a
0x09dcD91DF9300a81a4b9C85FDd04345C3De58F48
0xA40013a058E70664367c515246F2560B82552ACb
$ npx hardhat --network integration-test free-money 0xB3b77A8Bc6b6fD93D591C0F34f202eC02e9af2e8 5
Sending 5 rBTC (5000000000000000000 wei) to 0xB3b77A8Bc6b6fD93D591C0F34f202eC02e9af2e8
tx hash: 0x92f9093ce53169223392e4df1d1ac00415b523dd3b7151cbc0f9ed45a5ff6147

Or with CURL:

$ curl http://localhost:18545 \            
  -s -i -X POST -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Request-Method: *
Access-Control-Allow-Methods: OPTIONS, GET
Access-Control-Allow-Headers: *
Content-Type: application/json
Date: Mon, 08 Nov 2021 01:28:01 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 42

{"jsonrpc":"2.0","id":1,"result":"0x7a69"}

The Bitcoin regtest network can be interacted with using bitcoin-cli (see integration_tests/scripts/bitcoin_cli.sh) or with CURL:

$ curl http://localhost:18443/wallet/user \
  -s -i -X POST -H "Content-Type: application/json" --user fastbtc:hunter2 \ 
  --data '{"method":"getwalletinfo","params":[],"id":1}'
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 08 Nov 2021 01:27:05 GMT
Content-Length: 425

{"result":{"walletname":"user","walletversion":169900,"format":"bdb","balance":0.59992000,
 "unconfirmed_balance":0.00000000,"immature_balance":0.00000000,"txcount":1,"keypoololdest":1636334208,
 "keypoolsize":1000,"hdseedid":"821e906358e696611f9dc97053c3d3fcace0b475","keypoolsize_hd_internal":1000,
 "paytxfee":0.00000000,"private_keys_enabled":true,"avoid_reuse":false,"scanning":false,"descriptors":false},
 "error":null,"id":1}

See also integration_test/scripts/test_example_transfer.sh

The RSK Smart contracts (fastbtc-contracts)

For details about the smart contracts, see packages/fastbtc-contracts/README.md.

The P2P network (fastbtc-node)

The package fastbtc-node contains the implementation of the background service. The nodes form a peer-to-peer network, where they connect to other nodes using pre-configured addresses, and then discover all nodes in the network.

For more in-depth information, see packages/fastbtc-node/README.md.

Data flow

fastbtc-node data flow

UI

The project also has an example UI (fastbtc-ui) that is not meant for production and should not be a part of any audit. It does not currently support the integration test setup out of the box

A note about secrets and private keys

The integration_test/nodes directory includes some private keys for the Bitcoin and RSK networks. These are generated exclusively for the project and are meant to be in Git, but please do not use them with real money.

bidirectional-fastbtc's People

Contributors

koirikivi avatar ztane avatar hakuryuuhakuu avatar

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.