QMail Subscribe — Group 6, Code 85

A vendor adds prepaid storage credit to one or many target mailboxes in a single request, so those mailboxes can upload QMail attachments without attaching a payment locker. The vendor proves ownership of an allow-listed billing coin by presenting its Authenticity Number, exactly like an upload; each entry’s credit is added to that mailbox’s balance on this RAIDA.

Quick reference

Command Group6 (QMail)
Command Code85 (0x55)
Server functioncmd_qmail_subscribe in cmd_qmail.c
Request bodyVariable: QMail preamble(48) + N×9-byte entries + terminator(2), N = 1–150. The count is derived from the length. Max 1400 bytes (150 entries).
AuthenticationVendor AN in the preamble, verified against the coin database like upload. The vendor (den,sn) must be on the server’s hard-coded allowlist.
Success responseStatus 250, no payload
SemanticsAdds each entry’s credit bytes to that mailbox’s balance (accumulates; saturates at 232−1). All-or-nothing: a bad denomination in any entry rejects the whole batch.
DistributionClient sends the same request to every QMail server

Purpose

Subscribe is how a billing vendor pre-funds a mailbox’s storage. Once a mailbox has credit, its owner can upload attachments with an all-zero locker code and the RAIDA draws down the prepaid balance instead of requiring a funded locker. Each RAIDA keeps its own balance table, so the vendor sends the same Subscribe to every QMail server; the per-server results tell the vendor which servers were funded.

The vendor is the preamble coin. The preamble carries the vendor coin’s denomination, serial number, and this-RAIDA Authenticity Number in the same layout every QMail command uses. The server first checks that (denomination, serial number) is on its compiled-in vendor allowlist, then verifies the AN against the coin database. Only the target mailbox and the credit amount travel in the payload after the preamble.

The credit is a raw byte count — an unsigned 32-bit big-endian integer. Repeated Subscribes to the same mailbox accumulate; the running total saturates at 4 294 967 295 (232−1) rather than overflowing.

Request body

Variable length: the 48-byte QMail preamble (challenge + identity + AN, identical to every other QMail command) followed by an array of 1–150 nine-byte entries and the 2-byte terminator. The server derives the entry count from the body length — it must be a whole number of 9-byte entries. The diagram below shows the preamble and the first entry; entries 2…N repeat the same MDN(1) MSN(4) credit(4) layout back-to-back. “VDN/VSN” = vendor denomination/serial; “MDN/MSN” = target mailbox denomination/serial; T = terminator.

Challenge random (12 bytes, part 1 of 2) 0 7 Challenge random (part 2) 8 11 Challenge CRC32 (BE) 12 15 Session ID (8 bytes, zeros) 16 23 Coin Type 24 25 VDN 26 Vendor Serial Number (BE) 27 30 rsv 31 Vendor Authenticity Number (part 1 of 2) 32 39 Vendor Authenticity Number (part 2 of 2) 40 47 MDN 48 Mailbox Serial Number (BE) 49 52 Credit (part 1) 53 55 Cr 56 3E 3E (term) 57 58
Request body layout (variable length)

+-------------------+---------------------------------+----------------------------------+------------+
| challenge / CRC   | vendor identity + auth (preamble)| entries (1..150 x 9 bytes)       | terminator |
| 16 bytes          | session(8) type(2) VDN(1) VSN(4) | [ MDN(1) MSN(4) credit(4) ] ...  | 2 bytes    |
|                   | rsv(1) AN(16)                    | one 9-byte entry per mailbox     | 3E 3E      |
+-------------------+---------------------------------+----------------------------------+------------+
| body[0..15]       | body[16..47]                     | body[48 .. 48 + N*9 - 1]         | last 2      |
+-------------------+---------------------------------+----------------------------------+------------+
total = 48 + N*9 + 2 bytes    (N = 1..150; N = 150 -> 1400 bytes)
Body offsetSizeFieldDescription
0–1112Challenge randomRandom bytes generated by the client.
12–154Challenge CRC32Big-endian CRC32 of bytes 0–11.
16–238Session IDPreamble session field; zeros.
24–252Coin TypeBig-endian 0x0006 (CloudCoin).
261Vendor denominationVendor coin denomination (signed, −8 to +6). Must be on the allowlist.
27–304Vendor serial numberVendor coin serial number, big-endian. Must be on the allowlist.
311ReservedPreamble reserved byte (was device ID); ignored.
32–4716Vendor Authenticity NumberVendor coin AN for this RAIDA. Compared to the stored AN; mismatch → ERROR_INVALID_AN, nothing written.
481Mailbox denomination (entry 1)Target mailbox denomination (signed, −8 to +6).
49–524Mailbox serial number (entry 1)Target mailbox serial number, big-endian. The balance is keyed by (mailbox den, mailbox sn).
53–564Credit (entry 1)Bytes of storage credit to add. Unsigned 32-bit big-endian.
57…9 eachEntries 2…NZero or more further 9-byte entries, same den(1) sn(4) credit(4) layout, back-to-back. Up to 150 entries total.
last 22TerminatorFixed 3E 3E.

Response

Success is a status-only response: standard RAIDA response header with status 250 (STATUS_SUCCESS) and no payload. The credit has been added to the target mailbox’s balance on this RAIDA and recorded in the server’s durable purchase log.

Status codes

DecimalHexSymbolMeaning
2500xFASTATUS_SUCCESSCredit added to the mailbox balance.
160x10ERROR_INVALID_PACKET_LENGTHPayload is not a whole number of 9-byte entries, is empty, or exceeds 150 entries.
400x28ERROR_INVALID_SN_OR_DENOMINATIONVendor or mailbox denomination is out of the −8…+6 range.
1720xACERROR_VENDOR_NOT_AUTHORIZEDVendor (den,sn) is not on the server’s allowlist.
80x08ERROR_COIN_NOT_FOUNDThe vendor coin is not held by this RAIDA.
2000xC8ERROR_INVALID_ANVendor AN does not match the stored AN. Nothing is written.
1940xC2ERROR_FILESYSTEMBalance database write failed.

Common mistakes

Confusing the address spelling with the serial number

A QMail address like 20.100@giga is dotted base-256: the serial number is hi×256 + lo (here 20×256+100 = 5220), and the domain names the denomination (giga = 4). The allowlist and the wire fields use the real serial number, not the decimal spelling of the address.

Putting the vendor identity in the payload

The vendor is the preamble coin, just like an upload. The 9-byte payload carries only the target mailbox and the credit — there are no vendor fields after the preamble.

Subscribing to fewer than all QMail servers

Each RAIDA keeps its own balance table. A mailbox funded on only some servers will hit “no credit” on the others when it uploads; send the Subscribe to every QMail server.

Overrunning the batch or the packet budget

At most 150 entries fit in one request (150 × 9 + 48 + 2 = 1400 bytes). The payload must be an exact multiple of 9 bytes; a partial entry is rejected with ERROR_INVALID_PACKET_LENGTH. Split larger vendor runs across multiple requests.