mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-20 13:54:36 +01:00
global: remove deprecated non-msat-named msat fields.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Removed: JSON-RPC: all the non-msat-named millisatoshi fields deprecated in v0.12.0.
This commit is contained in:
parent
67f23c19f7
commit
780f32dfc6
27 changed files with 95 additions and 287 deletions
2
cln-grpc/proto/node.proto
generated
2
cln-grpc/proto/node.proto
generated
|
@ -75,7 +75,6 @@ message GetinfoResponse {
|
|||
optional GetinfoOur_features our_features = 10;
|
||||
uint32 blockheight = 11;
|
||||
string network = 12;
|
||||
optional uint64 msatoshi_fees_collected = 18;
|
||||
Amount fees_collected_msat = 13;
|
||||
repeated GetinfoAddress address = 14;
|
||||
repeated GetinfoBinding binding = 15;
|
||||
|
@ -1204,7 +1203,6 @@ message GetrouteRoute {
|
|||
bytes id = 1;
|
||||
string channel = 2;
|
||||
uint32 direction = 3;
|
||||
optional uint64 msatoshi = 7;
|
||||
Amount amount_msat = 4;
|
||||
uint32 delay = 5;
|
||||
GetrouteRouteStyle style = 6;
|
||||
|
|
6
cln-grpc/src/convert.rs
generated
6
cln-grpc/src/convert.rs
generated
|
@ -63,8 +63,6 @@ impl From<responses::GetinfoResponse> for pb::GetinfoResponse {
|
|||
our_features: c.our_features.map(|v| v.into()),
|
||||
blockheight: c.blockheight, // Rule #2 for type u32
|
||||
network: c.network, // Rule #2 for type string
|
||||
#[allow(deprecated)]
|
||||
msatoshi_fees_collected: c.msatoshi_fees_collected, // Rule #2 for type u64?
|
||||
fees_collected_msat: Some(c.fees_collected_msat.into()), // Rule #2 for type msat
|
||||
address: c.address.into_iter().map(|i| i.into()).collect(), // Rule #3 for type GetinfoAddress
|
||||
binding: c.binding.map(|arr| arr.into_iter().map(|i| i.into()).collect()).unwrap_or(vec![]), // Rule #3
|
||||
|
@ -994,8 +992,6 @@ impl From<responses::GetrouteRoute> for pb::GetrouteRoute {
|
|||
id: c.id.serialize().to_vec(), // Rule #2 for type pubkey
|
||||
channel: c.channel.to_string(), // Rule #2 for type short_channel_id
|
||||
direction: c.direction, // Rule #2 for type u32
|
||||
#[allow(deprecated)]
|
||||
msatoshi: c.msatoshi, // Rule #2 for type u64?
|
||||
amount_msat: Some(c.amount_msat.into()), // Rule #2 for type msat
|
||||
delay: c.delay, // Rule #2 for type u32
|
||||
style: c.style as i32,
|
||||
|
@ -2403,7 +2399,6 @@ impl From<pb::GetinfoResponse> for responses::GetinfoResponse {
|
|||
our_features: c.our_features.map(|v| v.into()),
|
||||
blockheight: c.blockheight, // Rule #1 for type u32
|
||||
network: c.network, // Rule #1 for type string
|
||||
msatoshi_fees_collected: c.msatoshi_fees_collected, // Rule #1 for type u64?
|
||||
fees_collected_msat: c.fees_collected_msat.unwrap().into(), // Rule #1 for type msat
|
||||
address: c.address.into_iter().map(|s| s.into()).collect(), // Rule #4
|
||||
binding: Some(c.binding.into_iter().map(|s| s.into()).collect()), // Rule #4
|
||||
|
@ -3332,7 +3327,6 @@ impl From<pb::GetrouteRoute> for responses::GetrouteRoute {
|
|||
id: PublicKey::from_slice(&c.id).unwrap(), // Rule #1 for type pubkey
|
||||
channel: cln_rpc::primitives::ShortChannelId::from_str(&c.channel).unwrap(), // Rule #1 for type short_channel_id
|
||||
direction: c.direction, // Rule #1 for type u32
|
||||
msatoshi: c.msatoshi, // Rule #1 for type u64?
|
||||
amount_msat: c.amount_msat.unwrap().into(), // Rule #1 for type msat
|
||||
delay: c.delay, // Rule #1 for type u32
|
||||
style: c.style.try_into().unwrap(),
|
||||
|
|
|
@ -244,7 +244,6 @@ fn test_getinfo() {
|
|||
"version": "v0.10.2-509-ged26651-modded",
|
||||
"blockheight": 103,
|
||||
"network": "regtest",
|
||||
"msatoshi_fees_collected": 0,
|
||||
"fees_collected_msat": "0msat", "lightning-dir": "/tmp/ltests-20irp76f/test_pay_variants_1/lightning-1/regtest",
|
||||
"our_features": {"init": "8808226aa2", "node": "80008808226aa2", "channel": "", "invoice": "024200"}});
|
||||
let u: cln_rpc::model::GetinfoResponse = serde_json::from_value(j.clone()).unwrap();
|
||||
|
|
6
cln-rpc/src/model.rs
generated
6
cln-rpc/src/model.rs
generated
|
@ -1421,9 +1421,6 @@ pub mod responses {
|
|||
pub our_features: Option<GetinfoOur_features>,
|
||||
pub blockheight: u32,
|
||||
pub network: String,
|
||||
#[deprecated]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub msatoshi_fees_collected: Option<u64>,
|
||||
pub fees_collected_msat: Amount,
|
||||
pub address: Vec<GetinfoAddress>,
|
||||
#[serde(skip_serializing_if = "crate::is_none_or_empty")]
|
||||
|
@ -3329,9 +3326,6 @@ pub mod responses {
|
|||
pub id: PublicKey,
|
||||
pub channel: ShortChannelId,
|
||||
pub direction: u32,
|
||||
#[deprecated]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub msatoshi: Option<u64>,
|
||||
pub amount_msat: Amount,
|
||||
pub delay: u32,
|
||||
// Path `GetRoute.route[].style`
|
||||
|
|
|
@ -51,8 +51,7 @@ void json_add_bolt11(struct json_stream *response,
|
|||
json_add_u64(response, "expiry", b11->expiry);
|
||||
json_add_node_id(response, "payee", &b11->receiver_id);
|
||||
if (b11->msat)
|
||||
json_add_amount_msat_compat(response, *b11->msat,
|
||||
"msatoshi", "amount_msat");
|
||||
json_add_amount_msat(response, "amount_msat", *b11->msat);
|
||||
if (b11->description)
|
||||
json_add_string(response, "description", b11->description);
|
||||
if (b11->description_hash)
|
||||
|
|
|
@ -589,16 +589,6 @@ void json_add_psbt(struct json_stream *stream,
|
|||
tal_free(psbt);
|
||||
}
|
||||
|
||||
void json_add_amount_msat_compat(struct json_stream *result,
|
||||
struct amount_msat msat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
{
|
||||
if (deprecated_apis)
|
||||
json_add_u64(result, rawfieldname, msat.millisatoshis); /* Raw: low-level helper */
|
||||
json_add_amount_msat_only(result, msatfieldname, msat);
|
||||
}
|
||||
|
||||
void json_add_amount_msat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_msat msat)
|
||||
|
@ -612,16 +602,6 @@ void json_add_amount_msat_only(struct json_stream *result,
|
|||
json_add_u64(result, msatfieldname, msat.millisatoshis); /* Raw: low-level helper */
|
||||
}
|
||||
|
||||
void json_add_amount_sat_compat(struct json_stream *result,
|
||||
struct amount_sat sat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
{
|
||||
if (deprecated_apis)
|
||||
json_add_u64(result, rawfieldname, sat.satoshis); /* Raw: low-level helper */
|
||||
json_add_amount_sat_msat(result, msatfieldname, sat);
|
||||
}
|
||||
|
||||
void json_add_amount_sat_msat(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
|
@ -632,22 +612,6 @@ void json_add_amount_sat_msat(struct json_stream *result,
|
|||
json_add_amount_msat_only(result, msatfieldname, msat);
|
||||
}
|
||||
|
||||
/* When I noticed that we were adding "XXXmsat" fields *not* ending in _msat */
|
||||
void json_add_amount_sats_deprecated(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
if (deprecated_apis) {
|
||||
struct amount_msat msat;
|
||||
assert(!strends(fieldname, "_msat"));
|
||||
if (amount_sat_to_msat(&msat, sat))
|
||||
json_add_string(result, fieldname,
|
||||
take(fmt_amount_msat(NULL, msat)));
|
||||
}
|
||||
json_add_amount_sat_msat(result, msatfieldname, sat);
|
||||
}
|
||||
|
||||
void json_add_sats(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct amount_sat sat)
|
||||
|
|
|
@ -324,31 +324,14 @@ void json_add_address_internal(struct json_stream *response,
|
|||
const char *fieldname,
|
||||
const struct wireaddr_internal *addr);
|
||||
|
||||
/* Adds both a 'raw' number field and an 'amount_msat' field */
|
||||
void json_add_amount_msat_compat(struct json_stream *result,
|
||||
struct amount_msat msat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds both a 'raw' number field and an 'amount_msat' field */
|
||||
void json_add_amount_sat_compat(struct json_stream *result,
|
||||
struct amount_sat sat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_msat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_msat msat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_sat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
/* Compat shim */
|
||||
#define json_add_amount_msat json_add_amount_msat_only
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_sat_msat(struct json_stream *result,
|
||||
|
@ -356,13 +339,6 @@ void json_add_amount_sat_msat(struct json_stream *result,
|
|||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field, and an older deprecated field. */
|
||||
void json_add_amount_sats_deprecated(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* This is used to create requests, *never* for output (output is always
|
||||
* msat!) */
|
||||
void json_add_sats(struct json_stream *result,
|
||||
|
|
|
@ -57,9 +57,6 @@ struct json_filter **command_filter_ptr(struct command *cmd UNNEEDED)
|
|||
{ fprintf(stderr, "command_filter_ptr called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for fmt_amount_msat */
|
||||
const char *fmt_amount_msat(const tal_t *ctx UNNEEDED, struct amount_msat msat UNNEEDED)
|
||||
{ fprintf(stderr, "fmt_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for fmt_amount_sat */
|
||||
const char *fmt_amount_sat(const tal_t *ctx UNNEEDED, struct amount_sat sat UNNEEDED)
|
||||
{ fprintf(stderr, "fmt_amount_sat called!\n"); abort(); }
|
||||
|
|
|
@ -59,7 +59,6 @@ def getinfo2py(m):
|
|||
"lightning_dir": m.lightning_dir, # PrimitiveField in generate_composite
|
||||
"blockheight": m.blockheight, # PrimitiveField in generate_composite
|
||||
"network": m.network, # PrimitiveField in generate_composite
|
||||
"msatoshi_fees_collected": m.msatoshi_fees_collected, # PrimitiveField in generate_composite
|
||||
"fees_collected_msat": amount2msat(m.fees_collected_msat), # PrimitiveField in generate_composite
|
||||
"address": [getinfo_address2py(i) for i in m.address], # ArrayField[composite] in generate_composite
|
||||
"binding": [getinfo_binding2py(i) for i in m.binding], # ArrayField[composite] in generate_composite
|
||||
|
@ -787,7 +786,6 @@ def getroute_route2py(m):
|
|||
"id": hexlify(m.id), # PrimitiveField in generate_composite
|
||||
"channel": m.channel, # PrimitiveField in generate_composite
|
||||
"direction": m.direction, # PrimitiveField in generate_composite
|
||||
"msatoshi": m.msatoshi, # PrimitiveField in generate_composite
|
||||
"amount_msat": amount2msat(m.amount_msat), # PrimitiveField in generate_composite
|
||||
"delay": m.delay, # PrimitiveField in generate_composite
|
||||
"style": str(m.style), # EnumField in generate_composite
|
||||
|
|
|
@ -52,7 +52,6 @@ On success, an object is returned, containing:
|
|||
- **node** (hex): features in our node\_announcement message
|
||||
- **channel** (hex): negotiated channel features we (as channel initiator) publish in the channel\_announcement message
|
||||
- **invoice** (hex): features in our BOLT11 invoices
|
||||
- **msatoshi\_fees\_collected** (u64, optional) **deprecated, removal in v23.05**
|
||||
- **binding** (array of objects, optional): The addresses we are listening on:
|
||||
- **type** (string): Type of connection (one of "local socket", "ipv4", "ipv6", "torv2", "torv3")
|
||||
- **address** (string, optional): address in expected format for **type**
|
||||
|
@ -133,4 +132,4 @@ RESOURCES
|
|||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
|
||||
[comment]: # ( SHA256STAMP:5c7c4d6279279b6c92cd3b039dcb24429214b2460a6ad82bed384796389a9b5c)
|
||||
[comment]: # ( SHA256STAMP:ac7ea19a5294ebb8d8e0acaa3e813849ce1b1f7f8ef2f3e52a9ca22e5e5d82fc)
|
||||
|
|
|
@ -286,7 +286,6 @@ On success, an object containing **route** is returned. It is an array of objec
|
|||
- **amount\_msat** (msat): The amount expected by the node at the end of this hop
|
||||
- **delay** (u32): The total CLTV expected by the node at the end of this hop
|
||||
- **style** (string): The features understood by the destination node (always "tlv")
|
||||
- **msatoshi** (u64, optional) **deprecated, removal in v23.05**
|
||||
|
||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||
|
||||
|
@ -311,4 +310,4 @@ RESOURCES
|
|||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
|
||||
[comment]: # ( SHA256STAMP:336fb7d687a26e733ca0cc5f0ca49fb00edfaf311edc43773375201b1180f716)
|
||||
[comment]: # ( SHA256STAMP:9ef1e1107c9b649e3e1c17593e3b1855852e60060c70ed6b13ff73b5575cffad)
|
||||
|
|
|
@ -94,10 +94,6 @@
|
|||
"type": "string",
|
||||
"description": "represents the type of network on the node are working (e.g: `bitcoin`, `testnet`, or `regtest`)"
|
||||
},
|
||||
"msatoshi_fees_collected": {
|
||||
"type": "u64",
|
||||
"deprecated": "v0.12.0"
|
||||
},
|
||||
"fees_collected_msat": {
|
||||
"type": "msat",
|
||||
"description": "Total routing fees collected by this node"
|
||||
|
|
|
@ -32,10 +32,6 @@
|
|||
"type": "u32",
|
||||
"description": "0 if this channel is traversed from lesser to greater **id**, otherwise 1"
|
||||
},
|
||||
"msatoshi": {
|
||||
"type": "u64",
|
||||
"deprecated": "v0.12.0"
|
||||
},
|
||||
"amount_msat": {
|
||||
"type": "msat",
|
||||
"description": "The amount expected by the node at the end of this hop"
|
||||
|
|
|
@ -150,13 +150,9 @@ void json_add_unsaved_channel(struct json_stream *response,
|
|||
/* funding + our_upfront_shutdown only available if we're initiator */
|
||||
if (oa->role == TX_INITIATOR) {
|
||||
if (amount_sat_to_msat(&total, oa->funding)) {
|
||||
json_add_amount_msat_compat(response, total,
|
||||
"msatoshi_to_us",
|
||||
"to_us_msat");
|
||||
json_add_amount_msat(response, "to_us_msat", total);
|
||||
/* This will change if peer adds funds */
|
||||
json_add_amount_msat_compat(response, total,
|
||||
"msatoshi_total",
|
||||
"total_msat");
|
||||
json_add_amount_msat(response, "total_msat", total);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,11 +285,11 @@ static void openchannel2_hook_serialize(struct openchannel2_payload *payload,
|
|||
json_object_start(stream, "openchannel2");
|
||||
json_add_node_id(stream, "id", &payload->peer_id);
|
||||
json_add_channel_id(stream, "channel_id", &payload->channel_id);
|
||||
json_add_amount_sats_deprecated(stream, "their_funding", "their_funding_msat",
|
||||
payload->their_funding);
|
||||
json_add_amount_sats_deprecated(stream, "dust_limit_satoshis",
|
||||
"dust_limit_msat",
|
||||
payload->dust_limit_satoshis);
|
||||
json_add_amount_sat_msat(stream,
|
||||
"their_funding_msat", payload->their_funding);
|
||||
json_add_amount_sat_msat(stream,
|
||||
"dust_limit_msat", payload->dust_limit_satoshis);
|
||||
|
||||
json_add_amount_msat_only(stream, "max_htlc_value_in_flight_msat",
|
||||
payload->max_htlc_value_in_flight_msat);
|
||||
json_add_amount_msat_only(stream, "htlc_minimum_msat",
|
||||
|
|
|
@ -44,14 +44,12 @@ static void json_add_invoice_fields(struct json_stream *response,
|
|||
json_add_invstring(response, inv->invstring);
|
||||
json_add_sha256(response, "payment_hash", &inv->rhash);
|
||||
if (inv->msat)
|
||||
json_add_amount_msat_compat(response, *inv->msat,
|
||||
"msatoshi", "amount_msat");
|
||||
json_add_amount_msat(response, "amount_msat", *inv->msat);
|
||||
json_add_string(response, "status", invoice_status_str(inv));
|
||||
if (inv->state == PAID) {
|
||||
json_add_u64(response, "pay_index", inv->pay_index);
|
||||
json_add_amount_msat_compat(response, inv->received,
|
||||
"msatoshi_received",
|
||||
"amount_received_msat");
|
||||
json_add_amount_msat(response,
|
||||
"amount_received_msat", inv->received);
|
||||
json_add_u64(response, "paid_at", inv->paid_timestamp);
|
||||
json_add_preimage(response, "payment_preimage", &inv->r);
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ static void channel_opened_notification_serialize(struct json_stream *stream,
|
|||
{
|
||||
json_object_start(stream, "channel_opened");
|
||||
json_add_node_id(stream, "id", node_id);
|
||||
json_add_amount_sats_deprecated(stream, "amount", "funding_msat", *funding_sat);
|
||||
json_add_amount_sat_msat(stream, "funding_msat", *funding_sat);
|
||||
json_add_txid(stream, "funding_txid", funding_txid);
|
||||
if (deprecated_apis)
|
||||
json_add_bool(stream, "funding_locked", channel_ready);
|
||||
|
@ -490,26 +490,18 @@ static void coin_movement_notification_serialize(struct json_stream *stream,
|
|||
json_add_string(stream, "originating_account",
|
||||
mvt->originating_acct);
|
||||
json_mvt_id(stream, mvt->type, &mvt->id);
|
||||
if (deprecated_apis) {
|
||||
json_add_amount_msat_only(stream, "credit", mvt->credit);
|
||||
json_add_amount_msat_only(stream, "debit", mvt->debit);
|
||||
}
|
||||
json_add_amount_msat_only(stream, "credit_msat", mvt->credit);
|
||||
json_add_amount_msat_only(stream, "debit_msat", mvt->debit);
|
||||
|
||||
/* Only chain movements */
|
||||
if (mvt->output_val)
|
||||
json_add_amount_sats_deprecated(stream, "output_value",
|
||||
"output_msat",
|
||||
*mvt->output_val);
|
||||
json_add_amount_sat_msat(stream,
|
||||
"output_msat", *mvt->output_val);
|
||||
if (mvt->output_count > 0)
|
||||
json_add_num(stream, "output_count",
|
||||
mvt->output_count);
|
||||
|
||||
if (mvt->fees) {
|
||||
if (deprecated_apis)
|
||||
json_add_amount_msat_only(stream, "fees",
|
||||
*mvt->fees);
|
||||
json_add_amount_msat_only(stream, "fees_msat",
|
||||
*mvt->fees);
|
||||
}
|
||||
|
@ -556,9 +548,6 @@ static void balance_snapshot_notification_serialize(struct json_stream *stream,
|
|||
json_object_start(stream, NULL);
|
||||
json_add_string(stream, "account_id",
|
||||
snap->accts[i]->acct_id);
|
||||
if (deprecated_apis)
|
||||
json_add_amount_msat_only(stream, "balance",
|
||||
snap->accts[i]->balance);
|
||||
json_add_amount_msat_only(stream, "balance_msat",
|
||||
snap->accts[i]->balance);
|
||||
json_add_string(stream, "coin_type", snap->accts[i]->bip173_name);
|
||||
|
|
|
@ -62,10 +62,8 @@ void json_add_uncommitted_channel(struct json_stream *response,
|
|||
/* These should never fail. */
|
||||
if (amount_sat_to_msat(&total, uc->fc->funding_sats)
|
||||
&& amount_msat_sub(&ours, total, uc->fc->push)) {
|
||||
json_add_amount_msat_compat(response, ours,
|
||||
"msatoshi_to_us", "to_us_msat");
|
||||
json_add_amount_msat_compat(response, total,
|
||||
"msatoshi_total", "total_msat");
|
||||
json_add_amount_msat(response, "to_us_msat", ours);
|
||||
json_add_amount_msat(response, "total_msat", total);
|
||||
}
|
||||
|
||||
json_array_start(response, "features");
|
||||
|
@ -646,14 +644,14 @@ static void openchannel_hook_serialize(struct openchannel_hook_payload *payload,
|
|||
struct uncommitted_channel *uc = payload->openingd->channel;
|
||||
json_object_start(stream, "openchannel");
|
||||
json_add_node_id(stream, "id", &uc->peer->id);
|
||||
json_add_amount_sats_deprecated(stream, "funding_satoshis", "funding_msat",
|
||||
payload->funding_satoshis);
|
||||
json_add_amount_sat_msat(stream, "funding_msat",
|
||||
payload->funding_satoshis);
|
||||
json_add_amount_msat_only(stream, "push_msat", payload->push_msat);
|
||||
json_add_amount_sats_deprecated(stream, "dust_limit_satoshis", "dust_limit_msat",
|
||||
payload->dust_limit_satoshis);
|
||||
json_add_amount_sat_msat(stream, "dust_limit_msat",
|
||||
payload->dust_limit_satoshis);
|
||||
json_add_amount_msat_only(stream, "max_htlc_value_in_flight_msat",
|
||||
payload->max_htlc_value_in_flight_msat);
|
||||
json_add_amount_sats_deprecated(stream, "channel_reserve_satoshis", "channel_reserve_msat",
|
||||
json_add_amount_sat_msat(stream, "channel_reserve_msat",
|
||||
payload->channel_reserve_satoshis);
|
||||
json_add_amount_msat_only(stream, "htlc_minimum_msat",
|
||||
payload->htlc_minimum_msat);
|
||||
|
|
|
@ -123,11 +123,9 @@ void json_add_payment_fields(struct json_stream *response,
|
|||
/* If we have a 0 amount delivered at the remote end we simply don't
|
||||
* know since the onion was generated externally. */
|
||||
if (amount_msat_greater(t->msatoshi, AMOUNT_MSAT(0)))
|
||||
json_add_amount_msat_compat(response, t->msatoshi, "msatoshi",
|
||||
"amount_msat");
|
||||
json_add_amount_msat(response, "amount_msat", t->msatoshi);
|
||||
|
||||
json_add_amount_msat_compat(response, t->msatoshi_sent,
|
||||
"msatoshi_sent", "amount_sent_msat");
|
||||
json_add_amount_msat(response, "amount_sent_msat", t->msatoshi_sent);
|
||||
json_add_u32(response, "created_at", t->timestamp);
|
||||
if (t->completed_at)
|
||||
json_add_u32(response, "completed_at", *t->completed_at);
|
||||
|
|
|
@ -452,8 +452,7 @@ static void json_add_htlcs(struct lightningd *ld,
|
|||
json_object_start(response, NULL);
|
||||
json_add_string(response, "direction", "in");
|
||||
json_add_u64(response, "id", hin->key.id);
|
||||
json_add_amount_msat_compat(response, hin->msat,
|
||||
"msatoshi", "amount_msat");
|
||||
json_add_amount_msat(response, "amount_msat", hin->msat);
|
||||
json_add_u32(response, "expiry", hin->cltv_expiry);
|
||||
json_add_sha256(response, "payment_hash", &hin->payment_hash);
|
||||
json_add_string(response, "state",
|
||||
|
@ -476,8 +475,7 @@ static void json_add_htlcs(struct lightningd *ld,
|
|||
json_object_start(response, NULL);
|
||||
json_add_string(response, "direction", "out");
|
||||
json_add_u64(response, "id", hout->key.id);
|
||||
json_add_amount_msat_compat(response, hout->msat,
|
||||
"msatoshi", "amount_msat");
|
||||
json_add_amount_msat(response, "amount_msat", hout->msat);
|
||||
json_add_u64(response, "expiry", hout->cltv_expiry);
|
||||
json_add_sha256(response, "payment_hash", &hout->payment_hash);
|
||||
json_add_string(response, "state",
|
||||
|
@ -928,14 +926,12 @@ static void json_add_channel(struct lightningd *ld,
|
|||
&channel->funding_sats));
|
||||
funding_msat = AMOUNT_MSAT(0);
|
||||
}
|
||||
json_add_amount_msat_compat(response, channel->our_msat,
|
||||
"msatoshi_to_us", "to_us_msat");
|
||||
json_add_amount_msat_compat(response, channel->msat_to_us_min,
|
||||
"msatoshi_to_us_min", "min_to_us_msat");
|
||||
json_add_amount_msat_compat(response, channel->msat_to_us_max,
|
||||
"msatoshi_to_us_max", "max_to_us_msat");
|
||||
json_add_amount_msat_compat(response, funding_msat,
|
||||
"msatoshi_total", "total_msat");
|
||||
json_add_amount_msat(response, "to_us_msat", channel->our_msat);
|
||||
json_add_amount_msat(response,
|
||||
"min_to_us_msat", channel->msat_to_us_min);
|
||||
json_add_amount_msat(response,
|
||||
"max_to_us_msat", channel->msat_to_us_max);
|
||||
json_add_amount_msat(response, "total_msat", funding_msat);
|
||||
|
||||
/* routing fees */
|
||||
json_add_amount_msat_only(response, "fee_base_msat",
|
||||
|
@ -944,13 +940,10 @@ static void json_add_channel(struct lightningd *ld,
|
|||
channel->feerate_ppm);
|
||||
|
||||
/* channel config */
|
||||
json_add_amount_sat_compat(response,
|
||||
channel->our_config.dust_limit,
|
||||
"dust_limit_satoshis", "dust_limit_msat");
|
||||
json_add_amount_msat_compat(response,
|
||||
channel->our_config.max_htlc_value_in_flight,
|
||||
"max_htlc_value_in_flight_msat",
|
||||
"max_total_htlc_in_msat");
|
||||
json_add_amount_sat_msat(response, "dust_limit_msat",
|
||||
channel->our_config.dust_limit);
|
||||
json_add_amount_msat(response, "max_total_htlc_in_msat",
|
||||
channel->our_config.max_htlc_value_in_flight);
|
||||
|
||||
/* The `channel_reserve_satoshis` is imposed on
|
||||
* the *other* side (see `channel_reserve_msat`
|
||||
|
@ -959,29 +952,26 @@ static void json_add_channel(struct lightningd *ld,
|
|||
* is imposed on their side, while their
|
||||
* configuration `channel_reserve_satoshis` is
|
||||
* imposed on ours. */
|
||||
json_add_amount_sat_compat(response,
|
||||
channel->our_config.channel_reserve,
|
||||
"their_channel_reserve_satoshis",
|
||||
"their_reserve_msat");
|
||||
json_add_amount_sat_compat(response,
|
||||
channel->channel_info.their_config.channel_reserve,
|
||||
"our_channel_reserve_satoshis",
|
||||
"our_reserve_msat");
|
||||
json_add_amount_sat_msat(response,
|
||||
"their_reserve_msat",
|
||||
channel->our_config.channel_reserve);
|
||||
json_add_amount_sat_msat(response,
|
||||
"our_reserve_msat",
|
||||
channel->channel_info.their_config.channel_reserve);
|
||||
|
||||
/* append spendable to JSON output */
|
||||
json_add_amount_msat_compat(response,
|
||||
channel_amount_spendable(channel),
|
||||
"spendable_msatoshi", "spendable_msat");
|
||||
json_add_amount_msat(response,
|
||||
"spendable_msat",
|
||||
channel_amount_spendable(channel));
|
||||
|
||||
/* append receivable to JSON output */
|
||||
json_add_amount_msat_compat(response,
|
||||
channel_amount_receivable(channel),
|
||||
"receivable_msatoshi", "receivable_msat");
|
||||
json_add_amount_msat(response,
|
||||
"receivable_msat",
|
||||
channel_amount_receivable(channel));
|
||||
|
||||
json_add_amount_msat_compat(response,
|
||||
channel->our_config.htlc_minimum,
|
||||
"htlc_minimum_msat",
|
||||
"minimum_htlc_in_msat");
|
||||
json_add_amount_msat(response,
|
||||
"minimum_htlc_in_msat",
|
||||
channel->our_config.htlc_minimum);
|
||||
json_add_amount_msat_only(response,
|
||||
"minimum_htlc_out_msat",
|
||||
channel->htlc_minimum_msat);
|
||||
|
@ -1032,28 +1022,24 @@ static void json_add_channel(struct lightningd *ld,
|
|||
wallet_channel_stats_load(ld->wallet, channel->dbid, &channel_stats);
|
||||
json_add_u64(response, "in_payments_offered",
|
||||
channel_stats.in_payments_offered);
|
||||
json_add_amount_msat_compat(response,
|
||||
channel_stats.in_msatoshi_offered,
|
||||
"in_msatoshi_offered",
|
||||
"in_offered_msat");
|
||||
json_add_amount_msat(response,
|
||||
"in_offered_msat",
|
||||
channel_stats.in_msatoshi_offered);
|
||||
json_add_u64(response, "in_payments_fulfilled",
|
||||
channel_stats.in_payments_fulfilled);
|
||||
json_add_amount_msat_compat(response,
|
||||
channel_stats.in_msatoshi_fulfilled,
|
||||
"in_msatoshi_fulfilled",
|
||||
"in_fulfilled_msat");
|
||||
json_add_amount_msat(response,
|
||||
"in_fulfilled_msat",
|
||||
channel_stats.in_msatoshi_fulfilled);
|
||||
json_add_u64(response, "out_payments_offered",
|
||||
channel_stats.out_payments_offered);
|
||||
json_add_amount_msat_compat(response,
|
||||
channel_stats.out_msatoshi_offered,
|
||||
"out_msatoshi_offered",
|
||||
"out_offered_msat");
|
||||
json_add_amount_msat(response,
|
||||
"out_offered_msat",
|
||||
channel_stats.out_msatoshi_offered);
|
||||
json_add_u64(response, "out_payments_fulfilled",
|
||||
channel_stats.out_payments_fulfilled);
|
||||
json_add_amount_msat_compat(response,
|
||||
channel_stats.out_msatoshi_fulfilled,
|
||||
"out_msatoshi_fulfilled",
|
||||
"out_fulfilled_msat");
|
||||
json_add_amount_msat(response,
|
||||
"out_fulfilled_msat",
|
||||
channel_stats.out_msatoshi_fulfilled);
|
||||
|
||||
json_add_htlcs(ld, response, channel);
|
||||
json_object_end(response);
|
||||
|
@ -2434,10 +2420,9 @@ static struct command_result *json_getinfo(struct command *cmd,
|
|||
cmd->ld->gossip_blockheight);
|
||||
}
|
||||
json_add_string(response, "network", chainparams->network_name);
|
||||
json_add_amount_msat_compat(response,
|
||||
wallet_total_forward_fees(cmd->ld->wallet),
|
||||
"msatoshi_fees_collected",
|
||||
"fees_collected_msat");
|
||||
json_add_amount_msat(response,
|
||||
"fees_collected_msat",
|
||||
wallet_total_forward_fees(cmd->ld->wallet));
|
||||
json_add_string(response, "lightning-dir", cmd->ld->config_netdir);
|
||||
|
||||
if (!cmd->ld->topology->bitcoind->synced)
|
||||
|
|
|
@ -1088,10 +1088,6 @@ static void htlc_accepted_hook_serialize(struct htlc_accepted_hook_payload *p,
|
|||
if (p->payload->forward_node_id)
|
||||
json_add_pubkey(s, "next_node_id",
|
||||
p->payload->forward_node_id);
|
||||
if (deprecated_apis)
|
||||
json_add_string(s, "forward_amount",
|
||||
fmt_amount_msat(tmpctx,
|
||||
p->payload->amt_to_forward));
|
||||
json_add_amount_msat_only(s, "forward_msat",
|
||||
p->payload->amt_to_forward);
|
||||
json_add_u32(s, "outgoing_cltv_value", p->payload->outgoing_cltv);
|
||||
|
@ -1120,8 +1116,6 @@ static void htlc_accepted_hook_serialize(struct htlc_accepted_hook_payload *p,
|
|||
s, "short_channel_id",
|
||||
channel_scid_or_local_alias(hin->key.channel));
|
||||
json_add_u64(s, "id", hin->key.id);
|
||||
if (deprecated_apis)
|
||||
json_add_amount_msat_only(s, "amount", hin->msat);
|
||||
json_add_amount_msat_only(s, "amount_msat", hin->msat);
|
||||
json_add_u32(s, "cltv_expiry", expiry);
|
||||
json_add_s32(s, "cltv_expiry_relative", expiry - blockheight);
|
||||
|
@ -2897,18 +2891,12 @@ void json_add_forwarding_object(struct json_stream *response,
|
|||
if (cur->htlc_id_out)
|
||||
json_add_u64(response, "out_htlc_id", *cur->htlc_id_out);
|
||||
}
|
||||
json_add_amount_msat_compat(response,
|
||||
cur->msat_in,
|
||||
"in_msatoshi", "in_msat");
|
||||
json_add_amount_msat(response, "in_msat", cur->msat_in);
|
||||
|
||||
/* These can be unset (aka zero) if we failed before channel lookup */
|
||||
if (!amount_msat_eq(cur->msat_out, AMOUNT_MSAT(0))) {
|
||||
json_add_amount_msat_compat(response,
|
||||
cur->msat_out,
|
||||
"out_msatoshi", "out_msat");
|
||||
json_add_amount_msat_compat(response,
|
||||
cur->fee,
|
||||
"fee", "fee_msat");
|
||||
json_add_amount_msat(response, "out_msat", cur->msat_out);
|
||||
json_add_amount_msat(response, "fee_msat", cur->fee);
|
||||
}
|
||||
json_add_string(response, "status", forward_status_name(cur->status));
|
||||
|
||||
|
|
|
@ -333,26 +333,12 @@ void json_add_address_internal(struct json_stream *response UNNEEDED,
|
|||
const char *fieldname UNNEEDED,
|
||||
const struct wireaddr_internal *addr UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_address_internal called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_msat_compat */
|
||||
void json_add_amount_msat_compat(struct json_stream *result UNNEEDED,
|
||||
struct amount_msat msat UNNEEDED,
|
||||
const char *rawfieldname UNNEEDED,
|
||||
const char *msatfieldname)
|
||||
|
||||
{ fprintf(stderr, "json_add_amount_msat_compat called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_msat_only */
|
||||
void json_add_amount_msat_only(struct json_stream *result UNNEEDED,
|
||||
const char *msatfieldname UNNEEDED,
|
||||
struct amount_msat msat)
|
||||
|
||||
{ fprintf(stderr, "json_add_amount_msat_only called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_sat_compat */
|
||||
void json_add_amount_sat_compat(struct json_stream *result UNNEEDED,
|
||||
struct amount_sat sat UNNEEDED,
|
||||
const char *rawfieldname UNNEEDED,
|
||||
const char *msatfieldname)
|
||||
|
||||
{ fprintf(stderr, "json_add_amount_sat_compat called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_sat_msat */
|
||||
void json_add_amount_sat_msat(struct json_stream *result UNNEEDED,
|
||||
const char *msatfieldname UNNEEDED,
|
||||
|
|
|
@ -1896,8 +1896,6 @@ static void payment_add_attempt(struct json_stream *s, const char *fieldname, st
|
|||
json_add_string(s, "failreason", p->failreason);
|
||||
|
||||
json_add_u64(s, "partid", p->partid);
|
||||
if (deprecated_apis)
|
||||
json_add_amount_msat_only(s, "amount", p->amount);
|
||||
json_add_amount_msat_only(s, "amount_msat", p->amount);
|
||||
if (p->parent != NULL)
|
||||
json_add_u64(s, "parent_partid", p->parent->partid);
|
||||
|
@ -1975,11 +1973,9 @@ static void payment_finished(struct payment *p)
|
|||
json_add_timeabs(ret, "created_at", p->start_time);
|
||||
json_add_num(ret, "parts", result.attempts);
|
||||
|
||||
json_add_amount_msat_compat(ret, p->amount, "msatoshi",
|
||||
"amount_msat");
|
||||
json_add_amount_msat_compat(ret, result.sent,
|
||||
"msatoshi_sent",
|
||||
"amount_sent_msat");
|
||||
json_add_amount_msat(ret, "amount_msat", p->amount);
|
||||
json_add_amount_msat(ret, "amount_sent_msat",
|
||||
result.sent);
|
||||
|
||||
if (result.leafstates != PAYMENT_STEP_SUCCESS)
|
||||
json_add_string(
|
||||
|
@ -2069,12 +2065,9 @@ static void payment_finished(struct payment *p)
|
|||
json_add_string(ret, "status", "failed");
|
||||
}
|
||||
|
||||
json_add_amount_msat_compat(ret, p->amount, "msatoshi",
|
||||
"amount_msat");
|
||||
|
||||
json_add_amount_msat_compat(ret, result.sent,
|
||||
"msatoshi_sent",
|
||||
"amount_sent_msat");
|
||||
json_add_amount_msat(ret, "amount_msat", p->amount);
|
||||
json_add_amount_msat(ret, "amount_sent_msat",
|
||||
result.sent);
|
||||
|
||||
if (failure != NULL) {
|
||||
if (failure->erring_index)
|
||||
|
|
|
@ -630,10 +630,8 @@ static void on_payment_success(struct payment *payment)
|
|||
json_add_timeabs(ret, "created_at", p->start_time);
|
||||
json_add_num(ret, "parts", result.attempts);
|
||||
|
||||
json_add_amount_msat_compat(ret, p->amount, "msatoshi",
|
||||
"amount_msat");
|
||||
json_add_amount_msat_compat(ret, result.sent, "msatoshi_sent",
|
||||
"amount_sent_msat");
|
||||
json_add_amount_msat(ret, "amount_msat", p->amount);
|
||||
json_add_amount_msat(ret, "amount_sent_msat", result.sent);
|
||||
|
||||
if (result.leafstates != PAYMENT_STEP_SUCCESS)
|
||||
json_add_string(
|
||||
|
@ -670,8 +668,6 @@ static void payment_add_attempt(struct json_stream *s, const char *fieldname, st
|
|||
json_add_string(s, "failreason", p->failreason);
|
||||
|
||||
json_add_u64(s, "partid", p->partid);
|
||||
if (deprecated_apis)
|
||||
json_add_amount_msat_only(s, "amount", p->amount);
|
||||
json_add_amount_msat_only(s, "amount_msat", p->amount);
|
||||
if (p->parent != NULL)
|
||||
json_add_u64(s, "parent_partid", p->parent->partid);
|
||||
|
@ -772,12 +768,10 @@ static void on_payment_failure(struct payment *payment)
|
|||
json_add_string(ret, "status", "failed");
|
||||
}
|
||||
|
||||
json_add_amount_msat_compat(ret, p->amount, "msatoshi",
|
||||
"amount_msat");
|
||||
json_add_amount_msat(ret, "amount_msat", p->amount);
|
||||
|
||||
json_add_amount_msat_compat(ret, result.sent,
|
||||
"msatoshi_sent",
|
||||
"amount_sent_msat");
|
||||
json_add_amount_msat(ret, "amount_sent_msat",
|
||||
result.sent);
|
||||
|
||||
if (failure != NULL) {
|
||||
if (failure->erring_index)
|
||||
|
@ -902,10 +896,8 @@ payment_listsendpays_previous(struct command *cmd, const char *buf,
|
|||
ret = jsonrpc_stream_success(cmd);
|
||||
json_add_preimage(ret, "payment_preimage", &preimage);
|
||||
json_add_string(ret, "status", "complete");
|
||||
json_add_amount_msat_compat(ret, msat, "msatoshi",
|
||||
"amount_msat");
|
||||
json_add_amount_msat_compat(ret, sent, "msatoshi_sent",
|
||||
"amount_sent_msat");
|
||||
json_add_amount_msat(ret, "amount_msat", msat);
|
||||
json_add_amount_msat(ret, "amount_sent_msat", sent);
|
||||
json_add_node_id(ret, "destination", p->destination);
|
||||
json_add_sha256(ret, "payment_hash", p->payment_hash);
|
||||
json_add_u32(ret, "created_at", created_at);
|
||||
|
|
|
@ -33,13 +33,6 @@ bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
|||
bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
struct channel_id *channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_msat_compat */
|
||||
void json_add_amount_msat_compat(struct json_stream *result UNNEEDED,
|
||||
struct amount_msat msat UNNEEDED,
|
||||
const char *rawfieldname UNNEEDED,
|
||||
const char *msatfieldname)
|
||||
|
||||
{ fprintf(stderr, "json_add_amount_msat_compat called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_msat_only */
|
||||
void json_add_amount_msat_only(struct json_stream *result UNNEEDED,
|
||||
const char *msatfieldname UNNEEDED,
|
||||
|
|
|
@ -104,7 +104,7 @@ static void json_add_route_hop(struct json_stream *js,
|
|||
json_add_node_id(js, "id", &r->node_id);
|
||||
json_add_short_channel_id(js, "channel", &r->scid);
|
||||
json_add_num(js, "direction", r->direction);
|
||||
json_add_amount_msat_compat(js, r->amount, "msatoshi", "amount_msat");
|
||||
json_add_amount_msat(js, "amount_msat", r->amount);
|
||||
json_add_num(js, "delay", r->delay);
|
||||
json_add_string(js, "style", "tlv");
|
||||
json_object_end(js);
|
||||
|
@ -256,8 +256,7 @@ static void json_add_halfchan(struct json_stream *response,
|
|||
&htlc_minimum_msat,
|
||||
&htlc_maximum_msat);
|
||||
|
||||
json_add_amount_sat_compat(response, capacity,
|
||||
"satoshis", "amount_msat");
|
||||
json_add_amount_sat_msat(response, "amount_msat", capacity);
|
||||
json_add_num(response, "message_flags", message_flags);
|
||||
json_add_num(response, "channel_flags", channel_flags);
|
||||
|
||||
|
|
|
@ -292,26 +292,12 @@ void json_add_address_internal(struct json_stream *response UNNEEDED,
|
|||
const char *fieldname UNNEEDED,
|
||||
const struct wireaddr_internal *addr UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_address_internal called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_msat_compat */
|
||||
void json_add_amount_msat_compat(struct json_stream *result UNNEEDED,
|
||||
struct amount_msat msat UNNEEDED,
|
||||
const char *rawfieldname UNNEEDED,
|
||||
const char *msatfieldname)
|
||||
|
||||
{ fprintf(stderr, "json_add_amount_msat_compat called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_msat_only */
|
||||
void json_add_amount_msat_only(struct json_stream *result UNNEEDED,
|
||||
const char *msatfieldname UNNEEDED,
|
||||
struct amount_msat msat)
|
||||
|
||||
{ fprintf(stderr, "json_add_amount_msat_only called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_sat_compat */
|
||||
void json_add_amount_sat_compat(struct json_stream *result UNNEEDED,
|
||||
struct amount_sat sat UNNEEDED,
|
||||
const char *rawfieldname UNNEEDED,
|
||||
const char *msatfieldname)
|
||||
|
||||
{ fprintf(stderr, "json_add_amount_sat_compat called!\n"); abort(); }
|
||||
/* Generated stub for json_add_amount_sat_msat */
|
||||
void json_add_amount_sat_msat(struct json_stream *result UNNEEDED,
|
||||
const char *msatfieldname UNNEEDED,
|
||||
|
|
|
@ -247,8 +247,7 @@ static void json_add_utxo(struct json_stream *response,
|
|||
json_object_start(response, fieldname);
|
||||
json_add_txid(response, "txid", &utxo->outpoint.txid);
|
||||
json_add_num(response, "output", utxo->outpoint.n);
|
||||
json_add_amount_sat_compat(response, utxo->amount,
|
||||
"value", "amount_msat");
|
||||
json_add_amount_sat_msat(response, "amount_msat", utxo->amount);
|
||||
|
||||
if (utxo->is_p2sh) {
|
||||
struct pubkey key;
|
||||
|
@ -360,13 +359,12 @@ static struct command_result *json_listfunds(struct command *cmd,
|
|||
"short_channel_id",
|
||||
c->scid);
|
||||
|
||||
json_add_amount_sat_compat(response,
|
||||
amount_msat_to_sat_round_down(c->our_msat),
|
||||
"channel_sat",
|
||||
"our_amount_msat");
|
||||
json_add_amount_sat_compat(response, c->funding_sats,
|
||||
"channel_total_sat",
|
||||
"amount_msat");
|
||||
json_add_amount_msat(response,
|
||||
"our_amount_msat",
|
||||
c->our_msat);
|
||||
json_add_amount_sat_msat(response,
|
||||
"amount_msat",
|
||||
c->funding_sats);
|
||||
json_add_txid(response, "funding_txid",
|
||||
&c->funding.txid);
|
||||
json_add_num(response, "funding_output",
|
||||
|
@ -547,7 +545,7 @@ static void json_transaction_details(struct json_stream *response,
|
|||
json_object_start(response, NULL);
|
||||
|
||||
json_add_u32(response, "index", i);
|
||||
json_add_amount_sats_deprecated(response, "msat", "amount_msat", sat);
|
||||
json_add_amount_sat_msat(response, "amount_msat", sat);
|
||||
|
||||
#if EXPERIMENTAL_FEATURES
|
||||
struct tx_annotation *ann = &tx->output_annotations[i];
|
||||
|
|
Loading…
Add table
Reference in a new issue