Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions history/src/servers/history/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const listPrices = wrapAsyncToRunInSpan({
fnName: "listPrices",
fn: async (
{ request }: grpc.ServerUnaryCall<GetPriceHistoryArgs, unknown>,
callback: grpc.sendUnaryData<{ priceHistory: Tick[] }>,
callback: grpc.sendUnaryData<{
priceHistory: Array<Tick & { price_v2: number }>
}>,
) => {
const { currency, range } = request
const priceHistory = await History.getPriceHistory({ currency, range })
Expand All @@ -40,7 +42,17 @@ const listPrices = wrapAsyncToRunInSpan({
})
}

return callback(null, { priceHistory })
// ENG-317 / Phase A: populate both `price` (deprecated float32) and
// `price_v2` (double) on every Tick from the same source value. The
// wire will quantise `price` through float32; `price_v2` preserves
// the full float64. See realtime/run.ts and the proto for the full
// rollout plan.
const priceHistoryWithDouble = priceHistory.map((t) => ({
...t,
price_v2: t.price,
}))

return callback(null, { priceHistory: priceHistoryWithDouble })
},
})

Expand Down
7 changes: 6 additions & 1 deletion history/src/servers/protos/price_history.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ message PriceHistoryResponse {

message Tick {
uint64 timestamp = 1;
float price = 2;
// ENG-317 / Phase A of float→double rollout. See price.proto for the full
// rationale. Servers MUST populate both fields; clients SHOULD prefer
// `price_v2` and fall back to `price` when the server has not yet been
// upgraded. `float price = 2` will be removed in Phase B.
float price = 2 [deprecated = true];
double price_v2 = 3;
}
16 changes: 15 additions & 1 deletion realtime/src/servers/protos/price.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@ service PriceFeed {
}

message PriceResponse {
float price = 1;
// ENG-317 / Phase A of float→double rollout.
//
// `price` (float32) is lossy for non-USD/non-BTC currencies — the JMD
// round-trip exhibited ~J$0.80 of drift, see ENG-316 / lnflash/flash#282.
// It is preserved here at its original tag for wire compatibility with
// pre-ENG-317 clients and servers, and is marked deprecated.
//
// Servers MUST populate both `price` and `price_v2` for the duration of
// Phase A. Clients SHOULD prefer `price_v2` and fall back to `price` when
// talking to a server that has not yet been upgraded.
//
// Phase B (future PR) will remove `float price = 1` once all clients are
// confirmed upgraded in prod.
float price = 1 [deprecated = true];
double price_v2 = 3;
}

message PriceQuery {
Expand Down
10 changes: 8 additions & 2 deletions realtime/src/servers/realtime/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const getPrice = wrapAsyncToRunInSpan({
fnName: "getPrice",
fn: async (
{ request }: grpc.ServerUnaryCall<{ currency: string }, unknown>,
callback: grpc.sendUnaryData<{ price: Price }>,
callback: grpc.sendUnaryData<{ price: Price; price_v2: Price }>,
) => {
const currency = request.currency
const price = await Realtime.getPrice(currency)
Expand All @@ -40,7 +40,13 @@ const getPrice = wrapAsyncToRunInSpan({
})
}

return callback(null, { price })
// ENG-317 / Phase A: populate both the legacy float field (`price`) and
// the new double field (`price_v2`) from the same source value. The
// float wire encoding will quantise `price` to ~24 bits of mantissa;
// `price_v2` carries the full float64 we computed. Clients prefer
// `price_v2` and fall back to `price` only when talking to a server
// that pre-dates this change. Phase B will drop `price` entirely.
return callback(null, { price, price_v2: price })
},
})

Expand Down