Commit Graph

496 Commits

Author SHA1 Message Date
Rusty Russell
ea0b8040c2 doc: include delnetworkevent in generated documentation, and grpc.
Also added missing "added" annotation.  This meant that I had to manually
change contrib/msggen/msggen/patch.py to insert that added notation where it
was missing from .msggen.json.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: introduced this release.
2025-11-24 14:31:02 +10:30
Rusty Russell
b74d32f6c4 lightningd: add withhold option to fundchannel_complete.
This is just a polite way of telling us that if we close, don't bother broadcasting
since we didn't broadcast the funding tx.

Changelog-Added: JSON-RPC: `fundchannel_complete` new parameter `withhold` (default false).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-19 07:23:39 +10:30
Rusty Russell
39349965a6 lightningd: add withheld flag to listpeerchannels and listclosedchannels.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: JSON-RPC: `listpeerchannels` `funding` object `withheld` flag, and `listclosedchannels` `funding_withheld` flags, indicating fundchannel_complete was called with the `withheld` parameter true.
2025-11-19 07:23:39 +10:30
Rusty Russell
606aad07ed lightningd: expose funding PSBT (if we have it) in JSON API.
Changelog-Added: JSON-RPC: `psbt` field in `funding` in listpeerchannels, and `funding_psbt` in listclosedchannels.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-19 07:23:39 +10:30
Rusty Russell
ae9ecba375 sendpsbt: update channel psbts if this is a channel PSBT.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-19 07:23:39 +10:30
Rusty Russell
7c7f1e4235 lightningd: deprecate "message": null in channel_state_changed notifications.
Somehow I missed this when deprecating `short_channel_id` being null.

Changelog-Deprecated: Plugins: `channel_state_changed` notification `message` field being `null`: it will be omitted instead.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-18 14:28:22 +10:30
Rusty Russell
64563c51f4 schemas: allow *CLOSED* state in channel_state_changed notification.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-18 14:28:22 +10:30
Rusty Russell
1102d8063e askrene: add optional layers to reservations.
We have the issue of aliases: xpay uses scids like 0x0x0 for
routehints and blinded paths, and then can apply reservations to them.  But
generally, reservations are *global*, so we need to differentiate.

Changelog-Added: Plugins: `askrene-reserve` and `askrene-unreserve` can take an optional `layer` inside `path` elements.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-17 13:52:54 +10:30
Lagrang3
4f1c8806d7 askrene: add askrene-bias-node rpc
Changelog-Added: askrene-bias-node: an RPC command to set a bias on node's outgoing or incoming channels.

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2025-11-13 15:15:27 +10:30
Lagrang3
5769beb1db askrene: add timestamp to biases
We add one more field to biases: "timestamp".
With the timestamp variable old biases can be removed with the
askrene-age command.

Changelog-Added: Plugins: askrene channel biases now have an associated timestamp, and are timed out by askrene-age

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2025-11-13 15:15:27 +10:30
Rusty Russell
41e21d1d70 autoclean: don't increment num_cleaned when record wasn't even a candidate.
For example, `autoclean-once failedforwards` would count every non-failed forwards
as "uncleaned".

This is both technically correct and completely useless.

Changelog-Fixed: JSON-RPC: `autoclean-once` returns "uncleaned" number reflecting number of candidates which were too new to be cleaned, not all records we didn't delete.
Fixes: https://github.com/ElementsProject/lightning/issues/8632
Reported-by: @grubles and several other sharp-eyed users.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-13 13:58:13 +10:30
daywalker90
e9f3aaf8af docs: fix htlc states description regarding direction
Changelog-None
2025-11-13 12:21:44 +10:30
Rusty Russell
ec05e5da91 autoclean: clean network events (30 days by default).
We also document this in the listnetworkevents command itself.

The test_autoclean_once was getting repetitive, so I cleaned that
up too.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: `autoclean` will remove networkevents after 30 days by default.
2025-11-12 13:58:43 +10:30
Rusty Russell
9f54f01470 lightningd: delnetworkevent support
Changelog-Added: JSON-RPC: `delnetworkevent` to delete from listnetworkevents.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-12 13:58:43 +10:30
Rusty Russell
3b332948dd lightningd: implement listnetworkevents.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-12 13:58:43 +10:30
Rusty Russell
39b0e65a6a lightningd: add networkevents to wait API.
Changelog-Added: JSON-RPC: `wait` now has `networkevents` subsystem.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-12 13:58:43 +10:30
Rusty Russell
c9fdf60ac1 wallet: make p2tr the default address for newaddr.
Of course we still have to return a `bech32` for the deprecation period.

