wallet: DEX order RPC methods (create/conclude/fill/freeze/list) - #2
Conversation
Adds the six order RPC wrappers the market-maker needs: - CreateOrder / ConcludeOrder / FillOrder / FreezeOrder - ListOwnOrders / ListAllActiveOrders (currency filters) - OutputValue (Coin|Token tagged wire type), OwnOrder/ActiveOrder/OrderState Wire shapes verified against wallet-rpc-daemon v1.4.0 on testnet; orders.go at 100% statement coverage.
|
🔍 OpenCodeReview found 3 issue(s) in this PR.
📄
|
| if raw.Content.Amount != nil { | ||
| v.Amount = *raw.Content.Amount | ||
| } | ||
| return nil |
There was a problem hiding this comment.
UnmarshalJSON silently accepts a Coin/Token value with a missing or null "amount" (or a Token with an empty "id"), leaving OutputValue with a zero Amount. MarshalJSON validates TokenID but not Amount, so the contract is asymmetric: a malformed response, or a hand-built OutputValue{Coin:true} passed in CreateOrderParams.Ask/Give, is serialized as {"type":"Coin","content":{"amount":{}}} (Amount has omitempty on both fields) and the order is submitted with no amount at all. Since Amount "at least one of Atoms or Decimal must be set", validate here (and/or in MarshalJSON) and return an error instead of producing a zero-valued value.
Suggestion:
| if raw.Content.Amount != nil { | |
| v.Amount = *raw.Content.Amount | |
| } | |
| return nil | |
| if raw.Content.Amount == nil || (raw.Content.Amount.Atoms == "" && raw.Content.Amount.Decimal == "") { | |
| return fmt.Errorf("wallet: output value %q requires an amount", raw.Type) | |
| } | |
| v.Amount = *raw.Content.Amount | |
| if !v.Coin && v.TokenID == "" { | |
| return fmt.Errorf("wallet: token OutputValue requires TokenID") | |
| } | |
| return nil |
… validation
- MarshalJSON/UnmarshalJSON both reject OutputValue without any amount
(previously serialized {"amount":{}} or silently decoded a zero value —
an order could have been submitted with no amount at all)
- UnmarshalJSON also rejects a Token value with an empty id (was
marshal-only: asymmetric contract)
- TokenFilter("") now returns an error instead of building a filter that
only fails with an opaque daemon-side RPC error
Review: OpenCodeReview run 34820118630 (1 inline bug·medium + 1 summary
bug·low); both addressed. orders.go 100% coverage, package 84.2%.
| // Coin filters carry no content on the wire (daemon-verified); | ||
| // token filters encode the bech32 id as content. | ||
| if f.Type == "Coin" { | ||
| return json.Marshal(struct { | ||
| Type string `json:"type"` | ||
| }{Type: f.Type}) |
There was a problem hiding this comment.
MarshalJSON silently drops Content for any Coin-typed filter, including a zero-value-free misuse like &CurrencyFilter{Type: "Coin", Content: tokenID} or a mutated TokenFilter result, so ListAllActiveOrders would silently match the native coin instead of the intended token. Also, unlike the TokenFilter constructor, no validation ensures a non-Coin Type carries non-empty Content (e.g. &CurrencyFilter{Type: "Token"} marshals as a token filter with empty content). Prefer failing on these inconsistent states instead of silently encoding a possibly different currency.
Suggestion:
| // Coin filters carry no content on the wire (daemon-verified); | |
| // token filters encode the bech32 id as content. | |
| if f.Type == "Coin" { | |
| return json.Marshal(struct { | |
| Type string `json:"type"` | |
| }{Type: f.Type}) | |
| switch f.Type { | |
| case "Coin": | |
| if f.Content != "" { | |
| return nil, fmt.Errorf("wallet: Coin filter must not carry content") | |
| } | |
| return json.Marshal(struct { | |
| Type string `json:"type"` | |
| }{Type: f.Type}) | |
| case "Token": | |
| if f.Content == "" { | |
| return nil, fmt.Errorf("wallet: Token filter requires a token id") | |
| } | |
| return json.Marshal(struct { | |
| Type string `json:"type"` | |
| Content string `json:"content"` | |
| }{Type: f.Type, Content: f.Content}) | |
| } | |
| return nil, fmt.Errorf("wallet: unknown currency filter type %q", f.Type) |
Adds the six order RPC wrappers the market-maker needs:
Wire shapes verified against wallet-rpc-daemon v1.4.0 on testnet; orders.go at 100% statement coverage.