diff --git a/Makefile b/Makefile index bb458cd..552ce0c 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,11 @@ ifneq ($(workers),) LINT_WORKERS = --concurrency=$(workers) endif -DOCKER_TOOLS = docker run -v $$(pwd):/build loop-tools +DOCKER_TOOLS = docker run \ + --rm \ + -v $(shell bash -c "go env GOCACHE || (mkdir -p /tmp/go-cache; echo /tmp/go-cache)"):/tmp/build/.cache \ + -v $(shell bash -c "go env GOMODCACHE || (mkdir -p /tmp/go-modcache; echo /tmp/go-modcache)"):/tmp/build/.modcache \ + -v $$(pwd):/build loop-tools GREEN := "\\033[0;32m" NC := "\\033[0m" diff --git a/cmd/loop/instantout.go b/cmd/loop/instantout.go index 017828f..3c3a113 100644 --- a/cmd/loop/instantout.go +++ b/cmd/loop/instantout.go @@ -202,3 +202,31 @@ func instantOut(ctx *cli.Context) error { return nil } + +var listInstantOutsCommand = cli.Command{ + Name: "listinstantouts", + Usage: "list all instant out swaps", + Description: ` + List all instant out swaps. + `, + Action: listInstantOuts, +} + +func listInstantOuts(ctx *cli.Context) error { + // First set up the swap client itself. + client, cleanup, err := getClient(ctx) + if err != nil { + return err + } + defer cleanup() + + resp, err := client.ListInstantOuts( + context.Background(), &looprpc.ListInstantOutsRequest{}, + ) + if err != nil { + return err + } + + printRespJSON(resp) + return nil +} diff --git a/cmd/loop/main.go b/cmd/loop/main.go index 44023da..a89e01f 100644 --- a/cmd/loop/main.go +++ b/cmd/loop/main.go @@ -148,7 +148,8 @@ func main() { listSwapsCommand, swapInfoCommand, getLiquidityParamsCommand, setLiquidityRuleCommand, suggestSwapCommand, setParamsCommand, getInfoCommand, abandonSwapCommand, reservationsCommands, - instantOutCommand, staticAddressCommands, + instantOutCommand, listInstantOutsCommand, + staticAddressCommands, } err := app.Run(os.Args) diff --git a/go.mod b/go.mod index 3df3d62..fe6e456 100644 --- a/go.mod +++ b/go.mod @@ -15,9 +15,9 @@ require ( github.com/fortytw2/leaktest v1.3.0 github.com/golang-migrate/migrate/v4 v4.16.1 github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 - github.com/jackc/pgconn v1.14.0 + github.com/jackc/pgconn v1.14.3 github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa - github.com/jackc/pgx/v4 v4.18.1 + github.com/jackc/pgx/v4 v4.18.2 github.com/jessevdk/go-flags v1.4.0 github.com/lib/pq v1.10.7 github.com/lightninglabs/aperture v0.1.21-beta.0.20230705004936-87bb996a4030 @@ -32,12 +32,12 @@ require ( github.com/ory/dockertest/v3 v3.10.0 github.com/stretchr/testify v1.8.4 github.com/urfave/cli v1.22.9 - golang.org/x/net v0.17.0 + golang.org/x/net v0.23.0 google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/macaroon-bakery.v2 v2.1.0 gopkg.in/macaroon.v2 v2.1.0 - modernc.org/sqlite v1.20.3 + modernc.org/sqlite v1.29.5 ) require ( @@ -68,11 +68,11 @@ require ( github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect github.com/decred/dcrd/lru v1.0.0 // indirect github.com/docker/cli v20.10.17+incompatible // indirect - github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dsnet/compress v0.0.1 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/fergusstrange/embedded-postgres v1.10.0 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-logr/logr v1.3.0 // indirect @@ -90,11 +90,12 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.2 // indirect + github.com/jackc/pgproto3/v2 v2.3.3 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgtype v1.14.0 // indirect github.com/jackpal/gateway v1.0.5 // indirect @@ -103,7 +104,6 @@ require ( github.com/jrick/logrotate v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/juju/loggo v0.0.0-20210728185423-eebad3a902c4 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kkdai/bstream v1.0.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/klauspost/pgzip v1.2.5 // indirect @@ -123,6 +123,7 @@ require ( github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect github.com/nwaples/rardecode v1.1.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect @@ -134,7 +135,7 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.30.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/fastuuid v1.2.0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect @@ -172,15 +173,15 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.17.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/tools v0.17.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect @@ -188,15 +189,12 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/uint128 v1.2.0 // indirect - modernc.org/cc/v3 v3.40.0 // indirect - modernc.org/ccgo/v3 v3.16.13 // indirect - modernc.org/libc v1.22.2 // indirect - modernc.org/mathutil v1.5.0 // indirect - modernc.org/memory v1.4.0 // indirect - modernc.org/opt v0.1.3 // indirect - modernc.org/strutil v1.1.3 // indirect - modernc.org/token v1.0.1 // indirect + modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect + modernc.org/libc v1.41.0 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.7.2 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect sigs.k8s.io/yaml v1.2.0 // indirect ) diff --git a/go.sum b/go.sum index 08e86d9..3f0d182 100644 --- a/go.sum +++ b/go.sum @@ -759,8 +759,8 @@ github.com/dhui/dktest v0.3.16 h1:i6gq2YQEtcrjKbeJpBkWjE8MmLZPYllcjOFbTZuPDnw= github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= +github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -769,8 +769,9 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3 github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -965,6 +966,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -981,8 +984,8 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= -github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw= github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= @@ -1000,8 +1003,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= -github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= @@ -1015,12 +1018,11 @@ github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08 github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= -github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= +github.com/jackc/pgx/v4 v4.18.2 h1:xVpYkNR5pk5bMCZGfClbO962UIqVABcAGt7ha1s/FeU= +github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v0.0.0-20170405195558-28a68d0c24ad h1:heFfj7z0pGsNCekUlsFhO2jstxO4b5iQ665LjwM5mDc= @@ -1055,7 +1057,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -1144,7 +1145,7 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -1168,6 +1169,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nwaples/rardecode v1.1.2 h1:Cj0yZY6T1Zx1R7AhTbyGSALm44/Mmq+BAPc4B/p/d3M= github.com/nwaples/rardecode v1.1.2/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= @@ -1230,8 +1233,9 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1401,9 +1405,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1419,8 +1422,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo= -golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w= +golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1463,8 +1466,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1531,8 +1534,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1579,8 +1582,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1679,8 +1682,8 @@ golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1690,8 +1693,8 @@ golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1785,8 +1788,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2097,24 +2100,20 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw= -modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= -modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= -modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= -modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= @@ -2123,33 +2122,32 @@ modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= -modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0= -modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= +modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= +modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk= -modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= -modernc.org/sqlite v1.20.3 h1:SqGJMMxjj1PHusLxdYxeQSodg7Jxn9WWkaAQjKrntZs= -modernc.org/sqlite v1.20.3/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A= +modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE= +modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= -modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= -modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= -modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= -modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/instantout/actions.go b/instantout/actions.go index 977cd04..71a411f 100644 --- a/instantout/actions.go +++ b/instantout/actions.go @@ -185,13 +185,13 @@ func (f *FSM) InitInstantOutAction(eventCtx fsm.EventContext) fsm.EventType { protocolVersion: ProtocolVersionFullReservation, initiationHeight: initCtx.initationHeight, outgoingChanSet: initCtx.outgoingChanSet, - cltvExpiry: initCtx.cltvExpiry, + CltvExpiry: initCtx.cltvExpiry, clientPubkey: keyRes.PubKey, serverPubkey: serverPubkey, - value: btcutil.Amount(reservationAmt), + Value: btcutil.Amount(reservationAmt), htlcFeeRate: feeRate, swapInvoice: instantOutResponse.SwapInvoice, - reservations: reservations, + Reservations: reservations, keyLocator: keyRes.KeyLocator, sweepAddress: sweepAddress, } @@ -211,7 +211,7 @@ func (f *FSM) InitInstantOutAction(eventCtx fsm.EventContext) fsm.EventType { func (f *FSM) PollPaymentAcceptedAction(_ fsm.EventContext) fsm.EventType { // Now that we're doing the swap, we first lock the reservations // so that they can't be used for other swaps. - for _, reservation := range f.InstantOut.reservations { + for _, reservation := range f.InstantOut.Reservations { err := f.cfg.ReservationManager.LockReservation( f.ctx, reservation.ID, ) @@ -227,7 +227,7 @@ func (f *FSM) PollPaymentAcceptedAction(_ fsm.EventContext) fsm.EventType { Invoice: f.InstantOut.swapInvoice, Timeout: defaultSendpaymentTimeout, MaxParts: defaultMaxParts, - MaxFee: getMaxRoutingFee(f.InstantOut.value), + MaxFee: getMaxRoutingFee(f.InstantOut.Value), }, ) if err != nil { @@ -301,7 +301,7 @@ func (f *FSM) BuildHTLCAction(eventCtx fsm.EventContext) fsm.EventType { return f.handleErrorAndUnlockReservations(err) } - if len(htlcInitRes.HtlcServerNonces) != len(f.InstantOut.reservations) { + if len(htlcInitRes.HtlcServerNonces) != len(f.InstantOut.Reservations) { return f.handleErrorAndUnlockReservations( errors.New("invalid number of server nonces"), ) @@ -435,8 +435,8 @@ func (f *FSM) PushPreimageAction(eventCtx fsm.EventContext) fsm.EventType { return OnErrorPublishHtlc } - f.InstantOut.finalizedSweeplessSweepTx = sweepTx - txHash := f.InstantOut.finalizedSweeplessSweepTx.TxHash() + f.InstantOut.FinalizedSweeplessSweepTx = sweepTx + txHash := f.InstantOut.FinalizedSweeplessSweepTx.TxHash() f.InstantOut.SweepTxHash = &txHash @@ -598,7 +598,7 @@ func (f *FSM) handleErrorAndUnlockReservations(err error) fsm.EventType { defer cancel() // Unlock the reservations. - for _, reservation := range f.InstantOut.reservations { + for _, reservation := range f.InstantOut.Reservations { err := f.cfg.ReservationManager.UnlockReservation( ctx, reservation.ID, ) diff --git a/instantout/instantout.go b/instantout/instantout.go index 162fef2..5fc1923 100644 --- a/instantout/instantout.go +++ b/instantout/instantout.go @@ -35,16 +35,16 @@ type InstantOut struct { // State is the current state of the swap. State fsm.StateType - // cltvExpiry is the expiry of the swap. - cltvExpiry int32 + // CltvExpiry is the expiry of the swap. + CltvExpiry int32 // outgoingChanSet optionally specifies the short channel ids of the // channels that may be used to loop out. outgoingChanSet loopdb.ChannelSet - // reservations are the reservations that are used in as inputs for the + // Reservations are the Reservations that are used in as inputs for the // instant out swap. - reservations []*reservation.Reservation + Reservations []*reservation.Reservation // protocolVersion is the version of the protocol that is used for the // swap. @@ -53,8 +53,8 @@ type InstantOut struct { // initiationHeight is the height at which the swap was initiated. initiationHeight int32 - // value is the amount that is swapped. - value btcutil.Amount + // Value is the amount that is swapped. + Value btcutil.Amount // keyLocator is the key locator that is used for the swap. keyLocator keychain.KeyLocator @@ -81,9 +81,9 @@ type InstantOut struct { // SweepTxHash is the hash of the sweep transaction. SweepTxHash *chainhash.Hash - // finalizedSweeplessSweepTx is the transaction that is used to sweep + // FinalizedSweeplessSweepTx is the transaction that is used to sweep // the funds in the cooperative path. - finalizedSweeplessSweepTx *wire.MsgTx + FinalizedSweeplessSweepTx *wire.MsgTx // sweepConfirmationHeight is the height at which the sweep // transaction was confirmed. @@ -93,7 +93,7 @@ type InstantOut struct { // getHtlc returns the swap.htlc for the instant out. func (i *InstantOut) getHtlc(chainParams *chaincfg.Params) (*swap.Htlc, error) { return swap.NewHtlcV2( - i.cltvExpiry, pubkeyTo33ByteSlice(i.serverPubkey), + i.CltvExpiry, pubkeyTo33ByteSlice(i.serverPubkey), pubkeyTo33ByteSlice(i.clientPubkey), i.SwapHash, chainParams, ) } @@ -104,11 +104,11 @@ func (i *InstantOut) createMusig2Session(ctx context.Context, [][]byte, error) { // Create the htlc musig2 context. - musig2Sessions := make([]*input.MuSig2SessionInfo, len(i.reservations)) - clientNonces := make([][]byte, len(i.reservations)) + musig2Sessions := make([]*input.MuSig2SessionInfo, len(i.Reservations)) + clientNonces := make([][]byte, len(i.Reservations)) // Create the sessions and nonces from the reservations. - for idx, reservation := range i.reservations { + for idx, reservation := range i.Reservations { session, err := reservation.Musig2CreateSession(ctx, signer) if err != nil { return nil, nil, err @@ -123,12 +123,12 @@ func (i *InstantOut) createMusig2Session(ctx context.Context, // getInputReservation returns the input reservation for the instant out. func (i *InstantOut) getInputReservations() (InputReservations, error) { - if len(i.reservations) == 0 { + if len(i.Reservations) == 0 { return nil, errors.New("no reservations") } - inputs := make(InputReservations, len(i.reservations)) - for idx, reservation := range i.reservations { + inputs := make(InputReservations, len(i.Reservations)) + for idx, reservation := range i.Reservations { pkScript, err := reservation.GetPkScript() if err != nil { return nil, err @@ -170,7 +170,7 @@ func (i *InstantOut) createHtlcTransaction(network *chaincfg.Params) ( // Estimate the fee weight := htlcWeight(len(inputReservations)) fee := i.htlcFeeRate.FeeForWeight(weight) - if fee > i.value/5 { + if fee > i.Value/5 { return nil, errors.New("fee is higher than 20% of " + "sweep value") } @@ -182,7 +182,7 @@ func (i *InstantOut) createHtlcTransaction(network *chaincfg.Params) ( // Create the sweep output sweepOutput := &wire.TxOut{ - Value: int64(i.value) - int64(fee), + Value: int64(i.Value) - int64(fee), PkScript: htlc.PkScript, } @@ -214,7 +214,7 @@ func (i *InstantOut) createSweeplessSweepTx(feerate chainfee.SatPerKWeight) ( // Estimate the fee weight := sweeplessSweepWeight(len(inputReservations)) fee := feerate.FeeForWeight(weight) - if fee > i.value/5 { + if fee > i.Value/5 { return nil, errors.New("fee is higher than 20% of " + "sweep value") } @@ -226,7 +226,7 @@ func (i *InstantOut) createSweeplessSweepTx(feerate chainfee.SatPerKWeight) ( // Create the sweep output sweepOutput := &wire.TxOut{ - Value: int64(i.value) - int64(fee), + Value: int64(i.Value) - int64(fee), PkScript: pkscript, } diff --git a/instantout/manager.go b/instantout/manager.go index a9c4563..5cb1386 100644 --- a/instantout/manager.go +++ b/instantout/manager.go @@ -258,3 +258,8 @@ func (m *Manager) GetInstantOutQuote(ctx context.Context, OnChainFee: chainFee, }, nil } + +// ListInstantOuts returns all instant outs from the database. +func (m *Manager) ListInstantOuts(ctx context.Context) ([]*InstantOut, error) { + return m.cfg.Store.ListInstantLoopOuts(ctx) +} diff --git a/instantout/store.go b/instantout/store.go index 39b16d3..6d622b0 100644 --- a/instantout/store.go +++ b/instantout/store.go @@ -94,8 +94,8 @@ func (s *SQLStore) CreateInstantLoopOut(ctx context.Context, SwapHash: instantOut.SwapHash[:], Preimage: instantOut.swapPreimage[:], InitiationTime: s.clock.Now(), - AmountRequested: int64(instantOut.value), - CltvExpiry: instantOut.cltvExpiry, + AmountRequested: int64(instantOut.Value), + CltvExpiry: instantOut.CltvExpiry, MaxMinerFee: 0, MaxSwapFee: 0, InitiationHeight: instantOut.initiationHeight, @@ -114,7 +114,7 @@ func (s *SQLStore) CreateInstantLoopOut(ctx context.Context, } reservationIdByteSlice := reservationIdsToByteSlice( - instantOut.reservations, + instantOut.Reservations, ) instantOutArgs := sqlc.InsertInstantOutParams{ SwapHash: instantOut.SwapHash[:], @@ -172,9 +172,9 @@ func (s *SQLStore) UpdateInstantLoopOut(ctx context.Context, } var finalSweeplessSweepTx []byte - if instantOut.finalizedSweeplessSweepTx != nil { + if instantOut.FinalizedSweeplessSweepTx != nil { var buffer bytes.Buffer - err := instantOut.finalizedSweeplessSweepTx.Serialize( + err := instantOut.FinalizedSweeplessSweepTx.Serialize( &buffer, ) if err != nil { @@ -355,12 +355,12 @@ func (s *SQLStore) sqlInstantOutToInstantOut(ctx context.Context, instantOut := &InstantOut{ SwapHash: swapHash, swapPreimage: swapPreImage, - cltvExpiry: row.CltvExpiry, + CltvExpiry: row.CltvExpiry, outgoingChanSet: outgoingChanSet, - reservations: reservations, + Reservations: reservations, protocolVersion: ProtocolVersion(row.ProtocolVersion), initiationHeight: row.InitiationHeight, - value: btcutil.Amount(row.AmountRequested), + Value: btcutil.Amount(row.AmountRequested), keyLocator: keychain.KeyLocator{ Family: keychain.KeyFamily(row.ClientKeyFamily), Index: uint32(row.ClientKeyIndex), @@ -372,7 +372,7 @@ func (s *SQLStore) sqlInstantOutToInstantOut(ctx context.Context, sweepAddress: sweepAddress, finalizedHtlcTx: finalizedHtlcTx, SweepTxHash: sweepTxHash, - finalizedSweeplessSweepTx: finalizedSweepLessSweepTx, + FinalizedSweeplessSweepTx: finalizedSweepLessSweepTx, sweepConfirmationHeight: uint32(deserializeNullInt32( row.SweepConfirmationHeight, )), diff --git a/loopd/perms/perms.go b/loopd/perms/perms.go index 92c29ff..67d39f9 100644 --- a/loopd/perms/perms.go +++ b/loopd/perms/perms.go @@ -122,4 +122,8 @@ var RequiredPermissions = map[string][]bakery.Op{ Entity: "swap", Action: "read", }}, + "/looprpc.SwapClient/ListInstantOuts": {{ + Entity: "swap", + Action: "read", + }}, } diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index 40aeb58..f42e8d5 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -1231,6 +1231,47 @@ func (s *swapClientServer) InstantOutQuote(ctx context.Context, }, nil } +// ListInstantOuts returns a list of all currently known instant out swaps and +// their current status. +func (s *swapClientServer) ListInstantOuts(ctx context.Context, + _ *clientrpc.ListInstantOutsRequest) ( + *clientrpc.ListInstantOutsResponse, error) { + + instantOuts, err := s.instantOutManager.ListInstantOuts(ctx) + if err != nil { + return nil, err + } + + rpcSwaps := make([]*clientrpc.InstantOut, 0, len(instantOuts)) + for _, instantOut := range instantOuts { + rpcSwaps = append(rpcSwaps, rpcInstantOut(instantOut)) + } + + return &clientrpc.ListInstantOutsResponse{ + Swaps: rpcSwaps, + }, nil +} + +func rpcInstantOut(instantOut *instantout.InstantOut) *clientrpc.InstantOut { + var sweepTxId string + if instantOut.SweepTxHash != nil { + sweepTxId = instantOut.SweepTxHash.String() + } + + reservations := make([][]byte, len(instantOut.Reservations)) + for i, res := range instantOut.Reservations { + reservations[i] = res.ID[:] + } + + return &clientrpc.InstantOut{ + SwapHash: instantOut.SwapHash[:], + State: string(instantOut.State), + Amount: uint64(instantOut.Value), + SweepTxId: sweepTxId, + ReservationIds: reservations, + } +} + func rpcAutoloopReason(reason liquidity.Reason) (clientrpc.AutoReason, error) { switch reason { case liquidity.ReasonNone: diff --git a/loopdb/sqlc/batch.sql.go b/loopdb/sqlc/batch.sql.go index 9469292..6f4aaf9 100644 --- a/loopdb/sqlc/batch.sql.go +++ b/loopdb/sqlc/batch.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 // source: batch.sql package sqlc @@ -144,6 +144,54 @@ func (q *Queries) GetBatchSweeps(ctx context.Context, batchID int32) ([]GetBatch return items, nil } +const getBatchSweptAmount = `-- name: GetBatchSweptAmount :one +SELECT + SUM(amt) AS total +FROM + sweeps +WHERE + batch_id = $1 +AND + completed = TRUE +` + +func (q *Queries) GetBatchSweptAmount(ctx context.Context, batchID int32) (int64, error) { + row := q.db.QueryRowContext(ctx, getBatchSweptAmount, batchID) + var total int64 + err := row.Scan(&total) + return total, err +} + +const getParentBatch = `-- name: GetParentBatch :one +SELECT + sweep_batches.id, sweep_batches.confirmed, sweep_batches.batch_tx_id, sweep_batches.batch_pk_script, sweep_batches.last_rbf_height, sweep_batches.last_rbf_sat_per_kw, sweep_batches.max_timeout_distance +FROM + sweep_batches +JOIN + sweeps ON sweep_batches.id = sweeps.batch_id +WHERE + sweeps.swap_hash = $1 +AND + sweeps.completed = TRUE +AND + sweep_batches.confirmed = TRUE +` + +func (q *Queries) GetParentBatch(ctx context.Context, swapHash []byte) (SweepBatch, error) { + row := q.db.QueryRowContext(ctx, getParentBatch, swapHash) + var i SweepBatch + err := row.Scan( + &i.ID, + &i.Confirmed, + &i.BatchTxID, + &i.BatchPkScript, + &i.LastRbfHeight, + &i.LastRbfSatPerKw, + &i.MaxTimeoutDistance, + ) + return i, err +} + const getSweepStatus = `-- name: GetSweepStatus :one SELECT COALESCE(s.completed, f.false_value) AS completed diff --git a/loopdb/sqlc/db.go b/loopdb/sqlc/db.go index 2ebc823..8ed64d1 100644 --- a/loopdb/sqlc/db.go +++ b/loopdb/sqlc/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 package sqlc diff --git a/loopdb/sqlc/instantout.sql.go b/loopdb/sqlc/instantout.sql.go index 88ce11e..73fb0ac 100644 --- a/loopdb/sqlc/instantout.sql.go +++ b/loopdb/sqlc/instantout.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 // source: instantout.sql package sqlc diff --git a/loopdb/sqlc/liquidity_params.sql.go b/loopdb/sqlc/liquidity_params.sql.go index dbb2df4..ac36bbe 100644 --- a/loopdb/sqlc/liquidity_params.sql.go +++ b/loopdb/sqlc/liquidity_params.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 // source: liquidity_params.sql package sqlc diff --git a/loopdb/sqlc/models.go b/loopdb/sqlc/models.go index d1cb5a7..78d4828 100644 --- a/loopdb/sqlc/models.go +++ b/loopdb/sqlc/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 package sqlc diff --git a/loopdb/sqlc/querier.go b/loopdb/sqlc/querier.go index bfa6183..20f502e 100644 --- a/loopdb/sqlc/querier.go +++ b/loopdb/sqlc/querier.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 package sqlc @@ -15,6 +15,7 @@ type Querier interface { CreateStaticAddress(ctx context.Context, arg CreateStaticAddressParams) error FetchLiquidityParams(ctx context.Context) ([]byte, error) GetBatchSweeps(ctx context.Context, batchID int32) ([]GetBatchSweepsRow, error) + GetBatchSweptAmount(ctx context.Context, batchID int32) (int64, error) GetInstantOutSwap(ctx context.Context, swapHash []byte) (GetInstantOutSwapRow, error) GetInstantOutSwapUpdates(ctx context.Context, swapHash []byte) ([]InstantoutUpdate, error) GetInstantOutSwaps(ctx context.Context) ([]GetInstantOutSwapsRow, error) @@ -22,6 +23,7 @@ type Querier interface { GetLoopInSwaps(ctx context.Context) ([]GetLoopInSwapsRow, error) GetLoopOutSwap(ctx context.Context, swapHash []byte) (GetLoopOutSwapRow, error) GetLoopOutSwaps(ctx context.Context) ([]GetLoopOutSwapsRow, error) + GetParentBatch(ctx context.Context, swapHash []byte) (SweepBatch, error) GetReservation(ctx context.Context, reservationID []byte) (Reservation, error) GetReservationUpdates(ctx context.Context, reservationID []byte) ([]ReservationUpdate, error) GetReservations(ctx context.Context) ([]Reservation, error) diff --git a/loopdb/sqlc/queries/batch.sql b/loopdb/sqlc/queries/batch.sql index 336ccf1..a9793f9 100644 --- a/loopdb/sqlc/queries/batch.sql +++ b/loopdb/sqlc/queries/batch.sql @@ -62,6 +62,29 @@ INSERT INTO sweeps ( amt = $5, completed = $6; +-- name: GetParentBatch :one +SELECT + sweep_batches.* +FROM + sweep_batches +JOIN + sweeps ON sweep_batches.id = sweeps.batch_id +WHERE + sweeps.swap_hash = $1 +AND + sweeps.completed = TRUE +AND + sweep_batches.confirmed = TRUE; + +-- name: GetBatchSweptAmount :one +SELECT + SUM(amt) AS total +FROM + sweeps +WHERE + batch_id = $1 +AND + completed = TRUE; -- name: GetBatchSweeps :many SELECT diff --git a/loopdb/sqlc/reservations.sql.go b/loopdb/sqlc/reservations.sql.go index 863371b..b26ccbc 100644 --- a/loopdb/sqlc/reservations.sql.go +++ b/loopdb/sqlc/reservations.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 // source: reservations.sql package sqlc diff --git a/loopdb/sqlc/swaps.sql.go b/loopdb/sqlc/swaps.sql.go index 8249942..a440308 100644 --- a/loopdb/sqlc/swaps.sql.go +++ b/loopdb/sqlc/swaps.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.17.2 +// sqlc v1.25.0 // source: swaps.sql package sqlc diff --git a/loopdb/sqlite.go b/loopdb/sqlite.go index b0ecb27..ae2fa41 100644 --- a/loopdb/sqlite.go +++ b/loopdb/sqlite.go @@ -68,6 +68,21 @@ func NewSqliteStore(cfg *SqliteConfig, network *chaincfg.Params) (*SqliteSwapSto name: "busy_timeout", value: "5000", }, + { + // With the WAL mode, this ensures that we also do an + // extra WAL sync after each transaction. The normal + // sync mode skips this and gives better performance, + // but risks durability. + name: "synchronous", + value: "full", + }, + { + // This is used to ensure proper durability for users + // running on Mac OS. It uses the correct fsync system + // call to ensure items are fully flushed to disk. + name: "fullfsync", + value: "true", + }, } sqliteOptions := make(url.Values) for _, option := range pragmaOptions { diff --git a/loopin.go b/loopin.go index 5aecb67..b92a3cf 100644 --- a/loopin.go +++ b/loopin.go @@ -919,9 +919,7 @@ func (s *loopInSwap) waitForSwapComplete(ctx context.Context, s.log.Infof("Htlc spend by tx: %v", spendDetails.SpenderTxHash) - err := s.processHtlcSpend( - ctx, spendDetails, htlcValue, sweepFee, - ) + err := s.processHtlcSpend(ctx, spendDetails, sweepFee) if err != nil { return err } @@ -959,8 +957,6 @@ func (s *loopInSwap) waitForSwapComplete(ctx context.Context, switch update.State { // Swap invoice was paid, so update server cost balance. case invpkg.ContractSettled: - s.cost.Server -= update.AmtPaid - // If invoice settlement and htlc spend happen // in the expected order, move the swap to an // intermediate state that indicates that the @@ -977,6 +973,8 @@ func (s *loopInSwap) waitForSwapComplete(ctx context.Context, invoiceFinalized = true htlcKeyRevealed = s.tryPushHtlcKey(ctx) + s.cost.Server = s.AmountRequested - + update.AmtPaid // Canceled invoice has no effect on server cost // balance. @@ -1023,8 +1021,7 @@ func (s *loopInSwap) tryPushHtlcKey(ctx context.Context) bool { } func (s *loopInSwap) processHtlcSpend(ctx context.Context, - spend *chainntnfs.SpendDetail, htlcValue, - sweepFee btcutil.Amount) error { + spend *chainntnfs.SpendDetail, sweepFee btcutil.Amount) error { // Determine the htlc input of the spending tx and inspect the witness // to find out whether a success or a timeout tx spent the htlc. @@ -1032,10 +1029,6 @@ func (s *loopInSwap) processHtlcSpend(ctx context.Context, if s.htlc.IsSuccessWitness(htlcInput.Witness) { s.setState(loopdb.StateSuccess) - - // Server swept the htlc. The htlc value can be added to the - // server cost balance. - s.cost.Server += htlcValue } else { // We needed another on chain tx to sweep the timeout clause, // which we now include in our costs. diff --git a/loopout.go b/loopout.go index 8035b9d..bf76274 100644 --- a/loopout.go +++ b/loopout.go @@ -306,7 +306,11 @@ func (s *loopOutSwap) sendUpdate(ctx context.Context) error { info := s.swapInfo() s.log.Infof("Loop out swap state: %v", info.State) - info.HtlcAddressP2WSH = s.htlc.Address + if s.htlc.OutputType == swap.HtlcP2WSH { + info.HtlcAddressP2WSH = s.htlc.Address + } else { + info.HtlcAddressP2TR = s.htlc.Address + } // In order to avoid potentially dangerous ownership sharing // we copy the outgoing channel set. @@ -452,7 +456,8 @@ func (s *loopOutSwap) handlePaymentResult(result paymentResult) error { return nil case result.status.State == lnrpc.Payment_SUCCEEDED: - s.cost.Server += result.status.Value.ToSatoshis() + s.cost.Server += result.status.Value.ToSatoshis() - + s.AmountRequested s.cost.Offchain += result.status.Fee.ToSatoshis() return nil @@ -514,7 +519,7 @@ func (s *loopOutSwap) executeSwap(globalCtx context.Context) error { } // Try to spend htlc and continue (rbf) until a spend has confirmed. - spendTx, err := s.waitForHtlcSpendConfirmedV2( + spend, err := s.waitForHtlcSpendConfirmedV2( globalCtx, *htlcOutpoint, htlcValue, ) if err != nil { @@ -523,7 +528,7 @@ func (s *loopOutSwap) executeSwap(globalCtx context.Context) error { // If spend details are nil, we resolved the swap without waiting for // its spend, so we can exit. - if spendTx == nil { + if spend == nil { return nil } @@ -531,7 +536,7 @@ func (s *loopOutSwap) executeSwap(globalCtx context.Context) error { // don't just try to match with the hash of our sweep tx, because it // may be swept by a different (fee) sweep tx from a previous run. htlcInput, err := swap.GetTxInputByOutpoint( - spendTx, htlcOutpoint, + spend.Tx, htlcOutpoint, ) if err != nil { return err @@ -539,11 +544,7 @@ func (s *loopOutSwap) executeSwap(globalCtx context.Context) error { sweepSuccessful := s.htlc.IsSuccessWitness(htlcInput.Witness) if sweepSuccessful { - s.cost.Server -= htlcValue - - s.cost.Onchain = htlcValue - - btcutil.Amount(spendTx.TxOut[0].Value) - + s.cost.Onchain = spend.OnChainFeePortion s.state = loopdb.StateSuccess } else { s.state = loopdb.StateFailSweepTimeout @@ -598,11 +599,12 @@ func (s *loopOutSwap) payInvoices(ctx context.Context) { ) // Pay the prepay invoice. Won't use the routing plugin here as the - // prepay is trivially small and shouldn't normally need any help. + // prepay is trivially small and shouldn't normally need any help. We + // are sending it over the same channel as the loop out payment. s.log.Infof("Sending prepayment %v", s.PrepayInvoice) s.prePaymentChan = s.payInvoice( ctx, s.PrepayInvoice, s.MaxPrepayRoutingFee, - nil, RoutingPluginNone, false, + s.LoopOutContract.OutgoingChanSet, RoutingPluginNone, false, ) } @@ -1005,9 +1007,9 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) ( // sweep or a server revocation tx. func (s *loopOutSwap) waitForHtlcSpendConfirmedV2(globalCtx context.Context, htlcOutpoint wire.OutPoint, htlcValue btcutil.Amount) ( - *wire.MsgTx, error) { + *sweepbatcher.SpendDetail, error) { - spendChan := make(chan *wire.MsgTx) + spendChan := make(chan *sweepbatcher.SpendDetail) spendErrChan := make(chan error, 1) quitChan := make(chan bool, 1) @@ -1054,10 +1056,10 @@ func (s *loopOutSwap) waitForHtlcSpendConfirmedV2(globalCtx context.Context, for { select { // Htlc spend, break loop. - case spendTx := <-spendChan: - s.log.Infof("Htlc spend by tx: %v", spendTx.TxHash()) + case spend := <-spendChan: + s.log.Infof("Htlc spend by tx: %v", spend.Tx.TxHash()) - return spendTx, nil + return spend, nil // Spend notification error. case err := <-spendErrChan: diff --git a/looprpc/client.pb.go b/looprpc/client.pb.go index 3893f6a..d479ebe 100644 --- a/looprpc/client.pb.go +++ b/looprpc/client.pb.go @@ -3867,6 +3867,182 @@ func (x *InstantOutQuoteResponse) GetSweepFeeSat() int64 { return 0 } +type ListInstantOutsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListInstantOutsRequest) Reset() { + *x = ListInstantOutsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstantOutsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstantOutsRequest) ProtoMessage() {} + +func (x *ListInstantOutsRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstantOutsRequest.ProtoReflect.Descriptor instead. +func (*ListInstantOutsRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{40} +} + +type ListInstantOutsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // + //The list of all currently known instant out swaps and their status. + Swaps []*InstantOut `protobuf:"bytes,1,rep,name=swaps,proto3" json:"swaps,omitempty"` +} + +func (x *ListInstantOutsResponse) Reset() { + *x = ListInstantOutsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstantOutsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstantOutsResponse) ProtoMessage() {} + +func (x *ListInstantOutsResponse) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstantOutsResponse.ProtoReflect.Descriptor instead. +func (*ListInstantOutsResponse) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{41} +} + +func (x *ListInstantOutsResponse) GetSwaps() []*InstantOut { + if x != nil { + return x.Swaps + } + return nil +} + +type InstantOut struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // + //The swap hash that identifies this swap. + SwapHash []byte `protobuf:"bytes,1,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` + // + //The state the swap is in. + State string `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` + // + //The amount of the swap. + Amount uint64 `protobuf:"varint,3,opt,name=amount,proto3" json:"amount,omitempty"` + // + //The used reservations for the swap. + ReservationIds [][]byte `protobuf:"bytes,4,rep,name=reservation_ids,json=reservationIds,proto3" json:"reservation_ids,omitempty"` + // + //The sweep transaction id of the swap. + SweepTxId string `protobuf:"bytes,5,opt,name=sweep_tx_id,json=sweepTxId,proto3" json:"sweep_tx_id,omitempty"` +} + +func (x *InstantOut) Reset() { + *x = InstantOut{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InstantOut) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstantOut) ProtoMessage() {} + +func (x *InstantOut) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InstantOut.ProtoReflect.Descriptor instead. +func (*InstantOut) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{42} +} + +func (x *InstantOut) GetSwapHash() []byte { + if x != nil { + return x.SwapHash + } + return nil +} + +func (x *InstantOut) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *InstantOut) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +func (x *InstantOut) GetReservationIds() [][]byte { + if x != nil { + return x.ReservationIds + } + return nil +} + +func (x *InstantOut) GetSweepTxId() string { + if x != nil { + return x.SweepTxId + } + return "" +} + type NewAddressRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3880,7 +4056,7 @@ type NewAddressRequest struct { func (x *NewAddressRequest) Reset() { *x = NewAddressRequest{} if protoimpl.UnsafeEnabled { - mi := &file_client_proto_msgTypes[40] + mi := &file_client_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3893,7 +4069,7 @@ func (x *NewAddressRequest) String() string { func (*NewAddressRequest) ProtoMessage() {} func (x *NewAddressRequest) ProtoReflect() protoreflect.Message { - mi := &file_client_proto_msgTypes[40] + mi := &file_client_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3906,7 +4082,7 @@ func (x *NewAddressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewAddressRequest.ProtoReflect.Descriptor instead. func (*NewAddressRequest) Descriptor() ([]byte, []int) { - return file_client_proto_rawDescGZIP(), []int{40} + return file_client_proto_rawDescGZIP(), []int{43} } func (x *NewAddressRequest) GetClientKey() []byte { @@ -3932,7 +4108,7 @@ type NewAddressResponse struct { func (x *NewAddressResponse) Reset() { *x = NewAddressResponse{} if protoimpl.UnsafeEnabled { - mi := &file_client_proto_msgTypes[41] + mi := &file_client_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3945,7 +4121,7 @@ func (x *NewAddressResponse) String() string { func (*NewAddressResponse) ProtoMessage() {} func (x *NewAddressResponse) ProtoReflect() protoreflect.Message { - mi := &file_client_proto_msgTypes[41] + mi := &file_client_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3958,7 +4134,7 @@ func (x *NewAddressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use NewAddressResponse.ProtoReflect.Descriptor instead. func (*NewAddressResponse) Descriptor() ([]byte, []int) { - return file_client_proto_rawDescGZIP(), []int{41} + return file_client_proto_rawDescGZIP(), []int{44} } func (x *NewAddressResponse) GetAddress() string { @@ -3992,7 +4168,7 @@ type ListUnspentRequest struct { func (x *ListUnspentRequest) Reset() { *x = ListUnspentRequest{} if protoimpl.UnsafeEnabled { - mi := &file_client_proto_msgTypes[42] + mi := &file_client_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4005,7 +4181,7 @@ func (x *ListUnspentRequest) String() string { func (*ListUnspentRequest) ProtoMessage() {} func (x *ListUnspentRequest) ProtoReflect() protoreflect.Message { - mi := &file_client_proto_msgTypes[42] + mi := &file_client_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4018,7 +4194,7 @@ func (x *ListUnspentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUnspentRequest.ProtoReflect.Descriptor instead. func (*ListUnspentRequest) Descriptor() ([]byte, []int) { - return file_client_proto_rawDescGZIP(), []int{42} + return file_client_proto_rawDescGZIP(), []int{45} } func (x *ListUnspentRequest) GetMinConfs() int32 { @@ -4048,7 +4224,7 @@ type ListUnspentResponse struct { func (x *ListUnspentResponse) Reset() { *x = ListUnspentResponse{} if protoimpl.UnsafeEnabled { - mi := &file_client_proto_msgTypes[43] + mi := &file_client_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4061,7 +4237,7 @@ func (x *ListUnspentResponse) String() string { func (*ListUnspentResponse) ProtoMessage() {} func (x *ListUnspentResponse) ProtoReflect() protoreflect.Message { - mi := &file_client_proto_msgTypes[43] + mi := &file_client_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4074,7 +4250,7 @@ func (x *ListUnspentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUnspentResponse.ProtoReflect.Descriptor instead. func (*ListUnspentResponse) Descriptor() ([]byte, []int) { - return file_client_proto_rawDescGZIP(), []int{43} + return file_client_proto_rawDescGZIP(), []int{46} } func (x *ListUnspentResponse) GetUtxos() []*Utxo { @@ -4106,7 +4282,7 @@ type Utxo struct { func (x *Utxo) Reset() { *x = Utxo{} if protoimpl.UnsafeEnabled { - mi := &file_client_proto_msgTypes[44] + mi := &file_client_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4119,7 +4295,7 @@ func (x *Utxo) String() string { func (*Utxo) ProtoMessage() {} func (x *Utxo) ProtoReflect() protoreflect.Message { - mi := &file_client_proto_msgTypes[44] + mi := &file_client_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4132,7 +4308,7 @@ func (x *Utxo) ProtoReflect() protoreflect.Message { // Deprecated: Use Utxo.ProtoReflect.Descriptor instead. func (*Utxo) Descriptor() ([]byte, []int) { - return file_client_proto_rawDescGZIP(), []int{44} + return file_client_proto_rawDescGZIP(), []int{47} } func (x *Utxo) GetStaticAddress() string { @@ -4629,196 +4805,218 @@ var file_client_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x77, 0x65, 0x65, - 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x22, 0x32, 0x0a, 0x11, 0x4e, 0x65, 0x77, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x22, 0x46, 0x0a, 0x12, 0x4e, - 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x79, 0x22, 0x4e, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x69, - 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, - 0x6e, 0x66, 0x73, 0x22, 0x3a, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x75, 0x74, - 0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x55, 0x74, 0x78, 0x6f, 0x52, 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x22, - 0x8e, 0x01, 0x0a, 0x04, 0x55, 0x74, 0x78, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2a, 0x3b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x18, 0x0a, 0x14, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x41, 0x50, - 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x2a, 0x25, 0x0a, - 0x08, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x4f, 0x4f, - 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, - 0x49, 0x4e, 0x10, 0x01, 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x56, - 0x45, 0x41, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x54, 0x4c, 0x43, 0x5f, - 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, - 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, - 0x45, 0x44, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, - 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xeb, 0x02, 0x0a, 0x0d, 0x46, 0x61, - 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x46, - 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, - 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, - 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x02, 0x12, 0x20, 0x0a, - 0x1c, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x03, 0x12, - 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, - 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x56, - 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, - 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x4f, 0x52, 0x41, - 0x52, 0x59, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, - 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, - 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x41, 0x42, 0x41, 0x4e, - 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x07, 0x12, 0x31, 0x0a, 0x2d, 0x46, 0x41, 0x49, 0x4c, 0x55, - 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, - 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, - 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x08, 0x12, 0x2b, 0x0a, 0x27, 0x46, 0x41, - 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, - 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x41, 0x4d, 0x54, 0x5f, - 0x53, 0x57, 0x45, 0x50, 0x54, 0x10, 0x09, 0x2a, 0x2f, 0x0a, 0x11, 0x4c, 0x69, 0x71, 0x75, 0x69, - 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x48, 0x52, - 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x01, 0x2a, 0xa6, 0x03, 0x0a, 0x0a, 0x41, 0x75, 0x74, - 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x22, 0x0a, 0x1e, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x10, 0x02, - 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x45, 0x4c, 0x41, 0x50, 0x53, 0x45, 0x44, 0x10, 0x03, - 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x41, - 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, - 0x46, 0x45, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, - 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x06, - 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x55, 0x54, 0x4f, - 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, - 0x42, 0x41, 0x43, 0x4b, 0x4f, 0x46, 0x46, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, - 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, - 0x54, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, - 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x0a, 0x12, 0x1c, 0x0a, 0x18, - 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x51, 0x55, - 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x4f, 0x4b, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x55, - 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, - 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x0c, 0x12, - 0x20, 0x0a, 0x1c, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, - 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, - 0x0d, 0x32, 0xc0, 0x0a, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x12, 0x39, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x4c, - 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, - 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x30, 0x01, 0x12, - 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x19, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x48, - 0x0a, 0x0b, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x12, 0x1b, 0x2e, + 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x44, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, + 0x73, 0x77, 0x61, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, + 0x52, 0x05, 0x73, 0x77, 0x61, 0x70, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x77, + 0x65, 0x65, 0x70, 0x5f, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x77, 0x65, 0x65, 0x70, 0x54, 0x78, 0x49, 0x64, 0x22, 0x32, 0x0a, 0x11, 0x4e, 0x65, + 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x22, 0x46, + 0x0a, 0x12, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0x4e, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, + 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x08, 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, + 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x22, 0x3a, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, + 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, + 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x74, 0x78, 0x6f, 0x52, 0x05, 0x75, 0x74, 0x78, + 0x6f, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x04, 0x55, 0x74, 0x78, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x24, 0x0a, + 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2a, 0x3b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, + 0x54, 0x41, 0x50, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, 0x10, 0x01, + 0x2a, 0x25, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, + 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x4f, + 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, + 0x52, 0x45, 0x56, 0x45, 0x41, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x54, + 0x4c, 0x43, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, + 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, + 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x4f, 0x49, + 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xeb, 0x02, 0x0a, + 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, + 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, 0x55, + 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43, 0x48, 0x41, + 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, + 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x02, + 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, + 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, + 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, + 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, + 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, 0x50, + 0x4f, 0x52, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c, 0x55, + 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, + 0x45, 0x43, 0x54, 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, + 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x41, + 0x42, 0x41, 0x4e, 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x07, 0x12, 0x31, 0x0a, 0x2d, 0x46, 0x41, + 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, + 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, + 0x4d, 0x45, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x08, 0x12, 0x2b, 0x0a, + 0x27, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, + 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x41, + 0x4d, 0x54, 0x5f, 0x53, 0x57, 0x45, 0x50, 0x54, 0x10, 0x09, 0x2a, 0x2f, 0x0a, 0x11, 0x4c, 0x69, + 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x01, 0x2a, 0xa6, 0x03, 0x0a, 0x0a, + 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, + 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x54, + 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x55, 0x54, 0x4f, 0x5f, + 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x46, 0x45, 0x45, + 0x53, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x45, 0x4c, 0x41, 0x50, 0x53, 0x45, + 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x04, 0x12, 0x18, + 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, + 0x41, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x46, 0x45, + 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x41, + 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, + 0x52, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x4f, 0x46, 0x46, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, + 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, + 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, + 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x0a, 0x12, + 0x1c, 0x0a, 0x18, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, + 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x4f, 0x4b, 0x10, 0x0b, 0x12, 0x23, 0x0a, + 0x1f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, + 0x47, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, + 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, + 0x4e, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, + 0x4e, 0x54, 0x10, 0x0d, 0x32, 0x96, 0x0b, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x17, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, + 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x30, 0x01, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, + 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, + 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, + 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x48, 0x0a, 0x0b, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, + 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, + 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, - 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, - 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, - 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, - 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x51, - 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, - 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, - 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x47, 0x65, - 0x74, 0x4c, 0x73, 0x61, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, - 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x47, 0x65, + 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, + 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, + 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, + 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, + 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, + 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, + 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, + 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x15, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, + 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x73, 0x61, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, + 0x12, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, - 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, - 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, - 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, - 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, - 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, - 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, - 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, - 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, - 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa6, 0x01, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x0a, - 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, - 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, - 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, - 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, - 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, + 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, + 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, + 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, + 0x77, 0x61, 0x70, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, + 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, + 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa6, 0x01, + 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, + 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, + 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, + 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4834,7 +5032,7 @@ func file_client_proto_rawDescGZIP() []byte { } var file_client_proto_enumTypes = make([]protoimpl.EnumInfo, 7) -var file_client_proto_msgTypes = make([]protoimpl.MessageInfo, 45) +var file_client_proto_msgTypes = make([]protoimpl.MessageInfo, 48) var file_client_proto_goTypes = []interface{}{ (AddressType)(0), // 0: looprpc.AddressType (SwapType)(0), // 1: looprpc.SwapType @@ -4883,24 +5081,27 @@ var file_client_proto_goTypes = []interface{}{ (*InstantOutResponse)(nil), // 44: looprpc.InstantOutResponse (*InstantOutQuoteRequest)(nil), // 45: looprpc.InstantOutQuoteRequest (*InstantOutQuoteResponse)(nil), // 46: looprpc.InstantOutQuoteResponse - (*NewAddressRequest)(nil), // 47: looprpc.NewAddressRequest - (*NewAddressResponse)(nil), // 48: looprpc.NewAddressResponse - (*ListUnspentRequest)(nil), // 49: looprpc.ListUnspentRequest - (*ListUnspentResponse)(nil), // 50: looprpc.ListUnspentResponse - (*Utxo)(nil), // 51: looprpc.Utxo - (*swapserverrpc.RouteHint)(nil), // 52: looprpc.RouteHint + (*ListInstantOutsRequest)(nil), // 47: looprpc.ListInstantOutsRequest + (*ListInstantOutsResponse)(nil), // 48: looprpc.ListInstantOutsResponse + (*InstantOut)(nil), // 49: looprpc.InstantOut + (*NewAddressRequest)(nil), // 50: looprpc.NewAddressRequest + (*NewAddressResponse)(nil), // 51: looprpc.NewAddressResponse + (*ListUnspentRequest)(nil), // 52: looprpc.ListUnspentRequest + (*ListUnspentResponse)(nil), // 53: looprpc.ListUnspentResponse + (*Utxo)(nil), // 54: looprpc.Utxo + (*swapserverrpc.RouteHint)(nil), // 55: looprpc.RouteHint } var file_client_proto_depIdxs = []int32{ 0, // 0: looprpc.LoopOutRequest.account_addr_type:type_name -> looprpc.AddressType - 52, // 1: looprpc.LoopInRequest.route_hints:type_name -> looprpc.RouteHint + 55, // 1: looprpc.LoopInRequest.route_hints:type_name -> looprpc.RouteHint 1, // 2: looprpc.SwapStatus.type:type_name -> looprpc.SwapType 2, // 3: looprpc.SwapStatus.state:type_name -> looprpc.SwapState 3, // 4: looprpc.SwapStatus.failure_reason:type_name -> looprpc.FailureReason 13, // 5: looprpc.ListSwapsRequest.list_swap_filter:type_name -> looprpc.ListSwapsFilter 6, // 6: looprpc.ListSwapsFilter.swap_type:type_name -> looprpc.ListSwapsFilter.SwapTypeFilter 11, // 7: looprpc.ListSwapsResponse.swaps:type_name -> looprpc.SwapStatus - 52, // 8: looprpc.QuoteRequest.loop_in_route_hints:type_name -> looprpc.RouteHint - 52, // 9: looprpc.ProbeRequest.route_hints:type_name -> looprpc.RouteHint + 55, // 8: looprpc.QuoteRequest.loop_in_route_hints:type_name -> looprpc.RouteHint + 55, // 9: looprpc.ProbeRequest.route_hints:type_name -> looprpc.RouteHint 26, // 10: looprpc.TokensResponse.tokens:type_name -> looprpc.LsatToken 27, // 11: looprpc.GetInfoResponse.loop_out_stats:type_name -> looprpc.LoopStats 27, // 12: looprpc.GetInfoResponse.loop_in_stats:type_name -> looprpc.LoopStats @@ -4914,54 +5115,57 @@ var file_client_proto_depIdxs = []int32{ 8, // 20: looprpc.SuggestSwapsResponse.loop_in:type_name -> looprpc.LoopInRequest 36, // 21: looprpc.SuggestSwapsResponse.disqualified:type_name -> looprpc.Disqualified 42, // 22: looprpc.ListReservationsResponse.reservations:type_name -> looprpc.ClientReservation - 51, // 23: looprpc.ListUnspentResponse.utxos:type_name -> looprpc.Utxo - 7, // 24: looprpc.SwapClient.LoopOut:input_type -> looprpc.LoopOutRequest - 8, // 25: looprpc.SwapClient.LoopIn:input_type -> looprpc.LoopInRequest - 10, // 26: looprpc.SwapClient.Monitor:input_type -> looprpc.MonitorRequest - 12, // 27: looprpc.SwapClient.ListSwaps:input_type -> looprpc.ListSwapsRequest - 15, // 28: looprpc.SwapClient.SwapInfo:input_type -> looprpc.SwapInfoRequest - 38, // 29: looprpc.SwapClient.AbandonSwap:input_type -> looprpc.AbandonSwapRequest - 16, // 30: looprpc.SwapClient.LoopOutTerms:input_type -> looprpc.TermsRequest - 19, // 31: looprpc.SwapClient.LoopOutQuote:input_type -> looprpc.QuoteRequest - 16, // 32: looprpc.SwapClient.GetLoopInTerms:input_type -> looprpc.TermsRequest - 19, // 33: looprpc.SwapClient.GetLoopInQuote:input_type -> looprpc.QuoteRequest - 22, // 34: looprpc.SwapClient.Probe:input_type -> looprpc.ProbeRequest - 24, // 35: looprpc.SwapClient.GetLsatTokens:input_type -> looprpc.TokensRequest - 28, // 36: looprpc.SwapClient.GetInfo:input_type -> looprpc.GetInfoRequest - 30, // 37: looprpc.SwapClient.GetLiquidityParams:input_type -> looprpc.GetLiquidityParamsRequest - 33, // 38: looprpc.SwapClient.SetLiquidityParams:input_type -> looprpc.SetLiquidityParamsRequest - 35, // 39: looprpc.SwapClient.SuggestSwaps:input_type -> looprpc.SuggestSwapsRequest - 40, // 40: looprpc.SwapClient.ListReservations:input_type -> looprpc.ListReservationsRequest - 43, // 41: looprpc.SwapClient.InstantOut:input_type -> looprpc.InstantOutRequest - 45, // 42: looprpc.SwapClient.InstantOutQuote:input_type -> looprpc.InstantOutQuoteRequest - 47, // 43: looprpc.StaticAddressClient.NewAddress:input_type -> looprpc.NewAddressRequest - 49, // 44: looprpc.StaticAddressClient.ListUnspent:input_type -> looprpc.ListUnspentRequest - 9, // 45: looprpc.SwapClient.LoopOut:output_type -> looprpc.SwapResponse - 9, // 46: looprpc.SwapClient.LoopIn:output_type -> looprpc.SwapResponse - 11, // 47: looprpc.SwapClient.Monitor:output_type -> looprpc.SwapStatus - 14, // 48: looprpc.SwapClient.ListSwaps:output_type -> looprpc.ListSwapsResponse - 11, // 49: looprpc.SwapClient.SwapInfo:output_type -> looprpc.SwapStatus - 39, // 50: looprpc.SwapClient.AbandonSwap:output_type -> looprpc.AbandonSwapResponse - 18, // 51: looprpc.SwapClient.LoopOutTerms:output_type -> looprpc.OutTermsResponse - 21, // 52: looprpc.SwapClient.LoopOutQuote:output_type -> looprpc.OutQuoteResponse - 17, // 53: looprpc.SwapClient.GetLoopInTerms:output_type -> looprpc.InTermsResponse - 20, // 54: looprpc.SwapClient.GetLoopInQuote:output_type -> looprpc.InQuoteResponse - 23, // 55: looprpc.SwapClient.Probe:output_type -> looprpc.ProbeResponse - 25, // 56: looprpc.SwapClient.GetLsatTokens:output_type -> looprpc.TokensResponse - 29, // 57: looprpc.SwapClient.GetInfo:output_type -> looprpc.GetInfoResponse - 31, // 58: looprpc.SwapClient.GetLiquidityParams:output_type -> looprpc.LiquidityParameters - 34, // 59: looprpc.SwapClient.SetLiquidityParams:output_type -> looprpc.SetLiquidityParamsResponse - 37, // 60: looprpc.SwapClient.SuggestSwaps:output_type -> looprpc.SuggestSwapsResponse - 41, // 61: looprpc.SwapClient.ListReservations:output_type -> looprpc.ListReservationsResponse - 44, // 62: looprpc.SwapClient.InstantOut:output_type -> looprpc.InstantOutResponse - 46, // 63: looprpc.SwapClient.InstantOutQuote:output_type -> looprpc.InstantOutQuoteResponse - 48, // 64: looprpc.StaticAddressClient.NewAddress:output_type -> looprpc.NewAddressResponse - 50, // 65: looprpc.StaticAddressClient.ListUnspent:output_type -> looprpc.ListUnspentResponse - 45, // [45:66] is the sub-list for method output_type - 24, // [24:45] is the sub-list for method input_type - 24, // [24:24] is the sub-list for extension type_name - 24, // [24:24] is the sub-list for extension extendee - 0, // [0:24] is the sub-list for field type_name + 49, // 23: looprpc.ListInstantOutsResponse.swaps:type_name -> looprpc.InstantOut + 54, // 24: looprpc.ListUnspentResponse.utxos:type_name -> looprpc.Utxo + 7, // 25: looprpc.SwapClient.LoopOut:input_type -> looprpc.LoopOutRequest + 8, // 26: looprpc.SwapClient.LoopIn:input_type -> looprpc.LoopInRequest + 10, // 27: looprpc.SwapClient.Monitor:input_type -> looprpc.MonitorRequest + 12, // 28: looprpc.SwapClient.ListSwaps:input_type -> looprpc.ListSwapsRequest + 15, // 29: looprpc.SwapClient.SwapInfo:input_type -> looprpc.SwapInfoRequest + 38, // 30: looprpc.SwapClient.AbandonSwap:input_type -> looprpc.AbandonSwapRequest + 16, // 31: looprpc.SwapClient.LoopOutTerms:input_type -> looprpc.TermsRequest + 19, // 32: looprpc.SwapClient.LoopOutQuote:input_type -> looprpc.QuoteRequest + 16, // 33: looprpc.SwapClient.GetLoopInTerms:input_type -> looprpc.TermsRequest + 19, // 34: looprpc.SwapClient.GetLoopInQuote:input_type -> looprpc.QuoteRequest + 22, // 35: looprpc.SwapClient.Probe:input_type -> looprpc.ProbeRequest + 24, // 36: looprpc.SwapClient.GetLsatTokens:input_type -> looprpc.TokensRequest + 28, // 37: looprpc.SwapClient.GetInfo:input_type -> looprpc.GetInfoRequest + 30, // 38: looprpc.SwapClient.GetLiquidityParams:input_type -> looprpc.GetLiquidityParamsRequest + 33, // 39: looprpc.SwapClient.SetLiquidityParams:input_type -> looprpc.SetLiquidityParamsRequest + 35, // 40: looprpc.SwapClient.SuggestSwaps:input_type -> looprpc.SuggestSwapsRequest + 40, // 41: looprpc.SwapClient.ListReservations:input_type -> looprpc.ListReservationsRequest + 43, // 42: looprpc.SwapClient.InstantOut:input_type -> looprpc.InstantOutRequest + 45, // 43: looprpc.SwapClient.InstantOutQuote:input_type -> looprpc.InstantOutQuoteRequest + 47, // 44: looprpc.SwapClient.ListInstantOuts:input_type -> looprpc.ListInstantOutsRequest + 50, // 45: looprpc.StaticAddressClient.NewAddress:input_type -> looprpc.NewAddressRequest + 52, // 46: looprpc.StaticAddressClient.ListUnspent:input_type -> looprpc.ListUnspentRequest + 9, // 47: looprpc.SwapClient.LoopOut:output_type -> looprpc.SwapResponse + 9, // 48: looprpc.SwapClient.LoopIn:output_type -> looprpc.SwapResponse + 11, // 49: looprpc.SwapClient.Monitor:output_type -> looprpc.SwapStatus + 14, // 50: looprpc.SwapClient.ListSwaps:output_type -> looprpc.ListSwapsResponse + 11, // 51: looprpc.SwapClient.SwapInfo:output_type -> looprpc.SwapStatus + 39, // 52: looprpc.SwapClient.AbandonSwap:output_type -> looprpc.AbandonSwapResponse + 18, // 53: looprpc.SwapClient.LoopOutTerms:output_type -> looprpc.OutTermsResponse + 21, // 54: looprpc.SwapClient.LoopOutQuote:output_type -> looprpc.OutQuoteResponse + 17, // 55: looprpc.SwapClient.GetLoopInTerms:output_type -> looprpc.InTermsResponse + 20, // 56: looprpc.SwapClient.GetLoopInQuote:output_type -> looprpc.InQuoteResponse + 23, // 57: looprpc.SwapClient.Probe:output_type -> looprpc.ProbeResponse + 25, // 58: looprpc.SwapClient.GetLsatTokens:output_type -> looprpc.TokensResponse + 29, // 59: looprpc.SwapClient.GetInfo:output_type -> looprpc.GetInfoResponse + 31, // 60: looprpc.SwapClient.GetLiquidityParams:output_type -> looprpc.LiquidityParameters + 34, // 61: looprpc.SwapClient.SetLiquidityParams:output_type -> looprpc.SetLiquidityParamsResponse + 37, // 62: looprpc.SwapClient.SuggestSwaps:output_type -> looprpc.SuggestSwapsResponse + 41, // 63: looprpc.SwapClient.ListReservations:output_type -> looprpc.ListReservationsResponse + 44, // 64: looprpc.SwapClient.InstantOut:output_type -> looprpc.InstantOutResponse + 46, // 65: looprpc.SwapClient.InstantOutQuote:output_type -> looprpc.InstantOutQuoteResponse + 48, // 66: looprpc.SwapClient.ListInstantOuts:output_type -> looprpc.ListInstantOutsResponse + 51, // 67: looprpc.StaticAddressClient.NewAddress:output_type -> looprpc.NewAddressResponse + 53, // 68: looprpc.StaticAddressClient.ListUnspent:output_type -> looprpc.ListUnspentResponse + 47, // [47:69] is the sub-list for method output_type + 25, // [25:47] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name } func init() { file_client_proto_init() } @@ -5451,7 +5655,7 @@ func file_client_proto_init() { } } file_client_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NewAddressRequest); i { + switch v := v.(*ListInstantOutsRequest); i { case 0: return &v.state case 1: @@ -5463,7 +5667,7 @@ func file_client_proto_init() { } } file_client_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NewAddressResponse); i { + switch v := v.(*ListInstantOutsResponse); i { case 0: return &v.state case 1: @@ -5475,7 +5679,7 @@ func file_client_proto_init() { } } file_client_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListUnspentRequest); i { + switch v := v.(*InstantOut); i { case 0: return &v.state case 1: @@ -5487,7 +5691,7 @@ func file_client_proto_init() { } } file_client_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListUnspentResponse); i { + switch v := v.(*NewAddressRequest); i { case 0: return &v.state case 1: @@ -5499,6 +5703,42 @@ func file_client_proto_init() { } } file_client_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NewAddressResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListUnspentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListUnspentResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Utxo); i { case 0: return &v.state @@ -5517,7 +5757,7 @@ func file_client_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_client_proto_rawDesc, NumEnums: 7, - NumMessages: 45, + NumMessages: 48, NumExtensions: 0, NumServices: 2, }, diff --git a/looprpc/client.proto b/looprpc/client.proto index aa746fc..738fe03 100644 --- a/looprpc/client.proto +++ b/looprpc/client.proto @@ -127,6 +127,13 @@ service SwapClient { */ rpc InstantOutQuote (InstantOutQuoteRequest) returns (InstantOutQuoteResponse); + + /* loop: `listinstantouts` + ListInstantOuts returns a list of all currently known instant out swaps and + their current status. + */ + rpc ListInstantOuts (ListInstantOutsRequest) + returns (ListInstantOutsResponse); } message LoopOutRequest { @@ -1387,11 +1394,49 @@ message InstantOutQuoteResponse { int64 sweep_fee_sat = 2; } +message ListInstantOutsRequest { +} + +message ListInstantOutsResponse { + /* + The list of all currently known instant out swaps and their status. + */ + repeated InstantOut swaps = 1; +} + +message InstantOut { + /* + The swap hash that identifies this swap. + */ + bytes swap_hash = 1; + + /* + The state the swap is in. + */ + string state = 2; + + /* + The amount of the swap. + */ + uint64 amount = 3; + + /* + The used reservations for the swap. + */ + repeated bytes reservation_ids = 4; + + /* + The sweep transaction id of the swap. + */ + string sweep_tx_id = 5; +} + service StaticAddressClient { /* NewAddress requests a new static address for loop-ins from the server. */ rpc NewAddress (NewAddressRequest) returns (NewAddressResponse); + /* ListUnspent returns a list of utxos behind a static address. */ @@ -1457,4 +1502,4 @@ message Utxo { The number of confirmations for the Utxo. */ int64 confirmations = 4; -} \ No newline at end of file +} diff --git a/looprpc/client.swagger.json b/looprpc/client.swagger.json index 2b86e79..a70776e 100644 --- a/looprpc/client.swagger.json +++ b/looprpc/client.swagger.json @@ -763,6 +763,37 @@ } } }, + "looprpcInstantOut": { + "type": "object", + "properties": { + "swap_hash": { + "type": "string", + "format": "byte", + "description": "The swap hash that identifies this swap." + }, + "state": { + "type": "string", + "description": "The state the swap is in." + }, + "amount": { + "type": "string", + "format": "uint64", + "description": "The amount of the swap." + }, + "reservation_ids": { + "type": "array", + "items": { + "type": "string", + "format": "byte" + }, + "description": "The used reservations for the swap." + }, + "sweep_tx_id": { + "type": "string", + "description": "The sweep transaction id of the swap." + } + } + }, "looprpcInstantOutQuoteResponse": { "type": "object", "properties": { @@ -959,6 +990,18 @@ ], "default": "UNKNOWN" }, + "looprpcListInstantOutsResponse": { + "type": "object", + "properties": { + "swaps": { + "type": "array", + "items": { + "$ref": "#/definitions/looprpcInstantOut" + }, + "description": "The list of all currently known instant out swaps and their status." + } + } + }, "looprpcListReservationsResponse": { "type": "object", "properties": { diff --git a/looprpc/client_grpc.pb.go b/looprpc/client_grpc.pb.go index f426a1e..b7de6cb 100644 --- a/looprpc/client_grpc.pb.go +++ b/looprpc/client_grpc.pb.go @@ -93,6 +93,10 @@ type SwapClientClient interface { //InstantOutQuote returns a quote for an instant out swap with the provided //parameters. InstantOutQuote(ctx context.Context, in *InstantOutQuoteRequest, opts ...grpc.CallOption) (*InstantOutQuoteResponse, error) + // loop: `listinstantouts` + //ListInstantOuts returns a list of all currently known instant out swaps and + //their current status. + ListInstantOuts(ctx context.Context, in *ListInstantOutsRequest, opts ...grpc.CallOption) (*ListInstantOutsResponse, error) } type swapClientClient struct { @@ -297,6 +301,15 @@ func (c *swapClientClient) InstantOutQuote(ctx context.Context, in *InstantOutQu return out, nil } +func (c *swapClientClient) ListInstantOuts(ctx context.Context, in *ListInstantOutsRequest, opts ...grpc.CallOption) (*ListInstantOutsResponse, error) { + out := new(ListInstantOutsResponse) + err := c.cc.Invoke(ctx, "/looprpc.SwapClient/ListInstantOuts", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // SwapClientServer is the server API for SwapClient service. // All implementations must embed UnimplementedSwapClientServer // for forward compatibility @@ -376,6 +389,10 @@ type SwapClientServer interface { //InstantOutQuote returns a quote for an instant out swap with the provided //parameters. InstantOutQuote(context.Context, *InstantOutQuoteRequest) (*InstantOutQuoteResponse, error) + // loop: `listinstantouts` + //ListInstantOuts returns a list of all currently known instant out swaps and + //their current status. + ListInstantOuts(context.Context, *ListInstantOutsRequest) (*ListInstantOutsResponse, error) mustEmbedUnimplementedSwapClientServer() } @@ -440,6 +457,9 @@ func (UnimplementedSwapClientServer) InstantOut(context.Context, *InstantOutRequ func (UnimplementedSwapClientServer) InstantOutQuote(context.Context, *InstantOutQuoteRequest) (*InstantOutQuoteResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method InstantOutQuote not implemented") } +func (UnimplementedSwapClientServer) ListInstantOuts(context.Context, *ListInstantOutsRequest) (*ListInstantOutsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListInstantOuts not implemented") +} func (UnimplementedSwapClientServer) mustEmbedUnimplementedSwapClientServer() {} // UnsafeSwapClientServer may be embedded to opt out of forward compatibility for this service. @@ -798,6 +818,24 @@ func _SwapClient_InstantOutQuote_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _SwapClient_ListInstantOuts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListInstantOutsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SwapClientServer).ListInstantOuts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.SwapClient/ListInstantOuts", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SwapClientServer).ListInstantOuts(ctx, req.(*ListInstantOutsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // SwapClient_ServiceDesc is the grpc.ServiceDesc for SwapClient service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -877,6 +915,10 @@ var SwapClient_ServiceDesc = grpc.ServiceDesc{ MethodName: "InstantOutQuote", Handler: _SwapClient_InstantOutQuote_Handler, }, + { + MethodName: "ListInstantOuts", + Handler: _SwapClient_ListInstantOuts_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/looprpc/swapclient.pb.json.go b/looprpc/swapclient.pb.json.go index 986a467..a715cdd 100644 --- a/looprpc/swapclient.pb.json.go +++ b/looprpc/swapclient.pb.json.go @@ -512,4 +512,29 @@ func RegisterSwapClientJSONCallbacks(registry map[string]func(ctx context.Contex } callback(string(respBytes), nil) } + + registry["looprpc.SwapClient.ListInstantOuts"] = func(ctx context.Context, + conn *grpc.ClientConn, reqJSON string, callback func(string, error)) { + + req := &ListInstantOutsRequest{} + err := marshaler.Unmarshal([]byte(reqJSON), req) + if err != nil { + callback("", err) + return + } + + client := NewSwapClientClient(conn) + resp, err := client.ListInstantOuts(ctx, req) + if err != nil { + callback("", err) + return + } + + respBytes, err := marshaler.Marshal(resp) + if err != nil { + callback("", err) + return + } + callback(string(respBytes), nil) + } } diff --git a/scripts/gen_sqlc_docker.sh b/scripts/gen_sqlc_docker.sh index 14e0ce9..b2c9ac6 100755 --- a/scripts/gen_sqlc_docker.sh +++ b/scripts/gen_sqlc_docker.sh @@ -16,5 +16,5 @@ docker run \ -e UID=$UID \ -v "$DIR/../:/build" \ -w /build \ - kjconroy/sqlc:1.17.2 generate + sqlc/sqlc:1.25.0 generate diff --git a/sweepbatcher/store.go b/sweepbatcher/store.go index 2bd3ea2..3fcc32e 100644 --- a/sweepbatcher/store.go +++ b/sweepbatcher/store.go @@ -22,9 +22,17 @@ type BaseDB interface { GetBatchSweeps(ctx context.Context, batchID int32) ( []sqlc.GetBatchSweepsRow, error) + // GetBatchSweptAmount returns the total amount of sats swept by a + // (confirmed) batch. + GetBatchSweptAmount(ctx context.Context, batchID int32) (int64, error) + // GetSweepStatus returns true if the sweep has been completed. GetSweepStatus(ctx context.Context, swapHash []byte) (bool, error) + // GetParentBatch fetches the parent batch of a completed sweep. + GetParentBatch(ctx context.Context, swapHash []byte) (sqlc.SweepBatch, + error) + // GetSwapUpdates fetches all the updates for a swap. GetSwapUpdates(ctx context.Context, swapHash []byte) ( []sqlc.SwapUpdate, error) @@ -148,6 +156,34 @@ func (s *SQLStore) FetchBatchSweeps(ctx context.Context, id int32) ( return sweeps, nil } +// TotalSweptAmount returns the total amount swept by a (confirmed) batch. +func (s *SQLStore) TotalSweptAmount(ctx context.Context, id int32) ( + btcutil.Amount, error) { + + amt, err := s.baseDb.GetBatchSweptAmount(ctx, id) + if err != nil { + return 0, err + } + + return btcutil.Amount(amt), nil +} + +// GetParentBatch fetches the parent batch of a completed sweep. +func (s *SQLStore) GetParentBatch(ctx context.Context, swapHash lntypes.Hash) ( + *dbBatch, error) { + + batch, err := s.baseDb.GetParentBatch(ctx, swapHash[:]) + if err != nil { + return nil, err + } + + if err != nil { + return nil, err + } + + return convertBatchRow(batch), nil +} + // UpsertSweep inserts a sweep into the database, or updates an existing sweep // if it already exists. func (s *SQLStore) UpsertSweep(ctx context.Context, sweep *dbSweep) error { diff --git a/sweepbatcher/store_mock.go b/sweepbatcher/store_mock.go index fef88c7..f27fcb4 100644 --- a/sweepbatcher/store_mock.go +++ b/sweepbatcher/store_mock.go @@ -5,6 +5,7 @@ import ( "errors" "sort" + "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lntypes" ) @@ -123,3 +124,44 @@ func (s *StoreMock) AssertSweepStored(id lntypes.Hash) bool { _, ok := s.sweeps[id] return ok } + +// GetParentBatch returns the parent batch of a swap. +func (s *StoreMock) GetParentBatch(ctx context.Context, swapHash lntypes.Hash) ( + *dbBatch, error) { + + for _, sweep := range s.sweeps { + if sweep.SwapHash == swapHash { + batch, ok := s.batches[sweep.BatchID] + if !ok { + return nil, errors.New("batch not found") + } + return &batch, nil + } + } + + return nil, errors.New("batch not found") +} + +// TotalSweptAmount returns the total amount of BTC that has been swept from a +// batch. +func (s *StoreMock) TotalSweptAmount(ctx context.Context, batchID int32) ( + btcutil.Amount, error) { + + batch, ok := s.batches[batchID] + if !ok { + return 0, errors.New("batch not found") + } + + if batch.State != batchConfirmed && batch.State != batchClosed { + return 0, nil + } + + var total btcutil.Amount + for _, sweep := range s.sweeps { + if sweep.BatchID == batchID { + total += sweep.Amount + } + } + + return 0, nil +} diff --git a/sweepbatcher/sweep_batch.go b/sweepbatcher/sweep_batch.go index 971b83d..0960f31 100644 --- a/sweepbatcher/sweep_batch.go +++ b/sweepbatcher/sweep_batch.go @@ -1136,6 +1136,33 @@ func (b *batch) monitorConfirmations(ctx context.Context) error { return nil } +// getFeePortionForSweep calculates the fee portion that each sweep should pay +// for the batch transaction. The fee is split evenly among the sweeps, If the +// fee cannot be split evenly, the remainder is paid by the first sweep. +func getFeePortionForSweep(spendTx *wire.MsgTx, numSweeps int, + totalSweptAmt btcutil.Amount) (btcutil.Amount, btcutil.Amount) { + + totalFee := spendTx.TxOut[0].Value - int64(totalSweptAmt) + feePortionPerSweep := (int64(totalSweptAmt) - + spendTx.TxOut[0].Value) / int64(numSweeps) + roundingDiff := totalFee - (int64(numSweeps) * feePortionPerSweep) + + return btcutil.Amount(feePortionPerSweep), btcutil.Amount(roundingDiff) +} + +// getFeePortionPaidBySweep returns the fee portion that the sweep should pay +// for the batch transaction. If the sweep is the first sweep in the batch, it +// pays the rounding difference. +func getFeePortionPaidBySweep(spendTx *wire.MsgTx, feePortionPerSweep, + roundingDiff btcutil.Amount, sweep *sweep) btcutil.Amount { + + if bytes.Equal(spendTx.TxIn[0].SignatureScript, sweep.htlc.SigScript) { + return feePortionPerSweep + roundingDiff + } + + return feePortionPerSweep +} + // handleSpend handles a spend notification. func (b *batch) handleSpend(ctx context.Context, spendTx *wire.MsgTx) error { var ( @@ -1151,12 +1178,14 @@ func (b *batch) handleSpend(ctx context.Context, spendTx *wire.MsgTx) error { // sweeps that did not make it to the confirmed transaction and feed // them back to the batcher. This will ensure that the sweeps will enter // a new batch instead of remaining dangling. + var totalSweptAmt btcutil.Amount for _, sweep := range b.sweeps { found := false for _, txIn := range spendTx.TxIn { if txIn.PreviousOutPoint == sweep.outpoint { found = true + totalSweptAmt += sweep.value notifyList = append(notifyList, sweep) } } @@ -1176,7 +1205,13 @@ func (b *batch) handleSpend(ctx context.Context, spendTx *wire.MsgTx) error { } } + // Calculate the fee portion that each sweep should pay for the batch. + feePortionPaidPerSweep, roundingDifference := getFeePortionForSweep( + spendTx, len(notifyList), totalSweptAmt, + ) + for _, sweep := range notifyList { + sweep := sweep // Save the sweep as completed. err := b.persistSweep(ctx, sweep, true) if err != nil { @@ -1192,9 +1227,17 @@ func (b *batch) handleSpend(ctx context.Context, spendTx *wire.MsgTx) error { continue } + spendDetail := SpendDetail{ + Tx: spendTx, + OnChainFeePortion: getFeePortionPaidBySweep( + spendTx, feePortionPaidPerSweep, + roundingDifference, &sweep, + ), + } + // Dispatch the sweep notifier, we don't care about the outcome // of this action so we don't wait for it. - go notifySweepSpend(ctx, sweep, spendTx) + go sweep.notifySweepSpend(ctx, &spendDetail) } // Proceed with purging the sweeps. This will feed the sweeps that @@ -1318,10 +1361,12 @@ func (b *batch) insertAndAcquireID(ctx context.Context) (int32, error) { } // notifySweepSpend writes the spendTx to the sweep's notifier channel. -func notifySweepSpend(ctx context.Context, s sweep, spendTx *wire.MsgTx) { +func (s *sweep) notifySweepSpend(ctx context.Context, + spendDetail *SpendDetail) { + select { // Try to write the update to the notification channel. - case s.notifier.SpendChan <- spendTx: + case s.notifier.SpendChan <- spendDetail: // If a quit signal was provided by the swap, continue. case <-s.notifier.QuitChan: diff --git a/sweepbatcher/sweep_batcher.go b/sweepbatcher/sweep_batcher.go index 5548085..7065a47 100644 --- a/sweepbatcher/sweep_batcher.go +++ b/sweepbatcher/sweep_batcher.go @@ -72,6 +72,14 @@ type BatcherStore interface { // GetSweepStatus returns the completed status of the sweep. GetSweepStatus(ctx context.Context, swapHash lntypes.Hash) ( bool, error) + + // GetParentBatch returns the parent batch of a (completed) sweep. + GetParentBatch(ctx context.Context, swapHash lntypes.Hash) ( + *dbBatch, error) + + // TotalSweptAmount returns the total amount swept by a (confirmed) + // batch. + TotalSweptAmount(ctx context.Context, id int32) (btcutil.Amount, error) } // MuSig2SignSweep is a function that can be used to sign a sweep transaction @@ -102,11 +110,22 @@ type SweepRequest struct { Notifier *SpendNotifier } +type SpendDetail struct { + // Tx is the transaction that spent the outpoint. + Tx *wire.MsgTx + + // OnChainFeePortion is the fee portion that was paid to get this sweep + // confirmed on chain. This is the difference between the value of the + // outpoint and the value of all sweeps that were included in the batch + // divided by the number of sweeps. + OnChainFeePortion btcutil.Amount +} + // SpendNotifier is a notifier that is used to notify the requester of a sweep // that the sweep was successful. type SpendNotifier struct { // SpendChan is a channel where the spend details are received. - SpendChan chan *wire.MsgTx + SpendChan chan *SpendDetail // SpendErrChan is a channel where spend errors are received. SpendErrChan chan error @@ -270,8 +289,7 @@ func (b *Batcher) handleSweep(ctx context.Context, sweep *sweep, // can't attach its notifier to the batch as that is no longer running. // Instead we directly detect and return the spend here. if completed && *notifier != (SpendNotifier{}) { - go b.monitorSpendAndNotify(ctx, sweep, notifier) - return nil + return b.monitorSpendAndNotify(ctx, sweep, notifier) } sweep.notifier = notifier @@ -509,57 +527,86 @@ func (b *Batcher) FetchUnconfirmedBatches(ctx context.Context) ([]*batch, // monitorSpendAndNotify monitors the spend of a specific outpoint and writes // the response back to the response channel. func (b *Batcher) monitorSpendAndNotify(ctx context.Context, sweep *sweep, - notifier *SpendNotifier) { - - b.wg.Add(1) - defer b.wg.Done() + notifier *SpendNotifier) error { spendCtx, cancel := context.WithCancel(ctx) defer cancel() + // First get the batch that completed the sweep. + parentBatch, err := b.store.GetParentBatch(ctx, sweep.swapHash) + if err != nil { + return err + } + + // Then we get the total amount that was swept by the batch. + totalSwept, err := b.store.TotalSweptAmount(ctx, parentBatch.ID) + if err != nil { + return err + } + spendChan, spendErr, err := b.chainNotifier.RegisterSpendNtfn( spendCtx, &sweep.outpoint, sweep.htlc.PkScript, sweep.initiationHeight, ) if err != nil { - select { - case notifier.SpendErrChan <- err: - case <-ctx.Done(): - } - - _ = b.writeToErrChan(ctx, err) - - return + return err } - log.Infof("Batcher monitoring spend for swap %x", sweep.swapHash[:6]) + b.wg.Add(1) + go func() { + defer b.wg.Done() + log.Infof("Batcher monitoring spend for swap %x", + sweep.swapHash[:6]) - for { - select { - case spend := <-spendChan: + for { select { - case notifier.SpendChan <- spend.SpendingTx: - case <-ctx.Done(): - } - - return + case spend := <-spendChan: + spendTx := spend.SpendingTx + // Calculate the fee portion that each sweep + // should pay for the batch. + feePortionPerSweep, roundingDifference := + getFeePortionForSweep( + spendTx, len(spendTx.TxIn), + totalSwept, + ) + + // Notify the requester of the spend + // with the spend details, including the fee + // portion for this particular sweep. + spendDetail := &SpendDetail{ + Tx: spendTx, + OnChainFeePortion: getFeePortionPaidBySweep( // nolint:lll + spendTx, feePortionPerSweep, + roundingDifference, sweep, + ), + } + + select { + case notifier.SpendChan <- spendDetail: + case <-ctx.Done(): + } + + return + + case err := <-spendErr: + select { + case notifier.SpendErrChan <- err: + case <-ctx.Done(): + } + + _ = b.writeToErrChan(ctx, err) + return + + case <-notifier.QuitChan: + return - case err := <-spendErr: - select { - case notifier.SpendErrChan <- err: case <-ctx.Done(): + return } - - _ = b.writeToErrChan(ctx, err) - return - - case <-notifier.QuitChan: - return - - case <-ctx.Done(): - return } - } + }() + + return nil } func (b *Batcher) writeToErrChan(ctx context.Context, err error) error { diff --git a/sweepbatcher/sweep_batcher_test.go b/sweepbatcher/sweep_batcher_test.go index 2d233b9..1671007 100644 --- a/sweepbatcher/sweep_batcher_test.go +++ b/sweepbatcher/sweep_batcher_test.go @@ -38,7 +38,7 @@ func testMuSig2SignSweep(ctx context.Context, } var dummyNotifier = SpendNotifier{ - SpendChan: make(chan *wire.MsgTx, ntfnBufferSize), + SpendChan: make(chan *SpendDetail, ntfnBufferSize), SpendErrChan: make(chan error, ntfnBufferSize), QuitChan: make(chan bool, ntfnBufferSize), } diff --git a/version.go b/version.go index 29636dd..094c04a 100644 --- a/version.go +++ b/version.go @@ -26,7 +26,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr const ( // Note: please update release_notes.md when you change these values. appMajor uint = 0 - appMinor uint = 27 + appMinor uint = 28 appPatch uint = 1 // appPreRelease MUST only contain characters from semanticAlphabet per