Changelog-Added: JSON-RPC: `newaddr` will now return a `p2tr` field by default.
Changelog-Deprecated: JSON-RPC: `newaddr` returning a `bech32` field if `addresstype` is not specified (use `p2tr`).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-07 10:51:04 +10:30
Sangbida Chaudhuri
310405761a schema: update schema to remove bip86 and add mnemonic to expose secret
This schema change updates newaddr to remove bip86 which was previously added, since don't want to make unnecessary schema changes this is being removed.

The generated files for the exposesecret schema change are also being added
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
7f3a57cc41 tests: add BIP86 support 2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
de9c6305a1 exposesecret: Add support for mnemonic-based HSM secrets
Update the exposesecret plugin to work with the new unified HSM secret
format that supports BIP39 mnemonics.

Changelog-Added - exposesecret now has a mnemonic field
2025-10-26 12:37:58 +10:30
Rusty Russell
71f164a454 autogenerate-rpc-examples.py: add examples for listchainmoves and listchannelmoves.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
0d18b82dae plugins: cancelrecurringinvoice command.
`fetchinvoice` variant, for setting invreq_recurrence_cancel instead.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: `cancelrecurringinvoice` command to send new "don't expect any more invoice requests" msg to recurring bolt12 invoices.
2025-10-01 15:31:30 +09:30
Rusty Russell
54444e4337 BOLT12: Update recurrence to latest spec draft.
Changes:
* Fields renumbered to their draft values + billion.
* offer_recurrence now comes in compulsory or optional (backwards compat) flavors.
* `proportional_amount` is now inside `offer_recurrence_base` not `offer_recurrence_paywindow`.
* New field `invreq_recurrence_cancel`.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: Draft specification for recurring offers changed: old recurring offers will no longer work.
2025-10-01 15:31:30 +09:30
Rusty Russell
e7ea57e130 BOLT12: Remove start_any_period from recurrence_base.
Offer_absolute_expiry should be used if you want to require starting at the start.

Changelog-EXPERIMENTAL: Protocol: BOLT 12 recurrence `start_any_period` removed, use expiry if you need to restrict when they can start using the offer.
2025-10-01 15:31:30 +09:30
Rusty Russell
05005475e3 BOLT12: Remove years from recurrence.
Use months instead.

Changelog-EXPERIMENTAL: Protocol: BOLT 12 recurrence `years` removed; use 12 x months.
2025-10-01 15:31:30 +09:30
Rusty Russell
22a5e9e7e6 common: reintroduce "ignored" primary tag.
Prior to 23.05, we used this tag to mark onchain to-self inputs we didn't
wait for (because they were too small).  This fixes migration if that happened
(and we are debating whether we should re-introduce this!).

```
lightningd: FATAL SIGNAL 6 (version v25.09rc2)                      
0x100c8683 send_backtrace                                           
        common/daemon.c:33                                          
0x100c876f crashdump                                                
        common/daemon.c:78                                          
0x7fffb2080493 ???                                                  
        ???:0                                                       
0x7fffb1ab0cac ???                                                  
        __pthread_kill_implementation+0x1bc:0
0x7fffb1a48a5b ???                                                  
        __GI_raise+0x2b:0                                           
0x7fffb1a2a3db ???                                                  
        __GI_abort+0x153:0                                          
0x100935b7 migrate_from_account_db
        wallet/account_migration.c:424
0x10093ff7 db_migrate                                               
        wallet/db.c:1139                                            
0x10096763 db_setup                                                 
        wallet/db.c:1185                                            
0x100a1bcb wallet_new                                               
        wallet/wallet.c:223                                         
0x1004485f main                                                     
        lightningd/lightningd.c:1311
0x7fffb1a2aba3 ???                                                  
        __libc_start_call_main+0x93:0
0x7fffb1a2adeb ???                                                  
        __libc_start_main_alias_1+0x1ab:0
0xffffffffffffffff ???                                              
        ???:0                                                       
lightningd: Died with signal 6                                  
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Fixes: https://github.com/ElementsProject/lightning/issues/8484
2025-08-28 13:41:44 +09:30
Rusty Russell
ebc9a8b28e lightningd: fix name of chainmoves journal entry.
```
lightningd: FATAL SIGNAL 6 (version v25.09rc1-1-ga00ed81)
0x5c9e848ca050 send_backtrace
	common/daemon.c:33
