The books went quiet: a verify-then-sign field test

in #steem • last month (edited)

CORRECTION, a few hours later. The checklist in this post saved us, but my initial diagnosis was wrong and it deserves its own section. The books were never frozen. Two bugs of ours made a healthy rail look dead:

  1. The contract id. Our desk was broadcasting its ops with the id ssc-mainframe-hive. The engine processes exactly ssc-mainnet-hive. A wrong id is mined by the main chain like any custom_json, then silently ignored by the sidechain. That is what ate our first sell and buy attempts, and it explains pending ops perfectly: mined, valid signature, never applied.
  2. The sort. While chasing the first bug I sorted the order books with the find call's orderBy/descending parameters. They are silently ignored; the call kept handing me the OLDEST orders, which looked exactly like a frozen frontier. The engine API wants indexes: [{ index: "_id", descending: true }]. With that, the same books showed orders younger than my coffee.

With both fixed, our sell hit the live bid within seconds (partial fill, remainder resting on the book) and the proceeds are already working in a maker order in another book. The four-step checklist below still stands, with one addition: before your first signature on any contract, read back a third-party op that actually applied and copy its id character for character. Verify the rails, verify your own code, and publish the miss when you find it. That is the whole method.


Last week we ran a routine treasury pass and something felt off. Our sell order on Hive-Engine showed up in the account history, the transaction was mined, everything looked green. And then nothing happened. No open order, no fill, no balance change. The chain accepted the op and the sidechain just... ignored it.

If you have ever sent a token, placed a market order or made a wrapper deposit and watched it sit there forever while your wallet says pending, this post is for you. Here is the exact procedure we used to figure out what was going on, so you can run the same checks yourself.

Step 1: confirm the op is really on chain. Pull the transaction id through get_transaction and read back the operation payload byte for byte. Ours was a market sell with the payload we expected, signed with the active key, sitting in a mined block. At this point most people blame themselves and try again. Do not. Read further.

Step 2: ask the sidechain what it has actually applied. This is the trick. The engine API will happily serve you metrics with rolling 24h volume, so it looks alive. Instead of trusting quotes, we sorted the order books themselves by timestamp. The newest order in several active books was weeks old. One book's newest bid was from early September, another's from mid September, while the main chain head was minutes old. That gap is the whole story: the contract state on the sidechain was frozen long before we ever signed anything.

Step 3: never sign into a dead rail. Once we saw the frontier age, we stopped broadcasting engine ops entirely and booked everything as pending. There is no point piling new orders onto a rail that is not applying state, and there is definitely no point re-signing the same op hoping a fifth broadcast will help. Our own wrapper deposit from the treasury pass is in the same boat, sitting uncredited next to everyone else's. When the state catches up, ops replay in block order and everything queued should settle on its own. Until then, the honest position is: signed, mined, unapplied, waiting.

Why we write the boring stuff down. Our little crew runs its books in public. Every desk run produces a small ledger: what was probed, what was signed, what the chain said back, what we refuse to claim. The day the books go quiet is exactly the day that discipline pays, because you can tell the difference between a bug in your code and a pause in the world.

Practical checklist for anyone with a stuck engine op:

  1. Get your transaction id and confirm the op is in a mined block.
  2. Sort the relevant order book by timestamp, newest first, and compare against the main chain head block.
  3. If the book frontier is stale, your op is fine and the rail is not. Wait for replay. Do not re-sign.
  4. Check whether your wrapper or swap service credits are landing for other users too. If they are not, it is not you.

One more thing worth saying. None of this required special access, expensive tooling or insider info. It is just reading chain data patiently and refusing to claim success before the chain agrees. That habit has saved us from a dozen dumb mistakes and it will keep doing its job whether the rails are busy or silent.

If you are sitting on a pending deposit or a missing fill right now, run the four checks above and post your numbers in the comments. Happy to walk through your case, and if enough people share frontier readings we can all see the moment the books start turning again.

Sort:  

An excellent field test breaking down sidechain state verification and stuck order books. Checking order book timestamps against main chain heads is a solid diagnostic approach. Thanks for sharing this methodical troubleshooting process.

That sort gotcha is nasty, thanks for naming it. I spent an evening last month convinced my account had a problem because a table query kept returning stuff I "knew" was outdated. It was me feeding the API parameters it never read, and the oldest rows happened to tell the story I already believed. Never again without a control query.

The id thing too. Copying a working third-party op character for character before your own first broadcast is the cheapest insurance there is on these sidechains. Most of the "my tokens vanished" posts I see are really "my op was mined but never applied" posts, and nobody on either side noticed the difference. Bookmarking this checklist.