← Code & releases

Send To Many — the patch and how to build it

This page is the public build log for the current network upgrade: the actual patch, what it changes, and the exact steps to compile and test it yourself. Generated against blockchainmint1/texitcoin@master. 16 files, all inside src/omnicore/. Nothing outside Omni is touched, and the feature stays inert on mainnet until a feature-19 activation is broadcast.

Why this is a backport

New Omni capability, preserved modern core

Send To Many comes from Omni Core v0.12.0.1, which sits on an older Bitcoin Core base. TEXITcoin already runs on the newer 0.25.2 base, so replacing the whole Omni tree would move the project backwards. Instead, we carried transaction type 7 into the current tree and adapted its parser and wallet builder to TEXITcoin.

The full file-by-file technical specification remains in the repository atdocs/send-to-many-backport.md. This page is the working guide: design, patch, build, proof, and rollout in one place.

00

Prep the box — node-omni.texitcoin.org

The test node lives at node-omni.texitcoin.org (52.55.22.141, t3.medium, Ubuntu 24.04). Only port 22 is open — that is correct; the node reaches the network outbound and RPC stays local.

Connect with EC2 Instance Connect — no SSH keys needed:

  1. Open the AWS Console → EC2 → Instances, select this instance (the one behind node-omni.texitcoin.org).
  2. Click Connect → "EC2 Instance Connect" tab → Connect (keep the default username shown).
  3. A browser terminal opens, already signed in as ubuntu. Everything below is pasted there.

First, confirm you are on the right box — this should print the box's public IP (52.55.22.141) and hostname:

curl -s ifconfig.me && echo "" && hostname

t3.medium has 4 GB RAM and the build can spike past it. Add swap first, then the build dependencies. Paste this whole block in one go:

sudo fallocate -l 4G /swapfile && sudo chmod 600 /swapfile && \
  sudo mkswap /swapfile && sudo swapon /swapfile && \
  echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

sudo apt-get update && sudo apt-get install -y \
  build-essential libtool autotools-dev automake pkg-config bsdmainutils \
  python3 libssl-dev libevent-dev libboost-all-dev libsqlite3-dev \
  libminiupnpc-dev libzmq3-dev git curl

Everything below runs on that box. When you refer to it anywhere, use the hostname — the IP can change if the instance is stopped and restarted.

01

Apply it

Work on a branch. The patch applies with standard paths (-p1). On the box, start in your home directory:

cd ~
wget https://core.honest.money/patches/send-to-many.patch
git clone https://github.com/blockchainmint1/texitcoin
cd texitcoin
git checkout -b feature/send-to-many
git apply --check ../send-to-many.patch   # dry run, should print nothing
git apply ../send-to-many.patch
git commit -am "omni: backport Send To Many (tx type 7)"

If --check complains, master has moved; send me the reject output and I will regenerate against the new HEAD.

02

What it changes

createpayload.h / .cppCreatePayload_SendToMany — type 7 encoder
omnicore.hMSC_TYPE_SEND_TO_MANY = 7, PKT_ERROR_SEND_MANY = -86000
tx.h / tx.cppinterpret_SendToMany, logicMath_SendToMany, STM address map
omnicore.cppaddValidStmAddress hook in the output-scanning loop
rules.h / rules.cppFEATURE_SEND_TO_MANY = 19 + activation gate
rpcvalues.h / .cppParseStmOutputIndex
rpcrequirements.h / .cppRequireBoundedStmReceiverNumber
wallettxbuilder.h / .cppmulti-receiver WalletTxBuilder + GetDryPayloadOutputCount
rpcpayload.cppomni_createpayload_sendtomany
rpctx.cppomni_sendtomany
03

Build a fresh node

Standard TXC build (see texitcoin.org/build). Build with the wallet enabled — the new RPCs are wallet-scoped. Build the bundled dependencies first; they include the Berkeley DB version the wallet requires, which Ubuntu 24.04 no longer ships.

cd ~/texitcoin/depends && make -j2
cd ~/texitcoin

Then configure against those dependencies. The CONFIG_SITE line is mandatory — without it configure searches the system instead and fails with libdb_cxx headers missing even though depends built it:

./autogen.sh
CONFIG_SITE=$PWD/depends/x86_64-pc-linux-gnu/share/config.site ./configure --enable-wallet
make -j2

Use -j2 on a 2 vCPU box; -j$(nproc) with less than 2 GB RAM per core invites the out-of-memory killer mid-compile.

Reminder from the node probe: your running binary exposes 43 Omni RPCs while master has 85. A clean build from master should restore the whole omni_send* family before this patch even comes into play.

04

Prove it on regtest first

Do not point this at mainnet until regtest is green. Regtest is the same binary running a private pretend chain — minutes, free, and it runs on the same box next to the mainnet node without touching it. Regtest has MSC_SEND_TO_MANY_BLOCK = 0, so type 7 is live from genesis there. On mainnet, v0.26.1 switches it on at block 364,100 (about 6 October 2026, 16:30 UTC).

Start the private chain and its wallet (paste in one go):

cd ~/texitcoin
rm -rf ~/txc-regtest
mkdir -p ~/txc-regtest
cat > ~/txc-regtest/texitcoin.conf <<'EOF'
regtest=1
txindex=1
server=1
rpcallowip=127.0.0.1
fallbackfee=0.0001

[regtest]
rpcport=15749
rpcuser=txcregtest
rpcpassword=regtest-only-not-secret
EOF
./src/texitcoind -regtest -datadir=$HOME/txc-regtest -daemon
sleep 5
CLI="./src/texitcoin-cli -regtest -datadir=$HOME/txc-regtest"
$CLI createwallet regtest

Mine 101 blocks to a legacy address — Omni requires this address format for sender coin selection:

cd ~/texitcoin
CLI="./src/texitcoin-cli -regtest -datadir=$HOME/txc-regtest"
FROM=$($CLI getnewaddress "omni-funder" "legacy")
echo "$FROM" > ~/regtest-from.txt
$CLI generatetoaddress 101 "$FROM"
$CLI getbalance

getbalance should print 50. Now create a test token — a fixed issuance of 1,000,000 indivisible units:

cd ~/texitcoin
CLI="./src/texitcoin-cli -regtest -datadir=$HOME/txc-regtest"
FROM=$(cat ~/regtest-from.txt)
TX=$($CLI omni_sendissuancefixed "$FROM" 2 1 0 "STM" "" "TestTokens" "" "" "1000000")
$CLI generatetoaddress 1 "$FROM"
PROP=$($CLI omni_gettransaction "$TX" | grep -o '"propertyid"[ :]*[0-9]*' | grep -o '[0-9]*')
echo "PROPERTY ID: $PROP"
echo "$PROP" > ~/regtest-prop.txt

Then the real test — one transaction paying three addresses:

cd ~/texitcoin
CLI="./src/texitcoin-cli -regtest -datadir=$HOME/txc-regtest"
FROM=$(cat ~/regtest-from.txt)
PROP=$(cat ~/regtest-prop.txt)
A=$($CLI getnewaddress "receiver-a" "legacy")
B=$($CLI getnewaddress "receiver-b" "legacy")
C=$($CLI getnewaddress "receiver-c" "legacy")
$CLI omni_sendtomany "$FROM" "$PROP" \
  '[{"address":"'$A'","amount":"100"},{"address":"'$B'","amount":"50"},{"address":"'$C'","amount":"25"}]'
$CLI generatetoaddress 1 "$FROM"
$CLI omni_getbalance "$A" "$PROP"
$CLI omni_getbalance "$B" "$PROP"
$CLI omni_getbalance "$C" "$PROP"

The three balances should read exactly 100 / 50 / 25 — that is Send To Many proven end to end, tokens actually landing on multiple addresses from one transaction. When finished, $CLI stop (with the same CLI prefix) shuts down only the regtest node; the mainnet node keeps running.

Mainnet rejects type 7 with -86022 until you deliberately broadcast omni_sendactivation <addr> 19 <block> <minclientver>.

Verified 2026-10-03 on node-omni with the combined Send To Many + LWMA build: receivers 100 / 50 / 25, sender 999,825 of 1,000,000. One caveat found in testing: receivers must be legacy addresses — the bulk-send encoder cannot yet read the newer default address type, so the wallet call above passes "legacy" explicitly. Decide before mainnet whether type 7 needs to support the newer address type too.

05

Two things to watch

Output ordering is consensus. The payload references receivers by vout index. The new multi-receiver WalletTxBuilder appends dust outputs in list order right after the payload outputs, and refuses to build if the wallet inserts change ahead of them. If you ever see funds land on the wrong address in a tx that validates, that guard is the first place to look.

Pre-activation consensus must be identical. Run an old binary and the patched one over the same regtest chain before activating, and compare omni_getcurrentconsensushash. Matching hashes prove the patch is inert until feature 19 goes live.

06

Monitor it — the node canary

Once the node is up, stop eyeballing log files. One paste gives you a single verdict covering the build, the daemon, consensus with the network, the Omni parser, the new RPCs, the encoder vector, the activation gate and host health:

curl -fsSL "https://core.honest.money/install/node-canary.sh?v=$(date +%s)" | bash

Read-only — it never sends coins or changes node state. Full canary documentation, including baseline mode and how to read a FAIL.

07

Find the Omni nodes — who actually needs this build

The base coin is safe no matter what. The token layer is where everyone must upgrade: every node that parses Omni recomputes token balances itself, and an old one will silently skip Send To Many messages. Before anyone picks an activation block, we need to know how many of those nodes are live. The survey asks your node for every address it knows, connects to each one briefly, reads its version banner, and counts how many carry Omni:

curl -fsSL "https://core.honest.money/install/peer-survey.sh?v=$(date +%s)" | sudo bash -s 200

Read-only — it only connects, reads the banner, and disconnects. The number is how many addresses to try (100 takes a few minutes; bash -s 250 goes wider). Two honest limits: it only sees addresses your node has been told about, and only nodes that accept inbound connections answer — so treat the Omni count as a floor, not the full population. The summary is also saved to ~/peer-survey-<date>.txt.

08

The built-in node list — adding new seed nodes

A fresh node with an empty address book finds the network from a short list baked into the code. In src/chainparams.cpp that list is today just two entries:

vSeeds.emplace_back("node1.texitcoin.org");
vSeeds.emplace_back("node2.texitcoin.org");

To add more (node3 and the honest.money node), edit that block so it reads:

vSeeds.emplace_back("node1.texitcoin.org");
vSeeds.emplace_back("node2.texitcoin.org");
vSeeds.emplace_back("node3.texitcoin.org");
vSeeds.emplace_back("node-txc.honest.money");

Seed hosts must accept inbound connections on port 15740; anything firewalled is useless as a seed. The change only affects nodes that start with no known peers — existing nodes keep using their saved address book. To point a node at extra peers right now, without rebuilding, add addnode= lines to its texitcoin.conf and restart.

Why so many probes go unanswered. Most addresses your node gossips about are ordinary wallets behind home routers — outbound only, no open port. They are on the network, they just cannot be called back. The survey therefore counts the reachable public nodes, which is exactly the set that matters for activation coordination.

09

Also in v0.26.0 — smoother difficulty

The next update also fixes the 2-hour difficulty seesaw: difficulty will adjust every block instead of every 40. Simulation, patch and test steps.