0x5c9e848ca249 crashdump
	common/daemon.c:78
0x7f451664532f ???
	./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0x7f451669eb2c __pthread_kill_implementation
	./nptl/pthread_kill.c:44
0x7f451669eb2c __pthread_kill_internal
	./nptl/pthread_kill.c:78
0x7f451669eb2c __GI___pthread_kill
	./nptl/pthread_kill.c:89
0x7f451664527d __GI_raise
	../sysdeps/posix/raise.c:26
0x7f45166288fe __GI_abort
	./stdlib/abort.c:79
0x5c9e84893ac3 migrate_from_account_db
	wallet/account_migration.c:500
0x5c9e848943f7 db_migrate
	wallet/db.c:1139
...
#5  0x0000555555615ac4 in migrate_from_account_db (ld=0x555555999238, db=0x55555599b158) at wallet/account_migration.c:500
500				abort();
(gdb) p ev->tag
$1 = 0x555555a4fbb8 "journal_entry"
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-21 13:21:17 +09:30
Rusty Russell
78f88c1c0c common: use "foreign" in extra_tags to indicate a chain movement is injected.
This allows the bookkeeper plugin to know it's not actually a channel account.

Remove the "ignored" tag from the schema too: we removed it previously.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-19 13:37:50 +09:30
Rusty Russell
3ae222540b plugins/sql: use created_index as primary key, where available.
It's a unique integer, and very useful for querying changes.  Unlike
our generated rowid, it's *stable* across queries.

We still need an explicit rowid column for list commands which don't
(currently) have this.

Here's the documentation diff:

    @@ -85,69 +85,69 @@
     TABLES
     ------
     
    -Note that the first column of every table is a unique integer called `rowid`: this is used for related tables to refer to specific rows in their parent. sqlite3 usually has this as an implicit column, but we make it explicit as the implicit version is not allowed to be used as a foreign key.
    +Note that tables which have a `created_index` field use that as the primary key (and `rowid` is an alias to this), otherwise an explicit `rowid` integer primary key is generated, whose value changes on each refresh.  This field is used for related tables to refer to specific rows in their parent. (sqlite3 usually has this as an implicit column, but we make it explicit as the implicit version is not allowed to be used as a foreign key).
     
     The following tables are currently supported:
     - `bkpr_accountevents` (see lightning-bkpr-listaccountevents(7))
    @@ -119,14 +119,14 @@
       - `payment_id` (type `hex`, sqltype `BLOB`)
     
     - `chainmoves` indexed by `account_id` (see lightning-listchainmoves(7))
    -  - `created_index` (type `u64`, sqltype `INTEGER`)
    +  - `created_index` (type `u64`, sqltype `INTEGER PRIMARY KEY`)
       - `account_id` (type `string`, sqltype `TEXT`)
       - `credit_msat` (type `msat`, sqltype `INTEGER`)
       - `debit_msat` (type `msat`, sqltype `INTEGER`)
       - `timestamp` (type `u64`, sqltype `INTEGER`)
       - `primary_tag` (type `string`, sqltype `TEXT`)
       - related table `chainmoves_extra_tags`
    -    - `row` (reference to `chainmoves.rowid`, sqltype `INTEGER`)
    +    - `row` (reference to `chainmoves.created_index`, sqltype `INTEGER`)
         - `arrindex` (index within array, sqltype `INTEGER`)
         - `extra_tags` (type `string`, sqltype `TEXT`)
       - `peer_id` (type `pubkey`, sqltype `BLOB`)
    @@ -139,7 +139,7 @@
       - `blockheight` (type `u32`, sqltype `INTEGER`)
     
     - `channelmoves` indexed by `account_id` (see lightning-listchannelmoves(7))
    -  - `created_index` (type `u64`, sqltype `INTEGER`)
    +  - `created_index` (type `u64`, sqltype `INTEGER PRIMARY KEY`)
       - `account_id` (type `string`, sqltype `TEXT`)
       - `credit_msat` (type `msat`, sqltype `INTEGER`)
       - `debit_msat` (type `msat`, sqltype `INTEGER`)
    @@ -204,7 +204,7 @@
       - `last_stable_connection` (type `u64`, sqltype `INTEGER`)
     
     - `forwards` indexed by `in_channel` and `in_htlc_id` (see lightning-listforwards(7))
    -  - `created_index` (type `u64`, sqltype `INTEGER`)
    +  - `created_index` (type `u64`, sqltype `INTEGER PRIMARY KEY`)
       - `in_channel` (type `short_channel_id`, sqltype `TEXT`)
       - `in_htlc_id` (type `u64`, sqltype `INTEGER`)
       - `in_msat` (type `msat`, sqltype `INTEGER`)
    @@ -222,7 +222,7 @@
     
     - `htlcs` indexed by `short_channel_id` and `id` (see lightning-listhtlcs(7))
       - `short_channel_id` (type `short_channel_id`, sqltype `TEXT`)
    -  - `created_index` (type `u64`, sqltype `INTEGER`)
    +  - `created_index` (type `u64`, sqltype `INTEGER PRIMARY KEY`)
       - `updated_index` (type `u64`, sqltype `INTEGER`)
       - `id` (type `u64`, sqltype `INTEGER`)
       - `expiry` (type `u32`, sqltype `INTEGER`)
    @@ -242,7 +242,7 @@
       - `bolt12` (type `string`, sqltype `TEXT`)
       - `local_offer_id` (type `hash`, sqltype `BLOB`)
       - `invreq_payer_note` (type `string`, sqltype `TEXT`)
    -  - `created_index` (type `u64`, sqltype `INTEGER`)
    +  - `created_index` (type `u64`, sqltype `INTEGER PRIMARY KEY`)
       - `updated_index` (type `u64`, sqltype `INTEGER`)
       - `pay_index` (type `u64`, sqltype `INTEGER`)
       - `amount_received_msat` (type `msat`, sqltype `INTEGER`)
    @@ -408,7 +408,7 @@
       - `features` (type `hex`, sqltype `BLOB`)
     
     - `sendpays` indexed by `payment_hash` (see lightning-listsendpays(7))
    -  - `created_index` (type `u64`, sqltype `INTEGER`)
    +  - `created_index` (type `u64`, sqltype `INTEGER PRIMARY KEY`)
       - `id` (type `u64`, sqltype `INTEGER`)
       - `groupid` (type `u64`, sqltype `INTEGER`)
       - `partid` (type `u64`, sqltype `INTEGER`)

