Skip to content

Conversation

@f321x
Copy link
Member

@f321x f321x commented Jan 21, 2025

Defines a protocol method blockchain.transaction.broadcast_package for protocol version 1.4.4 and implements it so clients can submit a package of transactions to the mempool using the bitcoin core submitpackage method. This allows clients to broadcast a package of transactions that would on their own not be accepted to the mempool (e.g. below purge fee parent and high fee child to bump)

@spesmilo spesmilo deleted a comment from Dakota48423 Jan 29, 2025
Comment on lines 556 to 558
The Bitcoin Core daemon result according to its RPC API documentation.

**Result Example**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Not sure if we want to just forward the return value from bitcoind as-is.
The bitcoin core RPC docs say: This RPC is experimental and the interface may be unstable.
If we do want to just forward this result, I guess we too should mark the result as unstable (?).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that forwarding the result could cause problems in clients if the e-x server upgrades its daemon to a new version and the result structure changes, while defining our own structure would limit the issues to the e-x server side which seems less problematic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a verbose parameter so the user can decide if he wants the full response or only the package_msg and replaced txids. See PR spesmilo/electrum-protocol#1

@f321x f321x force-pushed the submitpackage branch 2 times, most recently from 157ca93 to 336a16a Compare February 6, 2025 11:36
@f321x f321x force-pushed the submitpackage branch 2 times, most recently from d39138b to 50a161b Compare February 6, 2025 12:56
@f321x
Copy link
Member Author

f321x commented Feb 6, 2025

Simple script to test the call:

import socket


def main():

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect(("127.0.0.1", 51001))
        s.sendall(b'{"jsonrpc": "2.0", "method": "server.version", "params": ["", "1.4.4"], "id": 0}\n')

        data = s.recv(1028)
        s.sendall(b'{"jsonrpc": "2.0", "method": "blockchain.transaction.broadcast_package", "params": [["raw_parent_tx", "raw_child_tx"], false], "id": 0}\n')

        data = s.recv(1028)
        print(data)


if __name__ == '__main__':
    main()

@spesmilo spesmilo deleted a comment from Armanidashh Feb 12, 2025
@f321x
Copy link
Member Author

f321x commented Feb 12, 2025

Commit ff7c1a3 represents the protocol changes in commit spesmilo/electrum-protocol@7bc5f11

@f321x
Copy link
Member Author

f321x commented Feb 19, 2025

7de390f represents protocol pr status spesmilo/electrum-protocol@3e49ee8

Copy link
Member

@SomberNight SomberNight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This looks good.
I added some comments but I will fix them myself in a follow-up.

Comment on lines +1486 to +1487
except ValueError:
self.logger.info(f"error calculating txids: {traceback.format_exc()}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to import traceback

Suggested change
except ValueError:
self.logger.info(f"error calculating txids: {traceback.format_exc()}")
except ValueError as e:
self.logger.info(f"error calculating txids", exc_info=e)

here is some boilerplate:

import traceback
import logging
import sys

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
console_stderr_handler = logging.StreamHandler(sys.stderr)
console_stderr_handler.setLevel(logging.DEBUG)
logger.addHandler(console_stderr_handler)

and now compare (in a fresh local python interpreter):

try:
    txids = [double_sha256(bytes.fromhex(tx)).hex() for tx in tx_package]
except Exception:
    logger.info(f"error calculating txids: {traceback.format_exc()}")

and

try:
    txids = [double_sha256(bytes.fromhex(tx)).hex() for tx in tx_package]
except Exception as e:
    logger.info(f"error calculating txids", exc_info=e)

and

try:
    txids = [double_sha256(bytes.fromhex(tx)).hex() for tx in tx_package]
except Exception:
    logger.info(f"error calculating txids", exc_info=True)

see https://docs.python.org/3/library/logging.html#logging.Logger.debug

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's useful to know!

Comment on lines +1609 to +1610
if ptuple >= (1, 4, 4):
handlers['blockchain.transaction.broadcast_package'] = self.package_broadcast
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's either not expose the new method at all, or maybe expose it unconditionally by moving it ~6 lines higher into the big dict.

I don't want to gate it behind an arbitrary temporary version number. Once spesmilo/electrum-protocol#2 is done, we can gate it behind that version number along with the other changes.

Until it is documented in the spec, clients should not rely on this method existing at any version.

@SomberNight SomberNight merged commit 7de390f into spesmilo:master Feb 19, 2025
3 of 4 checks passed
@f321x f321x deleted the submitpackage branch February 19, 2025 15:07
@SomberNight SomberNight added this to the protocol 1.6 milestone Oct 23, 2025
raw_txs: a list of raw transactions as hexadecimal strings"""
self.bump_cost(0.25 + sum(len(tx) / 5000 for tx in tx_package))
try:
txids = [double_sha256(bytes.fromhex(tx)).hex() for tx in tx_package]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these txids for? They are in reversed byte order versus normal RPC interface, so logging them isn't that helpful, because it's not like you can copy-paste them to an explorer to view the txns (unless you manually reverse them first).

Also, they are wtxids, and not normal txids, because you are hashing the raw txn which contains witness data, rather than the stripped txn...

Copy link
Member Author

@f321x f321x Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch. Yeah this is incorrect i remove it in this followup PR #319

f321x added a commit to f321x/electrumx-fork that referenced this pull request Oct 24, 2025
Removes the incorrect and unnecessary txid calculation in
`ElectrumX.package_broadcast()`, the daemon will complain anyways if the
transactions are invalid.
SomberNight added a commit that referenced this pull request Oct 24, 2025
session: broadcast_package: followup #288
SomberNight added a commit that referenced this pull request Nov 7, 2025
This implements the remainder of the protocol 1.6 changes,
and it bumps PROTOCOL_MAX to "1.6".

Some of protocol 1.6 was merged previously, see e.g.:
- #288
- #302
- kyuupichan/electrumx#1001
- #325

ref spesmilo/electrum-protocol#6
ref #317
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants