From d3100e01b46dfc31289486c0582d0143d084ed1c Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 16 May 2024 16:08:10 +0200 Subject: [PATCH] feat!: modularize client and upgrade to node v0.13.4 (#117) This PR gives celestia-openrpc parity with the latest celestia-node version. It also modularizes the project, so that users can create clients without needing to report all modules. This is good for integrations where the codebase wants to minimize dependencies and we only need blob module for example. In addition, I have updated the README and added examples in the `examples/` directory. A workflow is added that tests the equivalence between node and celestia-openrpc. This workflow can be set as a requirement once the test in node is merged and released: https://github.com/celestiaorg/celestia-node/pull/3405 Note: We must release ASAP, otherwise the new code examples inside of the golang client tutorial will not work --- .github/workflows/ci_release.yml | 6 + .github/workflows/test-equivalence.yml | 27 ++++ README.md | 66 ++++++++- api.go | 184 ------------------------ builder/client.go | 51 +++++++ client.go | 52 ++++--- client_test.go | 7 +- examples/commonuses/main.go | 120 ++++++++++++++++ examples/minimalclient/main.go | 77 ++++++++++ go.mod | 65 ++++----- go.sum | 163 ++++++++++++--------- types/blob/api.go | 23 +++ types/blob/blob.go | 114 +++++++++------ types/blob/blob_test.go | 48 ------- types/blob/commitment.go | 110 --------------- types/blob/merkle.go | 188 ------------------------- types/blob/share_splitting.go | 14 -- types/da/api.go | 46 ++++++ types/das/api.go | 8 ++ types/fraud/api.go | 14 ++ types/fraud/proof.go | 11 ++ types/header/api.go | 40 ++++++ types/node/api.go | 20 +++ types/p2p/api.go | 62 ++++++++ types/share/api.go | 26 ++++ types/state/api.go | 107 ++++++++++++++ 26 files changed, 929 insertions(+), 720 deletions(-) create mode 100644 .github/workflows/test-equivalence.yml delete mode 100644 api.go create mode 100644 builder/client.go create mode 100644 examples/commonuses/main.go create mode 100644 examples/minimalclient/main.go create mode 100644 types/blob/api.go delete mode 100644 types/blob/blob_test.go delete mode 100644 types/blob/commitment.go delete mode 100644 types/blob/merkle.go delete mode 100644 types/blob/share_splitting.go create mode 100644 types/da/api.go create mode 100644 types/das/api.go create mode 100644 types/fraud/api.go create mode 100644 types/fraud/proof.go create mode 100644 types/header/api.go create mode 100644 types/node/api.go create mode 100644 types/p2p/api.go create mode 100644 types/share/api.go create mode 100644 types/state/api.go 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"` +}