← TXC Core

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.

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.

src/texitcoind -regtest -daemon -server
CLI="src/texitcoin-cli -regtest"

# 1. the RPCs exist (wallet-scoped)
$CLI help omni_sendtomany
$CLI help omni_createpayload_sendtomany

# 2. encoder matches the known-good upstream vector
$CLI omni_createpayload_sendtomany 31 \
  '[{"output":2,"amount":"10.5"},{"output":3,"amount":"0.5"},{"output":5,"amount":"15.0"}]'
# -> 000000070000001f0302000000003e95ba80030000000002faf080050000000059682f00

# 3. real send: issue tokens, then pay two receivers in one tx
$CLI omni_sendissuancemanaged "$FROM" 2 1 0 "Test" "" "STM" "" ""
$CLI generatetoaddress 1 "$FROM"
$CLI omni_sendgrant "$FROM" "$FROM" $PROP "1000"
$CLI generatetoaddress 1 "$FROM"
$CLI omni_sendtomany "$FROM" $PROP \
  '[{"address":"'$A'","amount":"10"},{"address":"'$B'","amount":"25"}]'
$CLI generatetoaddress 1 "$FROM"
$CLI omni_getbalance "$A" $PROP
$CLI omni_getbalance "$B" $PROP

Regtest has MSC_SEND_TO_MANY_BLOCK = 0, so type 7 is live from genesis there. Mainnet is set to 999999999 — it will reject type 7 with -86022 until you deliberately broadcast omni_sendactivation <addr> 19 <block> <minclientver>.

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.