|
| 1 | +# Test `subcoin_sendRawTransaction` |
| 2 | + |
| 3 | +<!-- clap-markdown-toc --> |
| 4 | + |
| 5 | +* [1. Start a subcoin node](#1-start-a-subcoin-node) |
| 6 | +* [2. Start a Bitcoin Core node](#2-start-a-bitcoin-core-node) |
| 7 | +* [3. Fetch a pending transaction from mempool](#3-fetch-a-pending-transaction-from-mempool) |
| 8 | +* [4. Broadcast the transaction](#4-broadcast-the-transaction) |
| 9 | + |
| 10 | +<!-- /clap-markdown-toc --> |
| 11 | + |
| 12 | +RPC `subcoin_sendRawTransaction` is used to submit a raw transaction in hex string to the local node and network, the submitted transaction will be broadcasted to the connected peers. |
| 13 | + |
| 14 | +Here is how we'll test the functionality of this RPC: |
| 15 | + |
| 16 | +- Start a subcoin node. |
| 17 | +- Start a Bitcoin Core node with an empty mempool, connecting only the specified subcoin node. |
| 18 | +- Fetch a pending transaction using API from mempool.space. |
| 19 | +- Check the presence of the pending transaction before and after invoking the RPC `subcoin_sendRawTransaction`. |
| 20 | + |
| 21 | +### 1. Start a subcoin node |
| 22 | + |
| 23 | +```bash |
| 24 | +# Note that the default RPC url for subcoin is 127.0.0.1:9944. |
| 25 | +./target/release/subcoin run --listen=127.0.0.1:8888 -d tmp --log subcoin_network=debug |
| 26 | +``` |
| 27 | + |
| 28 | +### 2. Start a Bitcoin Core node |
| 29 | + |
| 30 | +Create a `test.conf` for the `rpcauth` and `rpcport` options. |
| 31 | + |
| 32 | +```ini |
| 33 | +# Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. RPC clients connect using rpcuser=<USERNAME>/rpcpassword=<PASSWORD> arguments. You can generate this value at https://jlopp.github.io/bitcoin-core-rpc-auth-generator/. This option can be specified multiple times. |
| 34 | +# The following rpcauth value is generated by specifying both username and password to test. |
| 35 | +rpcauth=test:3ead8ce3dcb0dc9f6258137d8a820b7f$d1b21d8220633d365f4dce99213e07159b3240deb33789b5f4d2ccfd1c82c473 |
| 36 | +# Listen for JSON-RPC connections on this port |
| 37 | +rpcport=9000 |
| 38 | +``` |
| 39 | + |
| 40 | +Start a `bitcoind` node. (Note that if this is a fresh `bitcoind` node, the data of broadcasted transaction may be requested on receiving the transaction ID. Try to keep the bitcoind node syncing for some blocks). |
| 41 | + |
| 42 | +```bash |
| 43 | +# -persistmempool=0 ensures there is no transactions in the pool on startup. |
| 44 | +# -noconnect -connect=127.0.0.1:8888 ensures the bitcoind node only connects to the subcoin node. |
| 45 | +./src/bitcoind -datadir=/tmp/btc-data -persistmempool=0 -noconnect=1 -connect=127.0.0.1:8888 -debug=net -conf=$PWD/test.conf |
| 46 | +``` |
| 47 | + |
| 48 | +### 3. Fetch a pending transaction from mempool |
| 49 | + |
| 50 | +Get a recent pending transaction using https://mempool.space/docs/api/rest#get-mempool-recent. |
| 51 | + |
| 52 | +```bash |
| 53 | +# Fetch the recent pending transactions and take the txid of first item. |
| 54 | +curl -sSL "https://mempool.space/api/mempool/recent" | python3 -m json.tool | grep txid | head -n 1 |
| 55 | + "txid": "4f45b6c6f34933e9f209431551d36f752ca2b18709e83f56f7223c59952e2b42", |
| 56 | +``` |
| 57 | + |
| 58 | +Get the full transaction in hex. |
| 59 | + |
| 60 | +```bash |
| 61 | +# Replace TXID with the transaction ID we want to fetch. |
| 62 | +# curl -sSL "https://mempool.space/api/tx/{{TXID}}/hex" |
| 63 | +curl -sSL "https://mempool.space/api/tx/4f45b6c6f34933e9f209431551d36f752ca2b18709e83f56f7223c59952e2b42/hex" |
| 64 | +``` |
| 65 | + |
| 66 | +A small python script `test_subcoin_sendRawTransaction.py` is provided for this step. |
| 67 | + |
| 68 | +```python |
| 69 | +import requests |
| 70 | + |
| 71 | +# Define the URL |
| 72 | +url = "https://mempool.space/api/mempool/recent" |
| 73 | + |
| 74 | +def fetch_pending_transaction(): |
| 75 | + # Send a GET request to the URL |
| 76 | + response = requests.get(url) |
| 77 | + |
| 78 | + # Check if the request was successful |
| 79 | + if response.status_code == 200: |
| 80 | + # Parse the JSON response |
| 81 | + recent_transactions = response.json() |
| 82 | + # Print the result |
| 83 | + print("==== Recent transactions:") |
| 84 | + print(recent_transactions) |
| 85 | + |
| 86 | + print("==== Txid of first transaction in the recent transaction list:") |
| 87 | + txid = recent_transactions[0]["txid"] |
| 88 | + print(txid) |
| 89 | + |
| 90 | + print("==== Fetching transaction in hex string:") |
| 91 | + response = requests.get(f"https://mempool.space/api/tx/{txid}/hex") |
| 92 | + print(response.text) |
| 93 | + |
| 94 | + else: |
| 95 | + # Print an error message if the request was not successful |
| 96 | + print(f"Failed to retrieve recent transactions: {response.status_code}") |
| 97 | + |
| 98 | +fetch_pending_transaction() |
| 99 | +``` |
| 100 | + |
| 101 | +Run `python3 test_subcoin_sendRawTransaction.py`: |
| 102 | + |
| 103 | +```bash |
| 104 | +python3 test_subcoin_sendRawTransaction.py |
| 105 | +==== Recent transactions: |
| 106 | +[{'txid': '4f45b6c6f34933e9f209431551d36f752ca2b18709e83f56f7223c59952e2b42', 'fee': 710, 'vsize': 99, 'value': 50000}, {'txid': 'a40e7f6534a289c0b2ec864886d606d7861644d0fe714382e3cf4b285c829376', 'fee': 712, 'vsize': 174, 'value': 781919031}, {'txid': '87fd7a9eb51a1225bfe5967178b115d0a0d62be834890e726fc83d326ecd2bfa', 'fee': 1266, 'vsize': 211, 'value': 68176}, {'txid': 'c10ca68cd682c880ee945bf46c81ff499d0f828ca7c50540fe0744e0cacc0f81', 'fee': 1435, 'vsize': 285, 'value': 87727756}, {'txid': 'd2a1c04ac9f1d3f26ed99ebfff8a58bca25a186d3945ba9b60e760e046c43788', 'fee': 564, 'vsize': 140, 'value': 2868167}, {'txid': '3bd4841935fe50616cc47cd38514dfbe277300e6464ad183d7778fb8ef09df48', 'fee': 564, 'vsize': 140, 'value': 52310}, {'txid': '848762114fa3dfd937ed6d4de2fd7b23ccb41a4f9815a46b3cd0d7118aa1fdb0', 'fee': 564, 'vsize': 140, 'value': 131887}, {'txid': '93a8359dd8749be74ec811841134b0bbd4b2428f871aaeb3dd1b0a322c934d04', 'fee': 964, 'vsize': 141, 'value': 68322}, {'txid': 'ce349b628d7a6520331dc6c6cc75c02656f337ab5eb8625ece29a9ef6234f2fb', 'fee': 985, 'vsize': 197, 'value': 14147}, {'txid': '0101166e0abc508ead0cda10e1b5ade23e48f6ee228ea3abab8e788f63b77e4f', 'fee': 1887, 'vsize': 377, 'value': 3478}] |
| 107 | +==== Txid of first transaction in the recent transaction list: |
| 108 | +4f45b6c6f34933e9f209431551d36f752ca2b18709e83f56f7223c59952e2b42 |
| 109 | +==== Fetching transaction in hex string: |
| 110 | +0200000000010187e47d1ae0bf05530bcd97bfb6b3879c58bcabb4e89951df1f307e0e3c8bb2e80300000000ffffffff018ac00000000000001600149e142d6b0d25d3fcde9102cbf17828f3e05f051f01406e3cb634234591661c1a4c52615bb5a543f099400b872dd94d39688f45bca29f28066782ca44012d27b5c1c9a528e376857d3f076c27123ea77b0041f54e8cd200000000 |
| 111 | +``` |
| 112 | + |
| 113 | +### 4. Broadcast the transaction |
| 114 | + |
| 115 | +Now we can broadcast the transaction via RPC `subcoin_sendRawTransaction` to the Bitcoin Core node. |
| 116 | + |
| 117 | +The transaction is not in the mempool of `bitcoind` before the broadcasting. |
| 118 | + |
| 119 | +```bash |
| 120 | +# Replace TXID with the transaction ID we want to fetch. |
| 121 | +# ./src/bitcoin-cli -datadir=/tmp/btc-data -conf=$PWD/test.conf getrawtransaction TXID |
| 122 | +# The transaction does not exist in the mempool at this moment. |
| 123 | +./src/bitcoin-cli -datadir=/tmp/btc-data -conf=$PWD/test.conf 4f45b6c6f34933e9f209431551d36f752ca2b18709e83f56f7223c59952e2b42 |
| 124 | +error code: -5 |
| 125 | +error message: |
| 126 | +No such mempool or blockchain transaction. Use gettransaction for wallet transactions. |
| 127 | +``` |
| 128 | + |
| 129 | +Now submit the transaction via `subcoin_sendRawTransaction`. |
| 130 | + |
| 131 | +```bash |
| 132 | +curl --location 'http://127.0.0.1:9944' \ |
| 133 | +--header 'Content-Type: application/json' \ |
| 134 | +--data '{ |
| 135 | + "jsonrpc": "2.0", |
| 136 | + "method": "subcoin_sendRawTransaction", |
| 137 | + "params": [ |
| 138 | + "0200000000010187e47d1ae0bf05530bcd97bfb6b3879c58bcabb4e89951df1f307e0e3c8bb2e80300000000ffffffff018ac00000000000001600149e142d6b0d25d3fcde9102cbf17828f3e05f051f01406e3cb634234591661c1a4c52615bb5a543f099400b872dd94d39688f45bca29f28066782ca44012d27b5c1c9a528e376857d3f076c27123ea77b0041f54e8cd200000000" |
| 139 | + ], |
| 140 | + "id": 1 |
| 141 | +}' |
| 142 | +``` |
| 143 | + |
| 144 | +Check the mempool of `bitcoind` again, now we should see the transaction is present there, thus the transaction has been broadcasted to the bitcoind node and the RPC works as expected. |
| 145 | + |
| 146 | +```bash |
| 147 | +# Now the transaction exists in the mempool. |
| 148 | +./src/bitcoin-cli -datadir=/tmp/btc-data -conf=$PWD/test.conf 4f45b6c6f34933e9f209431551d36f752ca2b18709e83f56f7223c59952e2b42 |
| 149 | +0200000000010187e47d1ae0bf05530bcd97bfb6b3879c58bcabb4e89951df1f307e0e3c8bb2e80300000000ffffffff018ac00000000000001600149e142d6b0d25d3fcde9102cbf17828f3e05f051f01406e3cb634234591661c1a4c52615bb5a543f099400b872dd94d39688f45bca29f28066782ca44012d27b5c1c9a528e376857d3f076c27123ea77b0041f54e8cd200000000 |
| 150 | +``` |
0 commit comments