Schedule ZEC outbounds to TEX addresses as transparent addresses

fixes #3393 (closed)

ZEC outbounds to a Zcash TEX address are now scheduled to the matching transparent (t1/tm) address, the form the Zcash daemon reports when the payment is observed. Bifrost no longer signs ZEC outbounds that still carry a TEX address, which can only be items queued before this change.

The MR also adds an exact Zcash network check for destination and refund addresses, and moves swapper clout earned on a TEX address onto the transparent address with a store migration.

Changes:

Outbound scheduling and signing:

  • prepareTxOutItem converts a ZEC TEX destination with the new common.ConvertToZECTransparentAddress before vault selection. Voter actions, the outbound queue and the scheduled_outbound event therefore store the transparent address, and a vault's own TEX address is now recognised by the self-send check.
  • A TEX destination that does not decode on the current network now fails outbound scheduling instead of being queued.
  • UnSafeAddTxOutItem keeps the stored TEX address when LackSigning re-queues an item, so the re-queued item still matches its voter action.
  • The bifrost signer skips ZEC outbounds whose address starts with tex, logs that they need manual reconciliation, and drops them from the signer store.

ZEC network checks:

  • The new Address.IsCurrentNetwork requires a ZEC address to decode on the build's own Zcash network. Other chains keep the SoftEquals check.
  • The swap, add-liquidity, THORName and secured-asset-withdraw handlers use it instead of SoftEquals, so on stagenet a testnet-form ZEC address is rejected and a swap to it is refunded.
  • refundTx pays the sender when the memo refund address for a ZEC coin is from the other Zcash network.
  • The quote refund-address check uses IsCurrentNetwork, and /quote/limit now rejects a destination that is not of the target chain or not on the current network.

Swapper clout:

  • The new Address.Canonical converts a TEX address to its transparent form. SetSwapperClout and GetSwapperClout use it, so crediting from the memo, outbound delay and reclaiming all use one record.
  • Store migration Migrate19to20 (consensus version 19 to 20) merges existing TEX clout records into the matching transparent record. It restores both records first, so an old spend on one cannot stay outstanding, and then deletes the TEX key. Records it cannot read or convert are logged and left in place.
  • ExportGenesis reads swapper clout records from the stored values instead of rebuilding addresses from the uppercased store keys. Base58 addresses such as ZEC transparent addresses and noop were left out before. The regression exports now include these records.

Refactoring:

  • The new common.ZECNetworkName replaces four copies of the Zcash network switch in ToTexAddress, PubKey.GetAddress, the bifrost ZEC client and the simulation UTXO client.
  • The EquivalentAddresses comment is shortened to one line.
  • The ZEC address tests move from address_mocknet_test.go to address_zec_test.go, and existing ZEC TEX tests use random addresses.

Breaking:

  • Queries and events now show the transparent address for ZEC outbounds to a TEX destination, while the inbound memo still shows the TEX string. Integrators that match the two by plain string comparison need to compare equivalent addresses instead.
  • The swapper clout query for a TEX address now returns the transparent address's record, and the TEX and transparent forms share one balance. The upgrade runs a store migration that rewrites these records.
  • ZEC outbounds to a TEX address that are still queued at upgrade time are never signed. LackSigning keeps rescheduling them, and with MaxOutboundAttempts at 0 they stay pending indefinitely, so any such items need a reconciliation plan.
  • On stagenet, testnet-form ZEC addresses (tm, t2, textest) are now rejected as swap destinations (the swap is refunded), add-liquidity asset addresses, THORName aliases, secured-asset withdraw destinations and quote refund addresses. Mainnet acceptance is unchanged. Values already stored on stagenet are not migrated.
  • /quote/limit now returns an error for a destination of the wrong chain or network on every network. It used to build a memo for any destination that parsed.
  • Any outbound to a TEX address that does not decode on the current network now fails scheduling instead of being queued.

Testing:

  • Unit tests cover TEX normalization on swap and refund paths, wrong-network rejection in txout, the handlers and quotes, the sender fallback for a wrong-network refund address, re-queue preservation, LackSigning rescheduling of a legacy TEX item, the signer block, TEX clout keying and its effect on outbound delay, the clout merge migration, base58 clout export, and Canonical/IsCurrentNetwork.
  • The common outbound test now also checks that the voter action completes without a missing-tx-out security event.
  • A new regression suite test/regression/suites/swaps/zec-tex-outbound.yaml runs a RUNE to ZEC swap to a TEX destination through completion and checks that the clout lands on the transparent address. The adv-swap-queue/rapid-swaps-failed-market-budget fixture is regenerated to include the xmr_mined_height field.
  • The simulation swaps stage now always runs one transparent and one TEX ZEC swap actor. Both must complete, and both the outbound action and the observation must use the transparent address.

Reviewer focus: the restore-then-sum merge of TEX clout into the transparent record in Migrate19to20, and the reconciliation plan for legacy TEX outbounds that bifrost now refuses to sign.

Edited by Starsquid

Merge request reports

Loading
Loading