diff --git a/.github/workflows/ci_release.yml b/.github/workflows/ci_release.yml index 628091e..4fbd9a4 100644 --- a/.github/workflows/ci_release.yml +++ b/.github/workflows/ci_release.yml @@ -24,6 +24,12 @@ on: - major jobs: + # TODO: Uncomment once test is available in released node. + #api-equivalence: + #uses: ./github/workflows/test-equivalence.yml + #with: + #GO_VERSION: "1.22" + lint: uses: ./.github/workflows/lint.yml with: diff --git a/.github/workflows/test-equivalence.yml b/.github/workflows/test-equivalence.yml new file mode 100644 index 0000000..8f5da14 --- /dev/null +++ b/.github/workflows/test-equivalence.yml @@ -0,0 +1,27 @@ +# api-equivalence workflow ensures that the API structs between the two repositories are consistent +# This workflow is triggered by ci_release.yml workflow +name: api-equivalence +on: + workflow_call: + inputs: + GO_VERSION: + description: "Go version to use" + type: string + required: true + +jobs: + test-equivalence: + name: Test API Equivalence + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + repository: celestiaorg/celestia-node + ref: v0.13.4 + - uses: actions/setup-go@v5 + with: + go-version: ${{ inputs.GO_VERSION }} + + - name: Run Structs Equivalence Test + run: cd celestia-node && go test -v -tags=conformance ./api -run TestAPIEquivalence diff --git a/README.md b/README.md index 4a6ad4e..653a280 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,67 @@ # celestia-openrpc -OpenRPC is a client of [celestia-node RPC](https://docs.celestia.org/developers/node-api/), without depenencies on celestia-node/celestia-app/cosmos-sdk. +`celestia-openrpc` is a golang client for [celestia-node RPC](https://docs.celestia.org/developers/node-api/), without depenencies on celestia-node/celestia-app/cosmos-sdk. -This is a temporary measure to resolve dependency issues when celestia-node is imported by celestia. +This client library is useful for environments where dependencies on celestia-node/celestia-app/cosmos-sdk are not possible or desired. + +## Examples + +For a full tutorial on how to use this library, visit the official [guide](https://docs.celestia.org/developers/golang-client-tutorial). + +For more examples, see the [examples](./examples) directory. + +### Create a new client and submit and fetch a blob + +```go +import ( + "bytes" + "context" + "fmt" + + client "github.com/celestiaorg/celestia-openrpc" + "github.com/celestiaorg/celestia-openrpc/types/blob" + "github.com/celestiaorg/celestia-openrpc/types/share" + "github.com/celestiaorg/rsmt2d" +) + +func main() { + SubmitBlob(context.Background(), "ws://localhost:26658", "JWT_TOKEN") +} + +// SubmitBlob submits a blob containing "Hello, World!" to the 0xDEADBEEF namespace. It uses the default signer on the running node. +func SubmitBlob(ctx context.Context, url string, token string) error { + client, err := client.NewClient(ctx, url, token) + if err != nil { + return err + } + + // let's post to 0xDEADBEEF namespace + namespace, err := share.NewBlobNamespaceV0([]byte{0xDE, 0xAD, 0xBE, 0xEF}) + if err != nil { + return err + } + + // create a blob + helloWorldBlob, err := blob.NewBlobV0(namespace, []byte("Hello, World!")) + if err != nil { + return err + } + + // submit the blob to the network + height, err := client.Blob.Submit(ctx, []*blob.Blob{helloWorldBlob}, blob.DefaultGasPrice()) + if err != nil { + return err + } + + fmt.Printf("Blob was included at height %d\n", height) + + // fetch the blob back from the network + retrievedBlobs, err := client.Blob.GetAll(ctx, height, []share.Namespace{namespace}) + if err != nil { + return err + } + + fmt.Printf("Blobs are equal? %v\n", bytes.Equal(helloWorldBlob.Commitment, retrievedBlobs[0].Commitment)) + return nil +} +``` diff --git a/api.go b/api.go deleted file mode 100644 index 728c625..0000000 --- a/api.go +++ /dev/null @@ -1,184 +0,0 @@ -package client - -import ( - "context" - - "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/libp2p/go-libp2p/core/metrics" - "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/core/protocol" - rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" - - "github.com/celestiaorg/rsmt2d" - - libhead "github.com/celestiaorg/go-header" - - "github.com/celestiaorg/go-fraud" - - "github.com/celestiaorg/go-header/sync" - - "github.com/celestiaorg/celestia-openrpc/types/blob" - "github.com/celestiaorg/celestia-openrpc/types/das" - "github.com/celestiaorg/celestia-openrpc/types/header" - "github.com/celestiaorg/celestia-openrpc/types/node" - "github.com/celestiaorg/celestia-openrpc/types/share" - "github.com/celestiaorg/celestia-openrpc/types/state" -) - -// Proof embeds the fraud.Proof interface type to provide a concrete type for JSON serialization. -type Proof struct { - fraud.Proof[*header.ExtendedHeader] -} - -type FraudAPI struct { - Subscribe func(context.Context, fraud.ProofType) (<-chan *Proof, error) `perm:"read"` - Get func(context.Context, fraud.ProofType) ([]Proof, error) `perm:"read"` -} - -type DASAPI struct { - SamplingStats func(ctx context.Context) (das.SamplingStats, error) `perm:"read"` - WaitCatchUp func(ctx context.Context) error `perm:"read"` -} - -type BlobAPI struct { - Submit func(context.Context, []*blob.Blob, GasPrice) (uint64, error) `perm:"write"` - Get func(context.Context, uint64, share.Namespace, blob.Commitment) (*blob.Blob, error) `perm:"read"` - GetAll func(context.Context, uint64, []share.Namespace) ([]*blob.Blob, error) `perm:"read"` - GetProof func(context.Context, uint64, share.Namespace, blob.Commitment) (*blob.Proof, error) `perm:"read"` - Included func(context.Context, uint64, share.Namespace, *blob.Proof, blob.Commitment) (bool, error) `perm:"read"` -} - -type HeaderAPI struct { - LocalHead func(context.Context) (*header.ExtendedHeader, error) `perm:"read"` - GetByHash func( - ctx context.Context, - hash libhead.Hash, - ) (*header.ExtendedHeader, error) `perm:"read"` - GetRangeByHeight func( - context.Context, - *header.ExtendedHeader, - uint64, - ) ([]*header.ExtendedHeader, error) `perm:"read"` - GetByHeight func(context.Context, uint64) (*header.ExtendedHeader, error) `perm:"read"` - WaitForHeight func(context.Context, uint64) (*header.ExtendedHeader, error) `perm:"read"` - SyncState func(ctx context.Context) (sync.State, error) `perm:"read"` - SyncWait func(ctx context.Context) error `perm:"read"` - NetworkHead func(ctx context.Context) (*header.ExtendedHeader, error) `perm:"read"` - Subscribe func(ctx context.Context) (<-chan *header.ExtendedHeader, error) `perm:"read"` -} -type StateAPI struct { - AccountAddress func(ctx context.Context) (state.Address, error) `perm:"read"` - IsStopped func(ctx context.Context) bool `perm:"read"` - Balance func(ctx context.Context) (*state.Balance, error) `perm:"read"` - BalanceForAddress func(ctx context.Context, addr state.Address) (*state.Balance, error) `perm:"read"` - Transfer func( - ctx context.Context, - to state.AccAddress, - amount, - fee state.Int, - gasLimit uint64, - ) (*state.TxResponse, error) `perm:"write"` - SubmitTx func(ctx context.Context, tx state.Tx) (*state.TxResponse, error) `perm:"write"` - SubmitPayForBlob func( - ctx context.Context, - fee state.Int, - gasLim uint64, - blobs []*blob.Blob, - ) (*state.TxResponse, error) `perm:"write"` - CancelUnbondingDelegation func( - ctx context.Context, - valAddr state.ValAddress, - amount, - height, - fee state.Int, - gasLim uint64, - ) (*state.TxResponse, error) `perm:"write"` - BeginRedelegate func( - ctx context.Context, - srcValAddr, - dstValAddr state.ValAddress, - amount, - fee state.Int, - gasLim uint64, - ) (*state.TxResponse, error) `perm:"write"` - Undelegate func( - ctx context.Context, - delAddr state.ValAddress, - amount, - fee state.Int, - gasLim uint64, - ) (*state.TxResponse, error) `perm:"write"` - Delegate func( - ctx context.Context, - delAddr state.ValAddress, - amount, - fee state.Int, - gasLim uint64, - ) (*state.TxResponse, error) `perm:"write"` - QueryDelegation func( - ctx context.Context, - valAddr state.ValAddress, - ) (*state.QueryDelegationResponse, error) `perm:"read"` - QueryUnbonding func( - ctx context.Context, - valAddr state.ValAddress, - ) (*state.QueryUnbondingDelegationResponse, error) `perm:"read"` - QueryRedelegations func( - ctx context.Context, - srcValAddr, - dstValAddr state.ValAddress, - ) (*state.QueryRedelegationsResponse, error) `perm:"read"` -} -type ShareAPI struct { - SharesAvailable func(context.Context, *header.ExtendedHeader) error `perm:"read"` - GetShare func( - ctx context.Context, - eh *header.ExtendedHeader, - row, col int, - ) (share.Share, error) `perm:"read"` - GetEDS func( - ctx context.Context, - eh *header.ExtendedHeader, - ) (*rsmt2d.ExtendedDataSquare, error) `perm:"read"` - GetSharesByNamespace func( - ctx context.Context, - eh *header.ExtendedHeader, - namespace share.Namespace, - ) (share.NamespacedShares, error) `perm:"read"` -} -type P2PAPI struct { - Peers func(context.Context) ([]peer.ID, error) `perm:"admin"` - PeerInfo func(ctx context.Context, id peer.ID) (peer.AddrInfo, error) `perm:"admin"` - Connect func(ctx context.Context, pi peer.AddrInfo) error `perm:"admin"` - ClosePeer func(ctx context.Context, id peer.ID) error `perm:"admin"` - Connectedness func(ctx context.Context, id peer.ID) (network.Connectedness, error) `perm:"admin"` - NATStatus func(context.Context) (network.Reachability, error) `perm:"admin"` - BlockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` - UnblockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` - ListBlockedPeers func(context.Context) ([]peer.ID, error) `perm:"admin"` - Protect func(ctx context.Context, id peer.ID, tag string) error `perm:"admin"` - Unprotect func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` - IsProtected func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` - BandwidthStats func(context.Context) (metrics.Stats, error) `perm:"admin"` - BandwidthForPeer func(ctx context.Context, id peer.ID) (metrics.Stats, error) `perm:"admin"` - BandwidthForProtocol func(ctx context.Context, proto protocol.ID) (metrics.Stats, error) `perm:"admin"` - ResourceState func(context.Context) (rcmgr.ResourceManagerStat, error) `perm:"admin"` - PubSubPeers func(ctx context.Context, topic string) ([]peer.ID, error) `perm:"admin"` -} -type NodeAPI struct { - Info func(context.Context) (node.Info, error) `perm:"admin"` - LogLevelSet func(ctx context.Context, name, level string) error `perm:"admin"` - AuthVerify func(ctx context.Context, token string) ([]auth.Permission, error) `perm:"admin"` - AuthNew func(ctx context.Context, perms []auth.Permission) ([]byte, error) `perm:"admin"` -} - -// GasPrice represents the amount to be paid per gas unit. Fee is set by -// multiplying GasPrice by GasLimit, which is determined by the blob sizes. -type GasPrice float64 - -// DefaultGasPrice returns the default gas price, letting node automatically -// determine the Fee based on the passed blob sizes. -func DefaultGasPrice() GasPrice { - return -1.0 -} diff --git a/builder/client.go b/builder/client.go new file mode 100644 index 0000000..5d63de8 --- /dev/null +++ b/builder/client.go @@ -0,0 +1,51 @@ +package clientbuilder + +import ( + "context" + "fmt" + "net/http" + "reflect" + "strings" + + "github.com/filecoin-project/go-jsonrpc" +) + +const AuthKey = "Authorization" + +// MultiClientCloser is a wrapper struct to close clients across multiple namespaces. +type MultiClientCloser struct { + closers []jsonrpc.ClientCloser +} + +// Register adds a new closer to the multiClientCloser +func (m *MultiClientCloser) Register(closer jsonrpc.ClientCloser) { + m.closers = append(m.closers, closer) +} + +// CloseAll closes all saved clients. +func (m *MultiClientCloser) CloseAll() { + for _, closer := range m.closers { + closer() + } +} + +func NewClient(ctx context.Context, addr string, token string, client interface{}) (interface{}, error) { + var authHeader http.Header + if token != "" { + authHeader = http.Header{AuthKey: []string{fmt.Sprintf("Bearer %s", token)}} + } + + v := reflect.ValueOf(client).Elem() + t := v.Type() + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + name := strings.ToLower(field.Name) + module := v.Field(i).Addr().Interface() + _, err := jsonrpc.NewClient(ctx, addr, name, module, authHeader) + if err != nil { + return nil, err + } + } + + return client, nil +} diff --git a/client.go b/client.go index 0950670..966d1f4 100644 --- a/client.go +++ b/client.go @@ -5,44 +5,39 @@ import ( "fmt" "net/http" + clientbuilder "github.com/celestiaorg/celestia-openrpc/builder" + "github.com/celestiaorg/celestia-openrpc/types/blob" + "github.com/celestiaorg/celestia-openrpc/types/da" + "github.com/celestiaorg/celestia-openrpc/types/das" + "github.com/celestiaorg/celestia-openrpc/types/fraud" + "github.com/celestiaorg/celestia-openrpc/types/header" + "github.com/celestiaorg/celestia-openrpc/types/node" + "github.com/celestiaorg/celestia-openrpc/types/p2p" + "github.com/celestiaorg/celestia-openrpc/types/share" + "github.com/celestiaorg/celestia-openrpc/types/state" + "github.com/filecoin-project/go-jsonrpc" ) const AuthKey = "Authorization" type Client struct { - Fraud FraudAPI - Blob BlobAPI - Header HeaderAPI - State StateAPI - Share ShareAPI - DAS DASAPI - P2P P2PAPI - Node NodeAPI - - closer multiClientCloser -} - -// multiClientCloser is a wrapper struct to close clients across multiple namespaces. -type multiClientCloser struct { - closers []jsonrpc.ClientCloser -} - -// register adds a new closer to the multiClientCloser -func (m *multiClientCloser) register(closer jsonrpc.ClientCloser) { - m.closers = append(m.closers, closer) -} + Fraud fraud.API + Blob blob.API + Header header.API + State state.API + Share share.API + DAS das.API + P2P p2p.API + Node node.API + DA da.API -// closeAll closes all saved clients. -func (m *multiClientCloser) closeAll() { - for _, closer := range m.closers { - closer() - } + closer clientbuilder.MultiClientCloser } // Close closes the connections to all namespaces registered on the client. func (c *Client) Close() { - c.closer.closeAll() + c.closer.CloseAll() } func NewClient(ctx context.Context, addr string, token string) (*Client, error) { @@ -62,6 +57,7 @@ func NewClient(ctx context.Context, addr string, token string) (*Client, error) "das": &client.DAS, "p2p": &client.P2P, "node": &client.Node, + "da": &client.DA, } for name, module := range modules { @@ -69,7 +65,7 @@ func NewClient(ctx context.Context, addr string, token string) (*Client, error) if err != nil { return nil, err } - client.closer.register(closer) + client.closer.Register(closer) } return &client, nil diff --git a/client_test.go b/client_test.go index b00aefe..2268a4e 100644 --- a/client_test.go +++ b/client_test.go @@ -127,11 +127,8 @@ func (t *TestSuite) TestRoundTrip() { blobBlob, err := blob.NewBlobV0(namespace, data) t.Require().NoError(err) - com, err := blob.CreateCommitment(blobBlob) - t.Require().NoError(err) - // write blob to DA - height, err := client.Blob.Submit(ctx, []*blob.Blob{blobBlob}, DefaultGasPrice()) + height, err := client.Blob.Submit(ctx, []*blob.Blob{blobBlob}, blob.DefaultGasPrice()) t.Require().NoError(err) t.Require().NotZero(height) @@ -142,7 +139,7 @@ func (t *TestSuite) TestRoundTrip() { t.Require().NoError(err) // retrieve data back from DA - daBlob, err := client.Blob.Get(ctx, height, namespace, com) + daBlob, err := client.Blob.Get(ctx, height, namespace, blobBlob.Commitment) t.Require().NoError(err) t.Require().NotNil(daBlob) t.Equal(data, daBlob.Data) diff --git a/examples/commonuses/main.go b/examples/commonuses/main.go new file mode 100644 index 0000000..171fc9a --- /dev/null +++ b/examples/commonuses/main.go @@ -0,0 +1,120 @@ +package main + +import ( + "bytes" + "context" + "fmt" + + client "github.com/celestiaorg/celestia-openrpc" + "github.com/celestiaorg/celestia-openrpc/types/blob" + "github.com/celestiaorg/celestia-openrpc/types/share" + "github.com/celestiaorg/rsmt2d" +) + +func main() { + ctx := context.Background() + url := "ws://localhost:26658" + token := "" + + err := SubmitBlob(ctx, url, token) + if err != nil { + fmt.Println(err) + } + + eds, err := GetEDS(ctx, url, token, 500) + if err != nil { + fmt.Println(err) + } + fmt.Println(eds.FlattenedODS()) + + SubscribeHeaders(ctx, url, token) +} + +// SubmitBlob submits a blob containing "Hello, World!" to the 0xDEADBEEF namespace. It uses the default signer on the running node. +func SubmitBlob(ctx context.Context, url string, token string) error { + client, err := client.NewClient(ctx, url, token) + if err != nil { + return err + } + + // let's post to 0xDEADBEEF namespace + namespace, err := share.NewBlobNamespaceV0([]byte{0xDE, 0xAD, 0xBE, 0xEF}) + if err != nil { + return err + } + + // create a blob + helloWorldBlob, err := blob.NewBlobV0(namespace, []byte("Hello, World!")) + if err != nil { + return err + } + + // submit the blob to the network + height, err := client.Blob.Submit(ctx, []*blob.Blob{helloWorldBlob}, blob.DefaultGasPrice()) + if err != nil { + return err + } + + fmt.Printf("Blob was included at height %d\n", height) + + // fetch the blob back from the network + retrievedBlobs, err := client.Blob.GetAll(ctx, height, []share.Namespace{namespace}) + if err != nil { + return err + } + + fmt.Printf("Blobs are equal? %v\n", bytes.Equal(helloWorldBlob.Commitment, retrievedBlobs[0].Commitment)) + return nil +} + +// SubscribeHeaders subscribes to new headers and fetches all blobs at the height of the new header in the 0xDEADBEEF namespace. +func SubscribeHeaders(ctx context.Context, url string, token string) error { + client, err := client.NewClient(ctx, url, token) + if err != nil { + return err + } + + // create a namespace to filter blobs with + namespace, err := share.NewBlobNamespaceV0([]byte{0xDE, 0xAD, 0xBE, 0xEF}) + if err != nil { + return err + } + + // subscribe to new headers using a <-chan *header.ExtendedHeader channel + headerChan, err := client.Header.Subscribe(ctx) + if err != nil { + return err + } + + for { + select { + case header := <-headerChan: + // fetch all blobs at the height of the new header + blobs, err := client.Blob.GetAll(context.TODO(), header.Height(), []share.Namespace{namespace}) + if err != nil { + fmt.Printf("Error fetching blobs: %v\n", err) + } + + fmt.Printf("Found %d blobs at height %d in 0xDEADBEEF namespace\n", len(blobs), header.Height()) + case <-ctx.Done(): + return nil + } + } +} + +// GetEDS fetches the EDS at the given height. +func GetEDS(ctx context.Context, url string, token string, height uint64) (*rsmt2d.ExtendedDataSquare, error) { + client, err := client.NewClient(ctx, url, token) + if err != nil { + return nil, err + } + + // First get the header of the block you want to fetch the EDS from + header, err := client.Header.GetByHeight(ctx, height) + if err != nil { + return nil, err + } + + // Fetch the EDS + return client.Share.GetEDS(ctx, header) +} diff --git a/examples/minimalclient/main.go b/examples/minimalclient/main.go new file mode 100644 index 0000000..f734769 --- /dev/null +++ b/examples/minimalclient/main.go @@ -0,0 +1,77 @@ +package main + +import ( + "bytes" + "context" + "fmt" + + "github.com/celestiaorg/celestia-openrpc/types/blob" + "github.com/celestiaorg/celestia-openrpc/types/share" + + clientbuilder "github.com/celestiaorg/celestia-openrpc/builder" +) + +/* + This example demonstrates how to create a client that is only + dependent on the blob and share types from this library. + + This is useful for environments where dependencies should be + kept to a minimum. +*/ + +func main() { + ctx := context.Background() + url := "ws://localhost:26658" + token := "" + + err := SubmitBlob(ctx, url, token) + if err != nil { + fmt.Println(err) + } +} + +const AuthKey = "Authorization" + +type Client struct { + Blob blob.API +} + +// SubmitBlob submits a blob containing "Hello, World!" to the 0xDEADBEEF namespace. It uses the default signer on the running node. +func SubmitBlob(ctx context.Context, url string, token string) error { + var client Client + constructedClient, err := clientbuilder.NewClient(ctx, url, token, client) + if err != nil { + return err + } + + client = constructedClient.(Client) + + // let's post to 0xDEADBEEF namespace + namespace, err := share.NewBlobNamespaceV0([]byte{0xDE, 0xAD, 0xBE, 0xEF}) + if err != nil { + return err + } + + // create a blob + helloWorldBlob, err := blob.NewBlobV0(namespace, []byte("Hello, World!")) + if err != nil { + return err + } + + // submit the blob to the network + height, err := client.Blob.Submit(ctx, []*blob.Blob{helloWorldBlob}, blob.DefaultGasPrice()) + if err != nil { + return err + } + + fmt.Printf("Blob was included at height %d\n", height) + + // fetch the blob back from the network + retrievedBlobs, err := client.Blob.GetAll(ctx, height, []share.Namespace{namespace}) + if err != nil { + return err + } + + fmt.Printf("Blobs are equal? %v\n", bytes.Equal(helloWorldBlob.Commitment, retrievedBlobs[0].Commitment)) + return nil +} diff --git a/go.mod b/go.mod index efd6fd3..802b1de 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/celestiaorg/celestia-openrpc -go 1.21 - -toolchain go1.21.9 +go 1.22.2 require ( cosmossdk.io/math v1.1.2 github.com/celestiaorg/go-fraud v0.2.0 github.com/celestiaorg/go-header v0.4.1 + github.com/celestiaorg/go-square v1.0.1 + github.com/celestiaorg/go-square/merkle v0.0.0-20240429192549-dea967e1533b github.com/celestiaorg/nmt v0.20.0 github.com/celestiaorg/rsmt2d v0.11.0 github.com/cometbft/cometbft v0.37.2 @@ -15,26 +15,26 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/libp2p/go-libp2p v0.30.0 github.com/ory/dockertest/v3 v3.10.0 - github.com/stretchr/testify v1.8.4 - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 + github.com/stretchr/testify v1.9.0 + golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb ) require ( - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/containerd/continuity v0.4.1 // indirect - github.com/cosmos/gogoproto v1.4.11 // indirect + github.com/containerd/continuity v0.3.0 // indirect + github.com/cosmos/gogoproto v1.4.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/docker/cli v24.0.2+incompatible // indirect - github.com/docker/docker v24.0.2+incompatible // indirect + github.com/docker/cli v20.10.17+incompatible // indirect + github.com/docker/docker v20.10.19+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -43,13 +43,11 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect - github.com/imdario/mergo v0.3.16 // indirect + github.com/imdario/mergo v0.3.13 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect @@ -64,7 +62,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/term v0.5.0 // indirect + github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -76,20 +74,20 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect - github.com/opencontainers/runc v1.1.7 // indirect + github.com/opencontainers/runc v1.1.5 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect - github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.opencensus.io v0.23.0 // indirect @@ -98,19 +96,18 @@ require ( go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.25.0 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.14.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 // indirect - google.golang.org/grpc v1.57.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect + google.golang.org/grpc v1.52.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gotest.tools/v3 v3.4.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/go.sum b/go.sum index 5a7eec0..0161fa9 100644 --- a/go.sum +++ b/go.sum @@ -33,12 +33,12 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cosmossdk.io/math v1.1.2 h1:ORZetZCTyWkI5GlZ6CZS28fMHi83ZYf+A2vVnHNzZBM= cosmossdk.io/math v1.1.2/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -53,8 +53,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= +github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= @@ -63,36 +63,46 @@ github.com/celestiaorg/go-fraud v0.2.0 h1:aaq2JiW0gTnhEdac3l51UCqSyJ4+VjFGTTpN83 github.com/celestiaorg/go-fraud v0.2.0/go.mod h1:lNY1i4K6kUeeE60Z2VK8WXd+qXb8KRzfBhvwPkK6aUc= github.com/celestiaorg/go-header v0.4.1 h1:bjbUcKDnhrJJ9EoE7vtPpgleNLVjc2S+cB4/qe8nQmo= github.com/celestiaorg/go-header v0.4.1/go.mod h1:H8xhnDLDLbkpwmWPhCaZyTnIV3dlVxBHPnxNXS2Qu6c= +github.com/celestiaorg/go-square v1.0.1 h1:LEG1zrw4i03VBMElQF8GAbKYgh1bT1uGzWxasU2ePuo= +github.com/celestiaorg/go-square v1.0.1/go.mod h1:XMv5SGCeGSkynW2OOsedugaW/rQlvzxGzWGxTKsyYOU= +github.com/celestiaorg/go-square/merkle v0.0.0-20240429192549-dea967e1533b h1:jo6M4RJnr33sQC/TTraP5gA6ZgbFO/QqzX8e/lIQC7Q= +github.com/celestiaorg/go-square/merkle v0.0.0-20240429192549-dea967e1533b/go.mod h1:86qIYnEhmn/hfW+xvw98NOI3zGaDEB3x8JGjYo2FqLs= github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 h1:CJdIpo8n5MFP2MwK0gSRcOVlDlFdQJO1p+FqdxYzmvc= github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4/go.mod h1:fzuHnhzj1pUygGz+1ZkB3uQbEUL4htqCGJ4Qs2LwMZA= github.com/celestiaorg/nmt v0.20.0 h1:9i7ultZ8Wv5ytt8ZRaxKQ5KOOMo4A2K2T/aPGjIlSas= github.com/celestiaorg/nmt v0.20.0/go.mod h1:Oz15Ub6YPez9uJV0heoU4WpFctxazuIhKyUtaYNio7E= github.com/celestiaorg/rsmt2d v0.11.0 h1:lcto/637WyTEZR3dLRoNvyuExfnUbxvdvKi3qz/2V4k= github.com/celestiaorg/rsmt2d v0.11.0/go.mod h1:6Y580I3gVr0+OVFfW6m2JTwnCCmvW3WfbwSLfuT+HCA= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= -github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= -github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB8= +github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -102,12 +112,13 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM= -github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg= -github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +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/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= +github.com/docker/docker v20.10.19+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.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= @@ -120,6 +131,7 @@ github.com/filecoin-project/go-jsonrpc v0.3.1 h1:qwvAUc5VwAkooquKJmfz9R2+F8znhiq github.com/filecoin-project/go-jsonrpc v0.3.1/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -144,6 +156,8 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -224,13 +238,13 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 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 v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= @@ -265,6 +279,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -309,8 +324,9 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -318,6 +334,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= @@ -347,17 +364,18 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= -github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= -github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -397,17 +415,22 @@ github.com/quic-go/quic-go v0.37.6/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6V github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -415,17 +438,20 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= @@ -470,8 +496,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -482,8 +508,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 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-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= 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= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -505,8 +531,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -537,12 +563,13 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= 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= @@ -561,8 +588,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -573,9 +600,12 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -596,7 +626,6 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -605,13 +634,16 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.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/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= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -621,8 +653,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -637,6 +669,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -668,16 +701,14 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -729,8 +760,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 h1:lv6/DhyiFFGsmzxbsUUTOkN29II+zeWHxvT8Lpdxsv0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 h1:a2S6M0+660BgMNl++4JPlcAO/CjkqYItDEZwkoDQK7c= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -744,8 +775,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -758,8 +789,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -777,10 +809,13 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= -gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= +gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/types/blob/api.go b/types/blob/api.go new file mode 100644 index 0000000..1f9ce53 --- /dev/null +++ b/types/blob/api.go @@ -0,0 +1,23 @@ +package blob + +import ( + "context" + + "github.com/celestiaorg/celestia-openrpc/types/share" +) + +type API struct { + // Submit sends Blobs and reports the height in which they were included. + // Allows sending multiple Blobs atomically synchronously. + // Uses default wallet registered on the Node. + Submit func(context.Context, []*Blob, float64) (uint64, error) `perm:"write"` + // Get retrieves the blob by commitment under the given namespace and height. + Get func(context.Context, uint64, share.Namespace, Commitment) (*Blob, error) `perm:"read"` + // GetAll returns all blobs at the given height under the given namespaces. + GetAll func(context.Context, uint64, []share.Namespace) ([]*Blob, error) `perm:"read"` + // GetProof retrieves proofs in the given namespaces at the given height by commitment. + GetProof func(context.Context, uint64, share.Namespace, Commitment) (*Proof, error) `perm:"read"` + // Included checks whether a blob's given commitment(Merkle subtree root) is included at + // given height and under the namespace. + Included func(context.Context, uint64, share.Namespace, *Proof, Commitment) (bool, error) `perm:"read"` +} diff --git a/types/blob/blob.go b/types/blob/blob.go index 4754ef1..d08085f 100644 --- a/types/blob/blob.go +++ b/types/blob/blob.go @@ -10,6 +10,10 @@ import ( "github.com/celestiaorg/celestia-openrpc/types/appconsts" "github.com/celestiaorg/celestia-openrpc/types/share" + + "github.com/celestiaorg/go-square/blob" + "github.com/celestiaorg/go-square/inclusion" + "github.com/celestiaorg/go-square/merkle" ) const ( @@ -39,10 +43,64 @@ func (com Commitment) Equal(c Commitment) bool { } // Proof is a collection of nmt.Proofs that verifies the inclusion of the data. +// Proof proves the WHOLE namespaced data for the particular row. +// TODO (@vgonkivs): rework `Proof` in order to prove a particular blob. +// https://github.com/celestiaorg/celestia-node/issues/2303 type Proof []*nmt.Proof func (p Proof) Len() int { return len(p) } +// Blob represents any application-specific binary data that anyone can submit to Celestia. +type Blob struct { + blob.Blob `json:"blob"` + + Commitment Commitment `json:"commitment"` + + // the celestia-node's namespace type + // this is to avoid converting to and from app's type + namespace share.Namespace + + // index represents the index of the blob's first share in the EDS. + // Only retrieved, on-chain blobs will have the index set. Default is -1. + index int +} + +// NewBlobV0 constructs a new blob from the provided Namespace and data. +// The blob will be formatted as v0 shares. +func NewBlobV0(namespace share.Namespace, data []byte) (*Blob, error) { + return NewBlob(appconsts.ShareVersionZero, namespace, data) +} + +// NewBlob constructs a new blob from the provided Namespace, data and share version. +func NewBlob(shareVersion uint8, namespace share.Namespace, data []byte) (*Blob, error) { + if len(data) == 0 || len(data) > appconsts.DefaultMaxBytes { + return nil, fmt.Errorf("blob data must be > 0 && <= %d, but it was %d bytes", appconsts.DefaultMaxBytes, len(data)) + } + if err := namespace.ValidateForBlob(); err != nil { + return nil, err + } + + blob := blob.Blob{ + NamespaceId: namespace.ID(), + Data: data, + ShareVersion: uint32(shareVersion), + NamespaceVersion: uint32(namespace.Version()), + } + + com, err := inclusion.CreateCommitment(&blob, merkle.HashFromByteSlices, appconsts.DefaultSubtreeRootThreshold) + if err != nil { + return nil, err + } + //nolint:govet + return &Blob{Blob: blob, Commitment: com, namespace: namespace, index: -1}, nil +} + +// DefaultGasPrice returns the default gas price, letting node automatically +// determine the Fee based on the passed blob sizes. +func DefaultGasPrice() float64 { + return -1.0 +} + type jsonBlob struct { Namespace share.Namespace `json:"namespace"` Data []byte `json:"data"` @@ -51,24 +109,17 @@ type jsonBlob struct { Index int `json:"index"` } -// Blob represents any application-specific binary data that anyone can submit to Celestia. -type Blob struct { - // NOTE: Namespace _must_ include both version and id bytes - Namespace []byte `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - ShareVersion uint32 `protobuf:"varint,3,opt,name=share_version,json=shareVersion,proto3" json:"share_version,omitempty"` - NamespaceVersion uint32 `protobuf:"varint,4,opt,name=namespace_version,json=namespaceVersion,proto3" json:"namespace_version,omitempty"` - Commitment []byte `protobuf:"bytes,5,opt,name=commitment,proto3" json:"commitment,omitempty"` - Index int `protobuf:"varint,6,opt,name=index,proto3" json:"index,omitempty"` -} - func (b *Blob) MarshalJSON() ([]byte, error) { + ns, err := share.NamespaceFromBytes(b.Namespace().Bytes()) + if err != nil { + return nil, err + } blob := &jsonBlob{ - Namespace: b.Namespace, + Namespace: ns, Data: b.Data, ShareVersion: b.ShareVersion, Commitment: b.Commitment, - Index: b.Index, + Index: b.index, } return json.Marshal(blob) } @@ -79,36 +130,13 @@ func (b *Blob) UnmarshalJSON(data []byte) error { if err != nil { return err } - b.NamespaceVersion = uint32(blob.Namespace.Version()) - b.Data = blob.Data - b.ShareVersion = blob.ShareVersion + + b.Blob.NamespaceVersion = uint32(blob.Namespace.Version()) + b.Blob.NamespaceId = blob.Namespace.ID() + b.Blob.Data = blob.Data + b.Blob.ShareVersion = blob.ShareVersion b.Commitment = blob.Commitment - b.Namespace = blob.Namespace - b.Index = blob.Index + b.namespace = blob.Namespace + b.index = blob.Index return nil } - -// NewBlobV0 constructs a new blob from the provided Namespace and data. -// The blob will be formatted as v0 shares. -func NewBlobV0(namespace share.Namespace, data []byte) (*Blob, error) { - return NewBlob(appconsts.ShareVersionZero, namespace, data) -} - -// NewBlob constructs a new blob from the provided Namespace, data and share version. -func NewBlob(shareVersion uint8, namespace share.Namespace, data []byte) (*Blob, error) { - if len(data) == 0 || len(data) > appconsts.DefaultMaxBytes { - return nil, fmt.Errorf("blob data must be > 0 && <= %d, but it was %d bytes", appconsts.DefaultMaxBytes, len(data)) - } - if err := namespace.ValidateForBlob(); err != nil { - return nil, err - } - - return &Blob{ - Namespace: namespace, - Data: data, - ShareVersion: uint32(shareVersion), - NamespaceVersion: 0, - Commitment: []byte{}, - Index: -1, - }, nil -} diff --git a/types/blob/blob_test.go b/types/blob/blob_test.go deleted file mode 100644 index eb95464..0000000 --- a/types/blob/blob_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package blob - -import ( - "bytes" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/celestiaorg/celestia-openrpc/types/appconsts" - appns "github.com/celestiaorg/celestia-openrpc/types/namespace" -) - -func TestBlobMarshalUnmarshal(t *testing.T) { - tests := []struct { - name string - blobJSON string - blob *Blob - }{ - { - "valid blob", - `{"namespace":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAUGBwg=","data":"aGVsbG8gd29ybGQ=","share_version":0,"commitment":"I6VBbcCIpcliy0hYTCLdX13m18ImVdABclJupNGueko=","index":0}`, - &Blob{ - Namespace: append(bytes.Repeat([]byte{0x00}, 21), []byte{1, 2, 3, 4, 5, 6, 7, 8}...), - Data: []byte("hello world"), - ShareVersion: uint32(appconsts.ShareVersionZero), - NamespaceVersion: uint32(appns.NamespaceVersionZero), - Commitment: []byte{0x23, 0xa5, 0x41, 0x6d, 0xc0, 0x88, 0xa5, 0xc9, 0x62, 0xcb, 0x48, 0x58, 0x4c, 0x22, 0xdd, 0x5f, 0x5d, 0xe6, 0xd7, 0xc2, 0x26, 0x55, 0xd0, 0x1, 0x72, 0x52, 0x6e, 0xa4, 0xd1, 0xae, 0x7a, 0x4a}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - blob := &Blob{} - err := blob.UnmarshalJSON([]byte(tt.blobJSON)) - require.NoError(t, err) - - require.Equal(t, tt.blob.ShareVersion, blob.ShareVersion) - require.Equal(t, tt.blob.NamespaceVersion, blob.NamespaceVersion) - require.Equal(t, tt.blob.Namespace, blob.Namespace) - require.Equal(t, tt.blob.Data, blob.Data) - require.Equal(t, tt.blob.Commitment, blob.Commitment) - - blobJSON, err := blob.MarshalJSON() - require.NoError(t, err) - require.Equal(t, tt.blobJSON, string(blobJSON)) - }) - } -} diff --git a/types/blob/commitment.go b/types/blob/commitment.go deleted file mode 100644 index acb5cb5..0000000 --- a/types/blob/commitment.go +++ /dev/null @@ -1,110 +0,0 @@ -package blob - -import ( - "crypto/sha256" - - "github.com/celestiaorg/nmt" - - "github.com/celestiaorg/celestia-openrpc/types/appconsts" - "github.com/celestiaorg/celestia-openrpc/types/share" -) - -// CreateCommitment generates the share commitment for a given blob. -// See [data square layout rationale] and [blob share commitment rules]. -// -// [data square layout rationale]: ../../specs/src/specs/data_square_layout.md -// [blob share commitment rules]: ../../specs/src/specs/data_square_layout.md#blob-share-commitment-rules -// NOTE: We assume Blob.Namespace contains both id and version bytes -func CreateCommitment(blob *Blob) ([]byte, error) { - shares, err := SplitBlobs(*blob) - if err != nil { - return nil, err - } - - // the commitment is the root of a merkle mountain range with max tree size - // determined by the number of roots required to create a share commitment - // over that blob. The size of the tree is only increased if the number of - // subtree roots surpasses a constant threshold. - subTreeWidth := share.SubTreeWidth(len(shares), appconsts.DefaultSubtreeRootThreshold) - treeSizes, err := merkleMountainRangeSizes(uint64(len(shares)), uint64(subTreeWidth)) - if err != nil { - return nil, err - } - leafSets := make([][][]byte, len(treeSizes)) - cursor := uint64(0) - for i, treeSize := range treeSizes { - leafSets[i] = share.ToBytes(shares[cursor : cursor+treeSize]) - cursor = cursor + treeSize - } - - // create the commitments by pushing each leaf set onto an nmt - subTreeRoots := make([][]byte, len(leafSets)) - for i, set := range leafSets { - // create the nmt todo(evan) use nmt wrapper - tree := nmt.New(sha256.New(), nmt.NamespaceIDSize(appconsts.NamespaceSize), nmt.IgnoreMaxNamespace(true)) - for _, leaf := range set { - namespace := blob.Namespace - // the namespace must be added again here even though it is already - // included in the leaf to ensure that the hash will match that of - // the nmt wrapper (pkg/wrapper). Each namespace is added to keep - // the namespace in the share, and therefore the parity data, while - // also allowing for the manual addition of the parity namespace to - // the parity data. - nsLeaf := make([]byte, 0) - nsLeaf = append(nsLeaf, namespace...) - nsLeaf = append(nsLeaf, leaf...) - - err = tree.Push(nsLeaf) - if err != nil { - return nil, err - } - } - // add the root - root, err := tree.Root() - if err != nil { - return nil, err - } - subTreeRoots[i] = root - } - return HashFromByteSlices(subTreeRoots), nil -} - -func CreateCommitments(blobs []*Blob) ([][]byte, error) { - commitments := make([][]byte, len(blobs)) - for i, blob := range blobs { - commitment, err := CreateCommitment(blob) - if err != nil { - return nil, err - } - commitments[i] = commitment - } - return commitments, nil -} - -// merkleMountainRangeSizes returns the sizes (number of leaf nodes) of the -// trees in a merkle mountain range constructed for a given totalSize and -// maxTreeSize. -// -// https://docs.grin.mw/wiki/chain-state/merkle-mountain-range/ -// https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md -// TODO: potentially rename function because this doesn't return heights -func merkleMountainRangeSizes(totalSize, maxTreeSize uint64) ([]uint64, error) { - var treeSizes []uint64 - - for totalSize != 0 { - switch { - case totalSize >= maxTreeSize: - treeSizes = append(treeSizes, maxTreeSize) - totalSize = totalSize - maxTreeSize - case totalSize < maxTreeSize: - treeSize, err := share.RoundDownPowerOfTwo(totalSize) - if err != nil { - return treeSizes, err - } - treeSizes = append(treeSizes, treeSize) - totalSize = totalSize - treeSize - } - } - - return treeSizes, nil -} diff --git a/types/blob/merkle.go b/types/blob/merkle.go deleted file mode 100644 index bdc4f69..0000000 --- a/types/blob/merkle.go +++ /dev/null @@ -1,188 +0,0 @@ -package blob - -import ( - "crypto/sha256" - "hash" - "math/bits" -) - -const ( - Size = sha256.Size - BlockSize = sha256.BlockSize -) - -// New returns a new hash.Hash. -func New() hash.Hash { - return sha256.New() -} - -// Sum returns the SHA256 of the bz. -func Sum(bz []byte) []byte { - h := sha256.Sum256(bz) - return h[:] -} - -//------------------------------------------------------------- - -const ( - TruncatedSize = 20 -) - -type sha256trunc struct { - sha256 hash.Hash -} - -func (h sha256trunc) Write(p []byte) (n int, err error) { - return h.sha256.Write(p) -} -func (h sha256trunc) Sum(b []byte) []byte { - shasum := h.sha256.Sum(b) - return shasum[:TruncatedSize] -} - -func (h sha256trunc) Reset() { - h.sha256.Reset() -} - -func (h sha256trunc) Size() int { - return TruncatedSize -} - -func (h sha256trunc) BlockSize() int { - return h.sha256.BlockSize() -} - -// NewTruncated returns a new hash.Hash. -func NewTruncated() hash.Hash { - return sha256trunc{ - sha256: sha256.New(), - } -} - -// SumTruncated returns the first 20 bytes of SHA256 of the bz. -func SumTruncated(bz []byte) []byte { - hash := sha256.Sum256(bz) - return hash[:TruncatedSize] -} - -// TODO: make these have a large predefined capacity -var ( - leafPrefix = []byte{0} - innerPrefix = []byte{1} -) - -// returns tmhash() -func emptyHash() []byte { - return Sum([]byte{}) -} - -// returns tmhash(0x00 || leaf) -func leafHash(leaf []byte) []byte { - return Sum(append(leafPrefix, leaf...)) -} - -// returns tmhash(0x01 || left || right) -func innerHash(left []byte, right []byte) []byte { - return Sum(append(innerPrefix, append(left, right...)...)) -} - -// HashFromByteSlices computes a Merkle tree where the leaves are the byte slice, -// in the provided order. It follows RFC-6962. -func HashFromByteSlices(items [][]byte) []byte { - switch len(items) { - case 0: - return emptyHash() - case 1: - return leafHash(items[0]) - default: - k := getSplitPoint(int64(len(items))) - left := HashFromByteSlices(items[:k]) - right := HashFromByteSlices(items[k:]) - return innerHash(left, right) - } -} - -// HashFromByteSliceIterative is an iterative alternative to -// HashFromByteSlice motivated by potential performance improvements. -// (#2611) had suggested that an iterative version of -// HashFromByteSlice would be faster, presumably because -// we can envision some overhead accumulating from stack -// frames and function calls. Additionally, a recursive algorithm risks -// hitting the stack limit and causing a stack overflow should the tree -// be too large. -// -// Provided here is an iterative alternative, a test to assert -// correctness and a benchmark. On the performance side, there appears to -// be no overall difference: -// -// BenchmarkHashAlternatives/recursive-4 20000 77677 ns/op -// BenchmarkHashAlternatives/iterative-4 20000 76802 ns/op -// -// On the surface it might seem that the additional overhead is due to -// the different allocation patterns of the implementations. The recursive -// version uses a single [][]byte slices which it then re-slices at each level of the tree. -// The iterative version reproduces [][]byte once within the function and -// then rewrites sub-slices of that array at each level of the tree. -// -// Experimenting by modifying the code to simply calculate the -// hash and not store the result show little to no difference in performance. -// -// These preliminary results suggest: -// -// 1. The performance of the HashFromByteSlice is pretty good -// 2. Go has low overhead for recursive functions -// 3. The performance of the HashFromByteSlice routine is dominated -// by the actual hashing of data -// -// Although this work is in no way exhaustive, point #3 suggests that -// optimization of this routine would need to take an alternative -// approach to make significant improvements on the current performance. -// -// Finally, considering that the recursive implementation is easier to -// read, it might not be worthwhile to switch to a less intuitive -// implementation for so little benefit. -func HashFromByteSlicesIterative(input [][]byte) []byte { - items := make([][]byte, len(input)) - - for i, leaf := range input { - items[i] = leafHash(leaf) - } - - size := len(items) - for { - switch size { - case 0: - return emptyHash() - case 1: - return items[0] - default: - rp := 0 // read position - wp := 0 // write position - for rp < size { - if rp+1 < size { - items[wp] = innerHash(items[rp], items[rp+1]) - rp += 2 - } else { - items[wp] = items[rp] - rp++ - } - wp++ - } - size = wp - } - } -} - -// getSplitPoint returns the largest power of 2 less than length -func getSplitPoint(length int64) int64 { - if length < 1 { - panic("Trying to split a tree with size < 1") - } - uLength := uint(length) - bitlen := bits.Len(uLength) - k := int64(1 << uint(bitlen-1)) - if k == length { - k >>= 1 - } - return k -} diff --git a/types/blob/share_splitting.go b/types/blob/share_splitting.go deleted file mode 100644 index 34a25c6..0000000 --- a/types/blob/share_splitting.go +++ /dev/null @@ -1,14 +0,0 @@ -package blob - -import "github.com/celestiaorg/celestia-openrpc/types/share" - -// SplitBlobs splits the provided blobs into shares. -func SplitBlobs(blobs ...Blob) ([]share.Share, error) { - writer := share.NewSparseShareSplitter() - for _, blob := range blobs { - if err := writer.Write(blob.NamespaceVersion, blob.Namespace, blob.Data); err != nil { - return nil, err - } - } - return writer.Export(), nil -} diff --git a/types/da/api.go b/types/da/api.go new file mode 100644 index 0000000..f98f0bd --- /dev/null +++ b/types/da/api.go @@ -0,0 +1,46 @@ +package da + +import ( + "context" +) + +// Namespace is an optional parameter used to set the location a blob should be +// posted to, for DA layers supporting the functionality. +type Namespace = []byte + +// Blob is the data submitted/received from DA interface. +type Blob = []byte + +// ID should contain serialized data required by the implementation to find blob in Data Availability layer. +type ID = []byte + +// Commitment should contain serialized cryptographic commitment to Blob value. +type Commitment = []byte + +// Proof should contain serialized proof of inclusion (publication) of Blob in Data Availability layer. +type Proof = []byte + +// Cannot import https://github.com/celestiaorg/go-da until there is more support for go 1.21 +// The copied version represents go-da v0.4.0 +type API struct { + // MaxBlobSize returns the max blob size + MaxBlobSize func(ctx context.Context) (uint64, error) `perm:"read"` + // Get returns Blob for each given ID, or an error. + // + // Error should be returned if ID is not formatted properly, there is no Blob for given ID or any other client-level + // error occurred (dropped connection, timeout, etc). + Get func(ctx context.Context, ids []ID, ns Namespace) ([]Blob, error) `perm:"read"` + // GetIDs returns IDs of all Blobs located in DA at given height. + GetIDs func(ctx context.Context, height uint64, ns Namespace) ([]ID, error) `perm:"read"` + // GetProofs returns inclusion Proofs for all Blobs located in DA at given height. + GetProofs func(ctx context.Context, ids []ID, ns Namespace) ([]Proof, error) `perm:"read"` + // Commit creates a Commitment for each given Blob. + Commit func(ctx context.Context, blobs []Blob, ns Namespace) ([]Commitment, error) `perm:"read"` + // Validate validates Commitments against the corresponding Proofs. This should be possible without retrieving the Blobs. + Validate func(ctx context.Context, ids []ID, proofs []Proof, ns Namespace) ([]bool, error) `perm:"read"` + // Submit submits the Blobs to Data Availability layer. + // + // This method is synchronous. Upon successful submission to Data Availability layer, it returns the IDs identifying blobs + // in DA. + Submit func(ctx context.Context, blobs []Blob, gasPrice float64, ns Namespace) ([]ID, error) `perm:"write"` +} diff --git a/types/das/api.go b/types/das/api.go new file mode 100644 index 0000000..133c6d8 --- /dev/null +++ b/types/das/api.go @@ -0,0 +1,8 @@ +package das + +import "context" + +type API struct { + SamplingStats func(ctx context.Context) (SamplingStats, error) `perm:"read"` + WaitCatchUp func(ctx context.Context) error `perm:"read"` +} diff --git a/types/fraud/api.go b/types/fraud/api.go new file mode 100644 index 0000000..a1e31a1 --- /dev/null +++ b/types/fraud/api.go @@ -0,0 +1,14 @@ +package fraud + +import ( + "context" + + "github.com/celestiaorg/go-fraud" +) + +type API struct { + // Subscribe allows to subscribe on a Proof pub sub topic by its type. + Subscribe func(context.Context, fraud.ProofType) (<-chan *Proof, error) `perm:"read"` + // Get fetches fraud proofs from the disk by its type. + Get func(context.Context, fraud.ProofType) ([]Proof, error) `perm:"read"` +} diff --git a/types/fraud/proof.go b/types/fraud/proof.go new file mode 100644 index 0000000..1a42740 --- /dev/null +++ b/types/fraud/proof.go @@ -0,0 +1,11 @@ +package fraud + +import ( + "github.com/celestiaorg/celestia-openrpc/types/header" + "github.com/celestiaorg/go-fraud" +) + +// Proof embeds the fraud.Proof interface type to provide a concrete type for JSON serialization. +type Proof struct { + fraud.Proof[*header.ExtendedHeader] +} diff --git a/types/header/api.go b/types/header/api.go new file mode 100644 index 0000000..75a6c49 --- /dev/null +++ b/types/header/api.go @@ -0,0 +1,40 @@ +package header + +import ( + "context" + + libhead "github.com/celestiaorg/go-header" + "github.com/celestiaorg/go-header/sync" +) + +type API struct { + // LocalHead returns the ExtendedHeader of the chain head. + LocalHead func(context.Context) (*ExtendedHeader, error) `perm:"read"` + // GetByHash returns the header of the given hash from the node's header store. + GetByHash func( + ctx context.Context, + hash libhead.Hash, + ) (*ExtendedHeader, error) `perm:"read"` + // GetRangeByHeight returns the given range (from:to) of ExtendedHeaders + // from the node's header store and verifies that the returned headers are + // adjacent to each other. + GetRangeByHeight func( + context.Context, + *ExtendedHeader, + uint64, + ) ([]*ExtendedHeader, error) `perm:"read"` + // GetByHeight returns the ExtendedHeader at the given height if it is + // currently available. + GetByHeight func(context.Context, uint64) (*ExtendedHeader, error) `perm:"read"` + // WaitForHeight blocks until the header at the given height has been processed + // by the store or context deadline is exceeded. + WaitForHeight func(context.Context, uint64) (*ExtendedHeader, error) `perm:"read"` + // SyncState returns the current state of the header Syncer. + SyncState func(ctx context.Context) (sync.State, error) `perm:"read"` + // SyncWait blocks until the header Syncer is synced to network head. + SyncWait func(ctx context.Context) error `perm:"read"` + // NetworkHead provides the Syncer's view of the current network head. + NetworkHead func(ctx context.Context) (*ExtendedHeader, error) `perm:"read"` + // Subscribe to recent ExtendedHeaders from the network. + Subscribe func(ctx context.Context) (<-chan *ExtendedHeader, error) `perm:"read"` +} diff --git a/types/node/api.go b/types/node/api.go new file mode 100644 index 0000000..f8336bc --- /dev/null +++ b/types/node/api.go @@ -0,0 +1,20 @@ +package node + +import ( + "context" + + "github.com/filecoin-project/go-jsonrpc/auth" +) + +type API struct { + // Info returns administrative information about the node. + Info func(context.Context) (Info, error) `perm:"admin"` + // Ready returns true once the node's RPC is ready to accept requests. + Ready func(context.Context) (bool, error) `perm:"read"` + // LogLevelSet sets the given component log level to the given level. + LogLevelSet func(ctx context.Context, name, level string) error `perm:"admin"` + // AuthVerify returns the permissions assigned to the given token. + AuthVerify func(ctx context.Context, token string) ([]auth.Permission, error) `perm:"admin"` + // AuthNew signs and returns a new token with the given permissions. + AuthNew func(ctx context.Context, perms []auth.Permission) ([]byte, error) `perm:"admin"` +} diff --git a/types/p2p/api.go b/types/p2p/api.go new file mode 100644 index 0000000..0b01cf9 --- /dev/null +++ b/types/p2p/api.go @@ -0,0 +1,62 @@ +package p2p + +import ( + "context" + + "github.com/libp2p/go-libp2p/core/metrics" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" +) + +type API struct { + // Info returns address information about the host. + Info func(context.Context) (peer.AddrInfo, error) `perm:"admin"` + // Peers returns connected peers. + Peers func(context.Context) ([]peer.ID, error) `perm:"admin"` + // PeerInfo returns a small slice of information Peerstore has on the + // given peer. + PeerInfo func(ctx context.Context, id peer.ID) (peer.AddrInfo, error) `perm:"admin"` + // Connect ensures there is a connection between this host and the peer with + // given peer. + Connect func(ctx context.Context, pi peer.AddrInfo) error `perm:"admin"` + // ClosePeer closes the connection to a given peer. + ClosePeer func(ctx context.Context, id peer.ID) error `perm:"admin"` + // Connectedness returns a state signaling connection capabilities. + Connectedness func(ctx context.Context, id peer.ID) (network.Connectedness, error) `perm:"admin"` + // NATStatus returns the current NAT status. + NATStatus func(context.Context) (network.Reachability, error) `perm:"admin"` + // BlockPeer adds a peer to the set of blocked peers. + BlockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` + // UnblockPeer removes a peer from the set of blocked peers. + UnblockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` + // ListBlockedPeers returns a list of blocked peers. + ListBlockedPeers func(context.Context) ([]peer.ID, error) `perm:"admin"` + // Protect adds a peer to the list of peers who have a bidirectional + // peering agreement that they are protected from being trimmed, dropped + // or negatively scored. + Protect func(ctx context.Context, id peer.ID, tag string) error `perm:"admin"` + // Unprotect removes a peer from the list of peers who have a bidirectional + // peering agreement that they are protected from being trimmed, dropped + // or negatively scored, returning a bool representing whether the given + // peer is protected or not. + Unprotect func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` + // IsProtected returns whether the given peer is protected. + IsProtected func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` + // BandwidthStats returns a Stats struct with bandwidth metrics for all + // data sent/received by the local peer, regardless of protocol or remote + // peer IDs. + BandwidthStats func(context.Context) (metrics.Stats, error) `perm:"admin"` + // BandwidthForPeer returns a Stats struct with bandwidth metrics associated with the given peer.ID. + // The metrics returned include all traffic sent / received for the peer, regardless of protocol. + BandwidthForPeer func(ctx context.Context, id peer.ID) (metrics.Stats, error) `perm:"admin"` + // BandwidthForProtocol returns a Stats struct with bandwidth metrics associated with the given + // protocol.ID. + BandwidthForProtocol func(ctx context.Context, proto protocol.ID) (metrics.Stats, error) `perm:"admin"` + // ResourceState returns the state of the resource manager. + ResourceState func(context.Context) (rcmgr.ResourceManagerStat, error) `perm:"admin"` + // PubSubPeers returns the peer IDs of the peers joined on + // the given topic. + PubSubPeers func(ctx context.Context, topic string) ([]peer.ID, error) `perm:"admin"` +} diff --git a/types/share/api.go b/types/share/api.go new file mode 100644 index 0000000..afd31e7 --- /dev/null +++ b/types/share/api.go @@ -0,0 +1,26 @@ +package share + +import ( + "context" + + "github.com/celestiaorg/celestia-openrpc/types/header" + "github.com/celestiaorg/rsmt2d" +) + +type API struct { + SharesAvailable func(context.Context, *header.ExtendedHeader) error `perm:"read"` + GetShare func( + ctx context.Context, + eh *header.ExtendedHeader, + row, col int, + ) (Share, error) `perm:"read"` + GetEDS func( + ctx context.Context, + eh *header.ExtendedHeader, + ) (*rsmt2d.ExtendedDataSquare, error) `perm:"read"` + GetSharesByNamespace func( + ctx context.Context, + eh *header.ExtendedHeader, + namespace Namespace, + ) (NamespacedShares, error) `perm:"read"` +} diff --git a/types/state/api.go b/types/state/api.go new file mode 100644 index 0000000..061c591 --- /dev/null +++ b/types/state/api.go @@ -0,0 +1,107 @@ +package state + +import ( + "context" + + "github.com/celestiaorg/celestia-openrpc/types/blob" +) + +type API struct { + // AccountAddress retrieves the address of the node's account/signer + AccountAddress func(ctx context.Context) (Address, error) `perm:"read"` + // Balance retrieves the Celestia coin balance for the node's account/signer + // and verifies it against the corresponding block's AppHash. + Balance func(ctx context.Context) (*Balance, error) `perm:"read"` + // BalanceForAddress retrieves the Celestia coin balance for the given address and verifies + // the returned balance against the corresponding block's AppHash. + // + // NOTE: the balance returned is the balance reported by the block right before + // the node's current head (head-1). This is due to the fact that for block N, the block's + // `AppHash` is the result of applying the previous block's transaction list. + BalanceForAddress func(ctx context.Context, addr Address) (*Balance, error) `perm:"read"` + // Transfer sends the given amount of coins from default wallet of the node to the given account + // address. + Transfer func( + ctx context.Context, + to AccAddress, + amount, + fee Int, + gasLimit uint64, + ) (*TxResponse, error) `perm:"write"` + // SubmitTx submits the given transaction/message to the + // Celestia network and blocks until the tx is included in + // a block. + SubmitTx func(ctx context.Context, tx Tx) (*TxResponse, error) `perm:"read"` + // SubmitPayForBlob builds, signs and submits a PayForBlob transaction. + SubmitPayForBlob func( + ctx context.Context, + fee Int, + gasLim uint64, + blobs []*blob.Blob, + ) (*TxResponse, error) `perm:"write"` + // CancelUnbondingDelegation cancels a user's pending undelegation from a validator. + CancelUnbondingDelegation func( + ctx context.Context, + valAddr ValAddress, + amount, + height, + fee Int, + gasLim uint64, + ) (*TxResponse, error) `perm:"write"` + // BeginRedelegate sends a user's delegated tokens to a new validator for redelegation. + BeginRedelegate func( + ctx context.Context, + srcValAddr, + dstValAddr ValAddress, + amount, + fee Int, + gasLim uint64, + ) (*TxResponse, error) `perm:"write"` + // Undelegate undelegates a user's delegated tokens, unbonding them from the current validator. + Undelegate func( + ctx context.Context, + delAddr ValAddress, + amount, + fee Int, + gasLim uint64, + ) (*TxResponse, error) `perm:"write"` + // Delegate sends a user's liquid tokens to a validator for delegation. + Delegate func( + ctx context.Context, + delAddr ValAddress, + amount, + fee Int, + gasLim uint64, + ) (*TxResponse, error) `perm:"write"` + // QueryDelegation retrieves the delegation information between a delegator and a validator. + QueryDelegation func( + ctx context.Context, + valAddr ValAddress, + ) (*QueryDelegationResponse, error) `perm:"read"` + // QueryUnbonding retrieves the unbonding status between a delegator and a validator. + QueryUnbonding func( + ctx context.Context, + valAddr ValAddress, + ) (*QueryUnbondingDelegationResponse, error) `perm:"read"` + // QueryRedelegations retrieves the status of the redelegations between a delegator and a validator. + QueryRedelegations func( + ctx context.Context, + srcValAddr, + dstValAddr ValAddress, + ) (*QueryRedelegationsResponse, error) `perm:"read"` + // GrantFee grants the given amount of fee to the given grantee. + GrantFee func( + ctx context.Context, + grantee AccAddress, + amount, + fee Int, + gasLim uint64, + ) (*TxResponse, error) `perm:"write"` + // RevokeGrantFee revokes the given amount of fee from the given grantee. + RevokeGrantFee func( + ctx context.Context, + grantee AccAddress, + fee Int, + gasLim uint64, + ) (*TxResponse, error) `perm:"write"` +}