Changelog-Changed: Plugins: `sql` tables `forwards`, `htlcs`, `invoices`, `sendpays` all use `created_index` as their primary key (and `rowid` is now an alias to this).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-19 13:37:50 +09:30
Rusty Russell
cfbca30b7f plugins/sql: add listchainmoves and listchannelmoves.
And note the other commands in See Also section.

Note that this means handling the "outpoint" type.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: JSON-RPC: `sql` plugin now supports `chainmoves` and `channelmoves` tables.
2025-08-19 13:37:50 +09:30
Rusty Russell
6c626b124b lightningd: add chainmoves and channelmoves to wait command.
Only makes sense to wait on creation, since they neither are deleted
nor updated.

We also enhance the list commands to take the standard index options.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: JSON-RPC: `wait`: new subsystems `chainmoves` and `channelmoves`.
2025-08-19 13:37:50 +09:30
Rusty Russell
7c2a74684e lightningd: add listchainmoves and listchannelmoves commands.
This is where all the previous work pays off: we can access the coinmoves
in the db.

Changelog-Added: JSON-RPC: `listchainmoves` and `listchannelmoves` commands to access the audit log of coin movements.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-19 13:37:50 +09:30
Rusty Russell
6799dbe656 xpay: add option to pay bip353.
Changelog-Added: JSON-RPC: `xpay` can now directly pay a BIP353 address, like `₿rusty@rustcorp.com.au`.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-18 14:57:46 +09:30
Rusty Russell
103a49ef51 xpay: support paying a (simple) bolt12 offer directly.
fetchinvoice is still good for detailed diagnostics and handling
recurring invoices and alternate currencies, but this covers the
"throw some sats" case well.

Changelog-Added: JSON-RPC: `xpay` can now pay a simple offer directly, rather than requiring fetchinvoice first.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-18 14:57:46 +09:30
Rusty Russell
9680404fc4 doc/schemas: add websocket to type in doc/schemas/notification/connect.json
This is done by tests/test_connection.py::test_websocket:

```
{
  "jsonrpc": "2.0",
  "method": "connect",
  "params": {
    "connect": {
      "id": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
      "direction": "in",
      "address": {
        "type": "websocket",
        "subtype": "ipv4",
        "address": "127.0.0.1",
        "port": 59412
      }
    }
  }
}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-18 10:01:07 +09:30
Rusty Russell
a686bda4cb lightningd: deprecate null short_channel_id and unknown old_state in channel_state_changed notification
We always prefer to omit fields rather than use 'null' (or unknown!).

Note that before this, the schema was broken, so we have to put a special
exemption in for that case.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-18 10:01:07 +09:30
ShahanaFarooqui
4b64b694b3 docs: Added fetchbip353 example in autogenerate script
Other doc examples fixes from 25.05 till 25.09 updates.
2025-08-17 09:47:19 +09:30
Lagrang3
0c5c7a5334 askrene: add maxparts
Changelog-Added: askrene: add a new parameter maxparts to getroutes that limits the number of routes in the solution.

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2025-08-15 16:13:19 +09:30
daywalker90
e3e41163e2 cln-bip353: add plugin that fetches payment instructions from human readable addresses
Changelog-Add: new plugin cln-bip353 that can fetch BIP-353 payment instructions from human readable addresses
2025-08-14 18:41:23 +09:30
ShahanaFarooqui
2e58ed6f23 docs: Added json_object and json_group_array to permitted_sqlite3_functions list 2025-08-13 15:52:53 +09:30
Lagrang3
73f03318bd askrene: update the docs on auto.no_mpp_support
Changelog-None

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2025-07-18 15:13:41 +09:30
Rusty Russell
c50bd381ec doc: recommend injectpaymentonion in place of sendonion.
Among other things, injectpaymentonion insists on knowing the destination
amount_msat.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-06-30 13:23:26 +09:30
Rusty Russell
89f411ca79 doc: be explicit (with tests!) on when we don't know amount_msat for listsendpays.
Sangbida and I traced back through ancient history: when the pay plugin was introduced
in 0.9.0 (2019!) it already used the amount_msat parameter (then called `msatoshi`),
so this case effectively "never happens".

But we added a test for it just in case.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-06-30 13:23:26 +09:30
Rusty Russell
50e4aabe18 commando: remove old commando rune commands.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Removed: JSON-RPC: `commando-rune`, `commando-listrunes`, `commando-blacklist` (deprecated v23.08, disabled v25.05).
2025-06-25 09:06:31 +09:30
Rusty Russell
884778635c deprecations: update v26.05 to v26.06.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Future release schedule moved one month: v25.05 is now v25.06, and all deprecations incremented accordingly.
2025-06-24 09:57:24 +09:30
Rusty Russell
094ac3518f deprecations: update v26.02 to v26.03.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-06-24 09:57:24 +09:30
Rusty Russell
09e03e98ef deprecations: update v25.11 to v25.12.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-06-24 09:57:24 +09:30
Alex Myers
2b8b709bfd meta: update changelog for v25.05
Changelog-None
2025-06-16 13:10:33 -05:00
Alex Myers
8d6ae149ff release: update version for 25.05rc1
Changelog-None
2025-05-19 14:12:55 -05:00
Matt Whitlock
968bb63739 doc: properly handle ``preformatted blocks``
Lowdown requires a blank line before all preformatted blocks, or it doesn't
recognize them. `tools/md2man.sh` contained some ad-hoc efforts at fixing up
some locations where these required blank lines are absent from the output of
`tools/fromschema.py`, but it missed some. Instead of playing Whack-a-Mole, use
a blanket sed expression to ensure that a blank line precedes _every_ opening
```.

`esc_underscores(…)` in `tools/fromschema.py` did not work correctly on strings
containing an odd number of backticks, notably the ``` delimiters surrounding
preformatted text blocks. Specifically, it was dropping the last backtick since
none of the alternatives in the regex matched it. Add a new alternative that
matches a whole preformatted block as a single unit.

`output_member(…)` in `tools/fromschema.py` was passing each line of a member's
description through `esc_underscores(…)` individually, but that breaks
preformatted text blocks that are naturally multi-line and leads to mistakenly
escaping underscores inside such blocks. Rewrite the code to make use of the
`outputs(…)` utility function that joins all the provided lines together before
passing the whole text through `esc_underscores(…)`.

Drive-by fix a couple of flubbed preformatted blocks in schemas.

[ Added shellcheck suppression for md2man.sh --RR ]
Changelog-None
2025-05-15 16:06:08 +09:30