mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
cmd/loop: display static loop-in monitor stages
This commit is contained in:
parent
e3e6205a4b
commit
4a2bcb3374
3 changed files with 600 additions and 7 deletions
|
|
@ -560,10 +560,7 @@ func parseAmt(text string) (btcutil.Amount, error) {
|
||||||
|
|
||||||
func logSwap(swap *looprpc.SwapStatus) {
|
func logSwap(swap *looprpc.SwapStatus) {
|
||||||
// If our swap failed, we add our failure reason to the state.
|
// If our swap failed, we add our failure reason to the state.
|
||||||
swapState := fmt.Sprintf("%v", swap.State)
|
swapState := monitorSwapState(swap)
|
||||||
if swap.State == looprpc.SwapState_FAILED {
|
|
||||||
swapState = fmt.Sprintf("%v (%v)", swapState, swap.FailureReason)
|
|
||||||
}
|
|
||||||
|
|
||||||
if swap.Type == looprpc.SwapType_LOOP_OUT {
|
if swap.Type == looprpc.SwapType_LOOP_OUT {
|
||||||
fmt.Printf("%v %v %v %v - %v",
|
fmt.Printf("%v %v %v %v - %v",
|
||||||
|
|
@ -585,10 +582,32 @@ func logSwap(swap *looprpc.SwapStatus) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if swap.State != looprpc.SwapState_INITIATED &&
|
showCost := shouldShowSwapCost(swap.GetState())
|
||||||
swap.State != looprpc.SwapState_HTLC_PUBLISHED &&
|
if swap.Type == looprpc.SwapType_STATIC_LOOP_IN {
|
||||||
swap.State != looprpc.SwapState_PREIMAGE_REVEALED {
|
staticState := swap.GetStaticLoopInState()
|
||||||
|
// Static loop-ins key cost visibility off the dedicated FSM state, not
|
||||||
|
// the generic SwapState lifecycle used by traditional swaps.
|
||||||
|
switch staticState {
|
||||||
|
case looprpc.StaticAddressLoopInSwapState_INIT_HTLC,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_SIGN_HTLC_TX,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_MONITOR_INVOICE_HTLC_TX,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_SWEEP_STATIC_ADDRESS_HTLC_TIMEOUT,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_MONITOR_HTLC_TIMEOUT_SWEEP,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_UNLOCK_DEPOSITS:
|
||||||
|
|
||||||
|
showCost = false
|
||||||
|
|
||||||
|
case looprpc.StaticAddressLoopInSwapState_PAYMENT_RECEIVED,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_HTLC_STATIC_ADDRESS_TIMEOUT_SWEPT,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_SUCCEEDED,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_SUCCEEDED_TRANSITIONING_FAILED,
|
||||||
|
looprpc.StaticAddressLoopInSwapState_FAILED_STATIC_ADDRESS_SWAP:
|
||||||
|
|
||||||
|
showCost = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if showCost {
|
||||||
fmt.Printf(" (cost: server %v, onchain %v, offchain %v)",
|
fmt.Printf(" (cost: server %v, onchain %v, offchain %v)",
|
||||||
swap.CostServer, swap.CostOnchain, swap.CostOffchain,
|
swap.CostServer, swap.CostOnchain, swap.CostOffchain,
|
||||||
)
|
)
|
||||||
|
|
@ -597,6 +616,38 @@ func logSwap(swap *looprpc.SwapStatus) {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// monitorSwapState returns the static loop-in FSM label for static swaps and
|
||||||
|
// the shared swap-state label for all others.
|
||||||
|
func monitorSwapState(swap *looprpc.SwapStatus) string {
|
||||||
|
if swap.Type == looprpc.SwapType_STATIC_LOOP_IN {
|
||||||
|
return swap.GetStaticLoopInState().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return genericMonitorSwapState(swap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// shouldShowSwapCost reports whether a swap's generic state is terminal enough
|
||||||
|
// to include the persisted cost summary in monitor output.
|
||||||
|
func shouldShowSwapCost(loopState looprpc.SwapState) bool {
|
||||||
|
return loopState != looprpc.SwapState_INITIATED &&
|
||||||
|
loopState != looprpc.SwapState_HTLC_PUBLISHED &&
|
||||||
|
loopState != looprpc.SwapState_PREIMAGE_REVEALED
|
||||||
|
}
|
||||||
|
|
||||||
|
// genericMonitorSwapState formats the shared swap-state label and failure
|
||||||
|
// reason used by non-static swaps.
|
||||||
|
func genericMonitorSwapState(swap *looprpc.SwapStatus) string {
|
||||||
|
loopState := swap.GetState()
|
||||||
|
swapState := fmt.Sprintf("%v", loopState)
|
||||||
|
if loopState == looprpc.SwapState_FAILED {
|
||||||
|
swapState = fmt.Sprintf(
|
||||||
|
"%v (%v)", swapState, swap.FailureReason,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return swapState
|
||||||
|
}
|
||||||
|
|
||||||
// getClientConn dials the loopd gRPC server with TLS and macaroon auth.
|
// getClientConn dials the loopd gRPC server with TLS and macaroon auth.
|
||||||
func getClientConn(address, tlsCertPath, macaroonPath string) (daemonConn,
|
func getClientConn(address, tlsCertPath, macaroonPath string) (daemonConn,
|
||||||
func(), error) {
|
func(), error) {
|
||||||
|
|
|
||||||
275
cmd/loop/monitor_test.go
Normal file
275
cmd/loop/monitor_test.go
Normal file
|
|
@ -0,0 +1,275 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/lightninglabs/loop/looprpc"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestMonitorSwapStateKeepsRegularLoopInFailureReason preserves the generic
|
||||||
|
// failure suffix for regular loop-in swaps so terminal errors stay visible.
|
||||||
|
func TestMonitorSwapStateKeepsRegularLoopInFailureReason(t *testing.T) {
|
||||||
|
swap := &looprpc.SwapStatus{
|
||||||
|
Type: looprpc.SwapType_LOOP_IN,
|
||||||
|
State: looprpc.SwapState_FAILED,
|
||||||
|
FailureReason: looprpc.
|
||||||
|
FailureReason_FAILURE_REASON_TIMEOUT,
|
||||||
|
}
|
||||||
|
|
||||||
|
got := monitorSwapState(swap)
|
||||||
|
require.Equal(t, "FAILED (FAILURE_REASON_TIMEOUT)", got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestMonitorSwapStateLabelsStaticLoopInStages locks the precise static loop-in
|
||||||
|
// stage names so monitor output stays stable as the FSM evolves.
|
||||||
|
func TestMonitorSwapStateLabelsStaticLoopInStages(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
staticState looprpc.StaticAddressLoopInSwapState
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "init htlc",
|
||||||
|
staticState: looprpc.StaticAddressLoopInSwapState_INIT_HTLC,
|
||||||
|
want: "INIT_HTLC",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sign htlc",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_SIGN_HTLC_TX,
|
||||||
|
want: "SIGN_HTLC_TX",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "monitor invoice and htlc",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_MONITOR_INVOICE_HTLC_TX,
|
||||||
|
want: "MONITOR_INVOICE_HTLC_TX",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unlock deposits",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_UNLOCK_DEPOSITS,
|
||||||
|
want: "UNLOCK_DEPOSITS",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "payment received",
|
||||||
|
staticState: looprpc.StaticAddressLoopInSwapState_PAYMENT_RECEIVED,
|
||||||
|
want: "PAYMENT_RECEIVED",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "timeout sweep",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_SWEEP_STATIC_ADDRESS_HTLC_TIMEOUT,
|
||||||
|
want: "SWEEP_STATIC_ADDRESS_HTLC_TIMEOUT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "monitor timeout sweep",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_MONITOR_HTLC_TIMEOUT_SWEEP,
|
||||||
|
want: "MONITOR_HTLC_TIMEOUT_SWEEP",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "timeout swept",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_HTLC_STATIC_ADDRESS_TIMEOUT_SWEPT,
|
||||||
|
want: "HTLC_STATIC_ADDRESS_TIMEOUT_SWEPT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "success",
|
||||||
|
staticState: looprpc.StaticAddressLoopInSwapState_SUCCEEDED,
|
||||||
|
want: "SUCCEEDED",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "succeeded transitioning failed",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_SUCCEEDED_TRANSITIONING_FAILED,
|
||||||
|
want: "SUCCEEDED_TRANSITIONING_FAILED",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "failed",
|
||||||
|
staticState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_FAILED_STATIC_ADDRESS_SWAP,
|
||||||
|
want: "FAILED_STATIC_ADDRESS_SWAP",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
swap := &looprpc.SwapStatus{
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
StaticLoopInStateOptional: &looprpc.SwapStatus_StaticLoopInState{
|
||||||
|
StaticLoopInState: test.staticState,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got := monitorSwapState(swap)
|
||||||
|
require.Equal(t, test.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
initSwap := &looprpc.SwapStatus{
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
StaticLoopInStateOptional: &looprpc.SwapStatus_StaticLoopInState{
|
||||||
|
StaticLoopInState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_INIT_HTLC,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
signSwap := &looprpc.SwapStatus{
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
StaticLoopInStateOptional: &looprpc.SwapStatus_StaticLoopInState{
|
||||||
|
StaticLoopInState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_SIGN_HTLC_TX,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
require.NotEqual(t, monitorSwapState(initSwap), monitorSwapState(signSwap))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestMonitorSwapStateLabelsUnknownStaticLoopIn ensures the absent static
|
||||||
|
// oneof maps to the UNKNOWN static loop-in label.
|
||||||
|
func TestMonitorSwapStateLabelsUnknownStaticLoopIn(t *testing.T) {
|
||||||
|
swap := &looprpc.SwapStatus{
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
}
|
||||||
|
|
||||||
|
got := monitorSwapState(swap)
|
||||||
|
require.Equal(t, "UNKNOWN_STATIC_ADDRESS_SWAP_STATE", got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestLogSwapHidesStaticLoopInCostForInFlightState proves in-flight static FSM
|
||||||
|
// state suppresses cost even with generic SUCCESS set deliberately.
|
||||||
|
func TestLogSwapHidesStaticLoopInCostForInFlightState(t *testing.T) {
|
||||||
|
swap := &looprpc.SwapStatus{
|
||||||
|
LastUpdateTime: time.Unix(1, 0).UnixNano(),
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
State: looprpc.SwapState_SUCCESS,
|
||||||
|
StaticLoopInStateOptional: &looprpc.SwapStatus_StaticLoopInState{
|
||||||
|
StaticLoopInState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_INIT_HTLC,
|
||||||
|
},
|
||||||
|
Amt: 50_000,
|
||||||
|
CostServer: 11,
|
||||||
|
CostOnchain: 22,
|
||||||
|
CostOffchain: 33,
|
||||||
|
HtlcAddressP2Wsh: "bc1qstaticinflighttestaddress",
|
||||||
|
}
|
||||||
|
|
||||||
|
output := captureStdout(t, func() {
|
||||||
|
logSwap(swap)
|
||||||
|
})
|
||||||
|
|
||||||
|
require.Contains(t, output, "STATIC_LOOP_IN INIT_HTLC 0.00050000 BTC")
|
||||||
|
require.NotContains(t, output, "(cost:")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestLogSwapHidesCostForUnknownStaticLoopInState ensures unknown static
|
||||||
|
// states print the UNKNOWN label without a cost summary.
|
||||||
|
func TestLogSwapHidesCostForUnknownStaticLoopInState(t *testing.T) {
|
||||||
|
swap := &looprpc.SwapStatus{
|
||||||
|
LastUpdateTime: time.Unix(3, 0).UnixNano(),
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
StaticLoopInStateOptional: &looprpc.SwapStatus_StaticLoopInState{
|
||||||
|
StaticLoopInState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_UNKNOWN_STATIC_ADDRESS_SWAP_STATE,
|
||||||
|
},
|
||||||
|
Amt: 50_000,
|
||||||
|
CostServer: 11,
|
||||||
|
CostOnchain: 22,
|
||||||
|
CostOffchain: 33,
|
||||||
|
HtlcAddressP2Wsh: "bc1qunknownstaticterminaltestaddress",
|
||||||
|
}
|
||||||
|
|
||||||
|
output := captureStdout(t, func() {
|
||||||
|
logSwap(swap)
|
||||||
|
})
|
||||||
|
|
||||||
|
require.Contains(
|
||||||
|
t, output, "STATIC_LOOP_IN UNKNOWN_STATIC_ADDRESS_SWAP_STATE 0.00050000 BTC",
|
||||||
|
)
|
||||||
|
require.NotContains(t, output, "(cost:")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestLogSwapShowsStaticLoopInCostForTerminalState preserves terminal cost
|
||||||
|
// output, including the P2WSH address, once the static loop-in is done.
|
||||||
|
func TestLogSwapShowsStaticLoopInCostForTerminalState(t *testing.T) {
|
||||||
|
swap := &looprpc.SwapStatus{
|
||||||
|
LastUpdateTime: time.Unix(2, 0).UnixNano(),
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
State: looprpc.SwapState_INITIATED,
|
||||||
|
StaticLoopInStateOptional: &looprpc.SwapStatus_StaticLoopInState{
|
||||||
|
StaticLoopInState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_SUCCEEDED,
|
||||||
|
},
|
||||||
|
Amt: 50_000,
|
||||||
|
CostServer: 11,
|
||||||
|
CostOnchain: 22,
|
||||||
|
CostOffchain: 33,
|
||||||
|
HtlcAddressP2Wsh: "bc1qstaticterminaltestaddress",
|
||||||
|
}
|
||||||
|
|
||||||
|
output := captureStdout(t, func() {
|
||||||
|
logSwap(swap)
|
||||||
|
})
|
||||||
|
|
||||||
|
require.Contains(
|
||||||
|
t, output,
|
||||||
|
"STATIC_LOOP_IN SUCCEEDED 0.00050000 BTC - P2WSH: bc1qstaticterminaltestaddress",
|
||||||
|
)
|
||||||
|
require.Contains(
|
||||||
|
t, output,
|
||||||
|
"(cost: server 11, onchain 22, offchain 33)",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestLogSwapDisplaysStaticLoopInTypeAndStage ensures the monitor output names
|
||||||
|
// the static loop-in type and active FSM stage instead of collapsing them.
|
||||||
|
func TestLogSwapDisplaysStaticLoopInTypeAndStage(t *testing.T) {
|
||||||
|
swap := &looprpc.SwapStatus{
|
||||||
|
LastUpdateTime: time.Unix(1, 0).UnixNano(),
|
||||||
|
Type: looprpc.SwapType_STATIC_LOOP_IN,
|
||||||
|
StaticLoopInStateOptional: &looprpc.SwapStatus_StaticLoopInState{
|
||||||
|
StaticLoopInState: looprpc.
|
||||||
|
StaticAddressLoopInSwapState_SIGN_HTLC_TX,
|
||||||
|
},
|
||||||
|
Amt: 50_000,
|
||||||
|
HtlcAddressP2Wsh: "tb1q5cyxnuxmeuwuvkwfem96llyxf8duyshm56t8k8",
|
||||||
|
}
|
||||||
|
|
||||||
|
output := captureStdout(t, func() {
|
||||||
|
logSwap(swap)
|
||||||
|
})
|
||||||
|
|
||||||
|
require.Contains(
|
||||||
|
t, output, "STATIC_LOOP_IN SIGN_HTLC_TX 0.00050000 BTC",
|
||||||
|
)
|
||||||
|
require.Contains(
|
||||||
|
t, output, "P2WSH: tb1q5cyxnuxmeuwuvkwfem96llyxf8duyshm56t8k8",
|
||||||
|
)
|
||||||
|
require.NotContains(t, output, "STATIC_LOOP_IN INIT_HTLC")
|
||||||
|
}
|
||||||
|
|
||||||
|
func captureStdout(t *testing.T, fn func()) string {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
originalStdout := os.Stdout
|
||||||
|
reader, writer, err := os.Pipe()
|
||||||
|
require.NoError(t, err)
|
||||||
|
os.Stdout = writer
|
||||||
|
|
||||||
|
fn()
|
||||||
|
|
||||||
|
require.NoError(t, writer.Close())
|
||||||
|
os.Stdout = originalStdout
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
_, err = io.Copy(&buf, reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, reader.Close())
|
||||||
|
|
||||||
|
return strings.TrimSpace(buf.String())
|
||||||
|
}
|
||||||
267
cmd/loop/testdata/sessions/basic-swaps/04_loop-monitor-static-loop-in.json
vendored
Normal file
267
cmd/loop/testdata/sessions/basic-swaps/04_loop-monitor-static-loop-in.json
vendored
Normal file
|
|
@ -0,0 +1,267 @@
|
||||||
|
{
|
||||||
|
"metadata": {
|
||||||
|
"args": [
|
||||||
|
"loop",
|
||||||
|
"monitor",
|
||||||
|
"--network",
|
||||||
|
"regtest"
|
||||||
|
],
|
||||||
|
"env": {},
|
||||||
|
"version": "0.33.3-beta commit= commit_hash=",
|
||||||
|
"run_error": "recv: rpc error: code = Canceled desc = context canceled",
|
||||||
|
"duration": 25407490958,
|
||||||
|
"clock_start_unix": 1784150305
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"time_ms": 13,
|
||||||
|
"kind": "grpc",
|
||||||
|
"data": {
|
||||||
|
"method": "/looprpc.SwapClient/Monitor",
|
||||||
|
"event": "send",
|
||||||
|
"message_type": "looprpc.MonitorRequest",
|
||||||
|
"payload": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 13,
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
"Note: offchain cost may report as 0 after loopd restart during swap\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 16479,
|
||||||
|
"kind": "grpc",
|
||||||
|
"data": {
|
||||||
|
"method": "/looprpc.SwapClient/Monitor",
|
||||||
|
"event": "recv",
|
||||||
|
"message_type": "looprpc.SwapStatus",
|
||||||
|
"payload": {
|
||||||
|
"amt": "500000",
|
||||||
|
"id": "bec3777d45337f652d96136e5714ed90a5d4f7cda87b5842110ecc38c9a65826",
|
||||||
|
"id_bytes": "vsN3fUUzf2UtlhNuVxTtkKXU982oe1hCEQ7MOMmmWCY=",
|
||||||
|
"type": "STATIC_LOOP_IN",
|
||||||
|
"state": "INITIATED",
|
||||||
|
"static_loop_in_state": "INIT_HTLC",
|
||||||
|
"failure_reason": "FAILURE_REASON_NONE",
|
||||||
|
"initiation_time": "1784150320647961000",
|
||||||
|
"last_update_time": "1784150321494895000",
|
||||||
|
"htlc_address": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2wsh": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2tr": "",
|
||||||
|
"cost_server": "0",
|
||||||
|
"cost_onchain": "0",
|
||||||
|
"cost_offchain": "0",
|
||||||
|
"last_hop": "",
|
||||||
|
"outgoing_chan_set": [],
|
||||||
|
"label": "",
|
||||||
|
"asset_info": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 16479,
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
"2026-07-15T18:18:41-03:00 STATIC_LOOP_IN INIT_HTLC 0.00500000 BTC - P2WSH: bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 16482,
|
||||||
|
"kind": "grpc",
|
||||||
|
"data": {
|
||||||
|
"method": "/looprpc.SwapClient/Monitor",
|
||||||
|
"event": "recv",
|
||||||
|
"message_type": "looprpc.SwapStatus",
|
||||||
|
"payload": {
|
||||||
|
"amt": "500000",
|
||||||
|
"id": "bec3777d45337f652d96136e5714ed90a5d4f7cda87b5842110ecc38c9a65826",
|
||||||
|
"id_bytes": "vsN3fUUzf2UtlhNuVxTtkKXU982oe1hCEQ7MOMmmWCY=",
|
||||||
|
"type": "STATIC_LOOP_IN",
|
||||||
|
"state": "INITIATED",
|
||||||
|
"static_loop_in_state": "SIGN_HTLC_TX",
|
||||||
|
"failure_reason": "FAILURE_REASON_NONE",
|
||||||
|
"initiation_time": "1784150320647961000",
|
||||||
|
"last_update_time": "1784150321499639000",
|
||||||
|
"htlc_address": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2wsh": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2tr": "",
|
||||||
|
"cost_server": "0",
|
||||||
|
"cost_onchain": "0",
|
||||||
|
"cost_offchain": "0",
|
||||||
|
"last_hop": "",
|
||||||
|
"outgoing_chan_set": [],
|
||||||
|
"label": "",
|
||||||
|
"asset_info": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 16482,
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
"2026-07-15T18:18:41-03:00 STATIC_LOOP_IN SIGN_HTLC_TX 0.00500000 BTC - P2WSH: bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 16530,
|
||||||
|
"kind": "grpc",
|
||||||
|
"data": {
|
||||||
|
"method": "/looprpc.SwapClient/Monitor",
|
||||||
|
"event": "recv",
|
||||||
|
"message_type": "looprpc.SwapStatus",
|
||||||
|
"payload": {
|
||||||
|
"amt": "500000",
|
||||||
|
"id": "bec3777d45337f652d96136e5714ed90a5d4f7cda87b5842110ecc38c9a65826",
|
||||||
|
"id_bytes": "vsN3fUUzf2UtlhNuVxTtkKXU982oe1hCEQ7MOMmmWCY=",
|
||||||
|
"type": "STATIC_LOOP_IN",
|
||||||
|
"state": "INITIATED",
|
||||||
|
"static_loop_in_state": "MONITOR_INVOICE_HTLC_TX",
|
||||||
|
"failure_reason": "FAILURE_REASON_NONE",
|
||||||
|
"initiation_time": "1784150320647961000",
|
||||||
|
"last_update_time": "1784150321548450000",
|
||||||
|
"htlc_address": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2wsh": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2tr": "",
|
||||||
|
"cost_server": "0",
|
||||||
|
"cost_onchain": "0",
|
||||||
|
"cost_offchain": "0",
|
||||||
|
"last_hop": "",
|
||||||
|
"outgoing_chan_set": [],
|
||||||
|
"label": "",
|
||||||
|
"asset_info": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 16530,
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
"2026-07-15T18:18:41-03:00 STATIC_LOOP_IN MONITOR_INVOICE_HTLC_TX 0.00500000 BTC - P2WSH: bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 17027,
|
||||||
|
"kind": "grpc",
|
||||||
|
"data": {
|
||||||
|
"method": "/looprpc.SwapClient/Monitor",
|
||||||
|
"event": "recv",
|
||||||
|
"message_type": "looprpc.SwapStatus",
|
||||||
|
"payload": {
|
||||||
|
"amt": "500000",
|
||||||
|
"id": "bec3777d45337f652d96136e5714ed90a5d4f7cda87b5842110ecc38c9a65826",
|
||||||
|
"id_bytes": "vsN3fUUzf2UtlhNuVxTtkKXU982oe1hCEQ7MOMmmWCY=",
|
||||||
|
"type": "STATIC_LOOP_IN",
|
||||||
|
"state": "INITIATED",
|
||||||
|
"static_loop_in_state": "PAYMENT_RECEIVED",
|
||||||
|
"failure_reason": "FAILURE_REASON_NONE",
|
||||||
|
"initiation_time": "1784150320647961000",
|
||||||
|
"last_update_time": "1784150322044521000",
|
||||||
|
"htlc_address": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2wsh": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2tr": "",
|
||||||
|
"cost_server": "1828",
|
||||||
|
"cost_onchain": "0",
|
||||||
|
"cost_offchain": "0",
|
||||||
|
"last_hop": "",
|
||||||
|
"outgoing_chan_set": [],
|
||||||
|
"label": "",
|
||||||
|
"asset_info": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 17027,
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
"2026-07-15T18:18:42-03:00 STATIC_LOOP_IN PAYMENT_RECEIVED 0.00500000 BTC - P2WSH: bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv (cost: server 1828, onchain 0, offchain 0)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 17036,
|
||||||
|
"kind": "grpc",
|
||||||
|
"data": {
|
||||||
|
"method": "/looprpc.SwapClient/Monitor",
|
||||||
|
"event": "recv",
|
||||||
|
"message_type": "looprpc.SwapStatus",
|
||||||
|
"payload": {
|
||||||
|
"amt": "500000",
|
||||||
|
"id": "bec3777d45337f652d96136e5714ed90a5d4f7cda87b5842110ecc38c9a65826",
|
||||||
|
"id_bytes": "vsN3fUUzf2UtlhNuVxTtkKXU982oe1hCEQ7MOMmmWCY=",
|
||||||
|
"type": "STATIC_LOOP_IN",
|
||||||
|
"state": "INITIATED",
|
||||||
|
"static_loop_in_state": "SUCCEEDED",
|
||||||
|
"failure_reason": "FAILURE_REASON_NONE",
|
||||||
|
"initiation_time": "1784150320647961000",
|
||||||
|
"last_update_time": "1784150322052572000",
|
||||||
|
"htlc_address": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2wsh": "bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv",
|
||||||
|
"htlc_address_p2tr": "",
|
||||||
|
"cost_server": "1828",
|
||||||
|
"cost_onchain": "0",
|
||||||
|
"cost_offchain": "0",
|
||||||
|
"last_hop": "",
|
||||||
|
"outgoing_chan_set": [],
|
||||||
|
"label": "",
|
||||||
|
"asset_info": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 17036,
|
||||||
|
"kind": "stdout",
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
"2026-07-15T18:18:42-03:00 STATIC_LOOP_IN SUCCEEDED 0.00500000 BTC - P2WSH: bcrt1qjsl6tmv2vf3p5wwv28jh6xwettds934k02c3l5w6zyjsyrsd3lfskgdjmv (cost: server 1828, onchain 0, offchain 0)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 25406,
|
||||||
|
"kind": "signal",
|
||||||
|
"data": {
|
||||||
|
"signal": "interrupt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 25407,
|
||||||
|
"kind": "grpc",
|
||||||
|
"data": {
|
||||||
|
"method": "/looprpc.SwapClient/Monitor",
|
||||||
|
"event": "error",
|
||||||
|
"error": "rpc error: code = Canceled desc = context canceled",
|
||||||
|
"status": {
|
||||||
|
"code": 1,
|
||||||
|
"message": "context canceled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 25407,
|
||||||
|
"kind": "stderr",
|
||||||
|
"data": {
|
||||||
|
"lines": [
|
||||||
|
"[loop] recv: rpc error: code = Canceled desc = context canceled\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time_ms": 25407,
|
||||||
|
"kind": "exit",
|
||||||
|
"data": {
|
||||||
|
"run_error": "recv: rpc error: code = Canceled desc = context canceled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue