From c68e6a12e08a2cf1c430425d05d93b702aa99404 Mon Sep 17 00:00:00 2001 From: Alexandr Burdiyan Date: Mon, 18 Sep 2023 11:18:18 +0200 Subject: [PATCH] Decode dagpb blobs --- backend/hyper/entity.go | 2 +- backend/hyper/entity_test.go | 1 - backend/hyper/hyper.go | 164 ++++++++++++++++++++++++----------- backend/hyper/indexing.go | 40 +++++---- backend/hyper/terra.go | 2 +- backend/syncing/syncing.go | 4 +- go.mod | 14 +-- go.sum | 28 +++--- 8 files changed, 162 insertions(+), 93 deletions(-) diff --git a/backend/hyper/entity.go b/backend/hyper/entity.go index b577c91134..0bf6fbe38e 100644 --- a/backend/hyper/entity.go +++ b/backend/hyper/entity.go @@ -307,7 +307,7 @@ func NewChange(eid EntityID, deps []cid.Cid, ts hlc.Time, signer core.KeyPair, d return hb, fmt.Errorf("failed to sign change: %w", err) } - hb, err = EncodeBlob(ch.Type, ch) + hb, err = EncodeBlob(ch) if err != nil { return hb, err } diff --git a/backend/hyper/entity_test.go b/backend/hyper/entity_test.go index 37dad76dff..7f3b2eb0f3 100644 --- a/backend/hyper/entity_test.go +++ b/backend/hyper/entity_test.go @@ -27,7 +27,6 @@ func TestEntity(t *testing.T) { }) require.NoError(t, err) - require.Equal(t, TypeChange, ch.Type) require.Nil(t, ch.Decoded.(Change).Deps) name, _ = e.Get("name") diff --git a/backend/hyper/hyper.go b/backend/hyper/hyper.go index 64595f78e9..54aa62dfa2 100644 --- a/backend/hyper/hyper.go +++ b/backend/hyper/hyper.go @@ -15,8 +15,8 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" cbornode "github.com/ipfs/go-ipld-cbor" + dagpb "github.com/ipld/go-codec-dagpb" "github.com/multiformats/go-multicodec" - "github.com/multiformats/go-multihash" "go.uber.org/zap" ) @@ -26,16 +26,27 @@ type BlobType string // Storage is an indexing blob storage. type Storage struct { db *sqlitex.Pool - bs *blockStore + bs *indexingBlockStore log *zap.Logger + + *indexer } // NewStorage creates a new blob storage. func NewStorage(db *sqlitex.Pool, log *zap.Logger) *Storage { - return &Storage{ + bs := newBlockstore(db) + + idx := &indexer{ db: db, - bs: newBlockstore(db), log: log, + bs: bs, + } + + return &Storage{ + db: db, + bs: &indexingBlockStore{blockStore: bs, indexBlob: idx.indexBlob}, + log: log, + indexer: idx, } } @@ -70,8 +81,10 @@ func (bs *Storage) SaveBlob(ctx context.Context, blob Blob) error { } defer release() + codec, hash := ipfs.DecodeCID(blob.CID) + return sqlitex.WithTx(conn, func() error { - id, exists, err := bs.bs.putBlock(conn, 0, uint64(blob.Codec), blob.Hash, blob.Data) + id, exists, err := bs.bs.putBlock(conn, 0, uint64(codec), hash, blob.Data) if err != nil { return err } @@ -81,7 +94,7 @@ func (bs *Storage) SaveBlob(ctx context.Context, blob Blob) error { return nil } - if err := bs.indexBlob(conn, id, blob); err != nil { + if err := bs.indexBlob(conn, id, blob.CID, blob.Decoded); err != nil { return fmt.Errorf("failed to index blob %s: %w", blob.CID, err) } @@ -122,8 +135,10 @@ func (bs *Storage) SaveDraftBlob(ctx context.Context, eid EntityID, blob Blob) e } defer release() + codec, hash := ipfs.DecodeCID(blob.CID) + return sqlitex.WithTx(conn, func() error { - id, exists, err := bs.bs.putBlock(conn, 0, uint64(blob.Codec), blob.Hash, blob.Data) + id, exists, err := bs.bs.putBlock(conn, 0, uint64(codec), hash, blob.Data) if err != nil { return err } @@ -133,7 +148,7 @@ func (bs *Storage) SaveDraftBlob(ctx context.Context, eid EntityID, blob Blob) e return nil } - if err := bs.indexBlob(conn, id, blob); err != nil { + if err := bs.indexBlob(conn, id, blob.CID, blob.Decoded); err != nil { return fmt.Errorf("failed to index blob %s: %w", blob.CID, err) } @@ -283,7 +298,9 @@ func (bs *Storage) ReplaceDraftBlob(ctx context.Context, eid EntityID, old cid.C return err } - id, exists, err := bs.bs.putBlock(conn, oldid, uint64(blob.Codec), blob.Hash, blob.Data) + codec, hash := ipfs.DecodeCID(blob.CID) + + id, exists, err := bs.bs.putBlock(conn, oldid, uint64(codec), hash, blob.Data) if err != nil { return fmt.Errorf("replace draft blob error when insert: %w", err) } @@ -293,7 +310,7 @@ func (bs *Storage) ReplaceDraftBlob(ctx context.Context, eid EntityID, old cid.C return nil } - if err := bs.indexBlob(conn, id, blob); err != nil { + if err := bs.indexBlob(conn, id, blob.CID, blob.Decoded); err != nil { return fmt.Errorf("failed to index blob %s: %w", blob.CID, err) } @@ -343,31 +360,23 @@ func (bs *Storage) IPFSBlockstore() blockstore.Blockstore { // Blob is a structural artifact. type Blob struct { - Type BlobType CID cid.Cid - Codec multicodec.Code - Hash multihash.Multihash Data []byte Decoded any } // EncodeBlob produces a Blob from any object. -func EncodeBlob(t BlobType, v any) (hb Blob, err error) { +func EncodeBlob(v any) (hb Blob, err error) { data, err := cbornode.DumpObject(v) if err != nil { - return hb, fmt.Errorf("failed to encode blob with type %s: %w", t, err) + return hb, fmt.Errorf("failed to encode blob %T: %w", v, err) } - codec := multicodec.DagCbor - - blk := ipfs.NewBlock(uint64(codec), data) + blk := ipfs.NewBlock(uint64(multicodec.DagCbor), data) c := blk.Cid() return Blob{ - Type: t, CID: c, - Codec: codec, - Hash: c.Hash(), Data: data, Decoded: v, }, nil @@ -379,44 +388,99 @@ var errNotHyperBlob = errors.New("not a hyper blob") func DecodeBlob(c cid.Cid, data []byte) (hb Blob, err error) { codec := c.Prefix().Codec - if codec != uint64(multicodec.DagCbor) { - return hb, fmt.Errorf("%s: %w", c, errNotHyperBlob) - } - - var v struct { - Type string `cbor:"@type"` - } - if err := cbor.Unmarshal(data, &v); err != nil { - var vv any - if err := cbornode.DecodeInto(data, &vv); err != nil { - panic(err) + switch multicodec.Code(codec) { + case multicodec.DagPb: + b := dagpb.Type.PBNode.NewBuilder() + if err := dagpb.DecodeBytes(b, data); err != nil { + return hb, fmt.Errorf("failed to decode dagpb node %s: %w", c, err) } - return hb, fmt.Errorf("failed to infer hyper blob %s: %w", c, err) - } - - switch BlobType(v.Type) { - case TypeKeyDelegation: - var v KeyDelegation - if err := cbornode.DecodeInto(data, &v); err != nil { - return hb, err + hb.Decoded = b.Build() + case multicodec.DagCbor: + var v struct { + Type string `cbor:"@type"` } - hb.Decoded = v - case TypeChange: - var v Change - if err := cbornode.DecodeInto(data, &v); err != nil { - return hb, err + if err := cbor.Unmarshal(data, &v); err != nil { + return hb, fmt.Errorf("failed to infer hyper blob %s: %w", c, err) + } + + switch BlobType(v.Type) { + case TypeKeyDelegation: + var v KeyDelegation + if err := cbornode.DecodeInto(data, &v); err != nil { + return hb, err + } + hb.Decoded = v + case TypeChange: + var v Change + if err := cbornode.DecodeInto(data, &v); err != nil { + return hb, err + } + hb.Decoded = v + default: + return hb, fmt.Errorf("unknown hyper blob type: '%s'", v.Type) } - hb.Decoded = v default: - return hb, fmt.Errorf("unknown hyper blob type: '%s'", v.Type) + return hb, fmt.Errorf("%s: %w", c, errNotHyperBlob) } - hb.Type = BlobType(v.Type) hb.CID = c - hb.Codec = multicodec.Code(codec) - hb.Hash = c.Hash() hb.Data = data return hb, nil } + +type indexingBlockStore struct { + *blockStore + indexBlob func(conn *sqlite.Conn, id int64, c cid.Cid, blob any) error +} + +func (b *indexingBlockStore) Put(ctx context.Context, block blocks.Block) error { + // conn, release, err := b.db.Conn(ctx) + // if err != nil { + // return err + // } + // defer release() + + // return sqlitex.WithTx(conn, func() error { + // codec, hash := ipfs.DecodeCID(block.Cid()) + // id, exists, err := b.putBlock(conn, 0, codec, hash, block.RawData()) + // if err != nil { + // return err + // } + + // if exists { + // return nil + // } + + // hb, err := DecodeBlob(block.Cid(), block.RawData()) + // if err != nil { + // return err + // } + + // return b.indexBlob(conn, id, hb.CID, hb.Decoded) + // }) + + return b.blockStore.Put(ctx, block) +} + +// PutMany implements blockstore.Blockstore interface. +func (b *indexingBlockStore) PutMany(ctx context.Context, blocks []blocks.Block) error { + // conn, release, err := b.db.Conn(ctx) + // if err != nil { + // return err + // } + // defer release() + + // return sqlitex.WithTx(conn, func() error { + // for _, blk := range blocks { + // codec, hash := ipfs.DecodeCID(blk.Cid()) + // if _, _, err := b.putBlock(conn, 0, codec, hash, blk.RawData()); err != nil { + // return err + // } + // } + // return nil + // }) + + return b.blockStore.PutMany(ctx, blocks) +} diff --git a/backend/hyper/indexing.go b/backend/hyper/indexing.go index 4a2834d039..9da29a17ec 100644 --- a/backend/hyper/indexing.go +++ b/backend/hyper/indexing.go @@ -24,8 +24,14 @@ import ( "google.golang.org/protobuf/encoding/protojson" ) +type indexer struct { + db *sqlitex.Pool + log *zap.Logger + bs *blockStore +} + // Reindex forces deletes all the information derived from the blobs and reindexes them. -func (bs *Storage) Reindex(ctx context.Context) (err error) { +func (bs *indexer) Reindex(ctx context.Context) (err error) { conn, release, err := bs.db.Conn(ctx) if err != nil { return err @@ -35,7 +41,7 @@ func (bs *Storage) Reindex(ctx context.Context) (err error) { return bs.reindex(conn) } -func (bs *Storage) reindex(conn *sqlite.Conn) (err error) { +func (bs *indexer) reindex(conn *sqlite.Conn) (err error) { start := time.Now() bs.log.Debug("ReindexingStarted") defer func() { @@ -85,7 +91,7 @@ func (bs *Storage) reindex(conn *sqlite.Conn) (err error) { return nil } - return bs.indexBlob(conn, id, hb) + return bs.indexBlob(conn, id, hb.CID, hb.Decoded) }); err != nil { return err } @@ -99,7 +105,7 @@ func (bs *Storage) reindex(conn *sqlite.Conn) (err error) { } // MaybeReindex will trigger reindexing if it's needed. -func (bs *Storage) MaybeReindex(ctx context.Context) error { +func (bs *indexer) MaybeReindex(ctx context.Context) error { conn, release, err := bs.db.Conn(ctx) if err != nil { return err @@ -121,8 +127,8 @@ func (bs *Storage) MaybeReindex(ctx context.Context) error { // indexBlob is an uber-function that knows about all types of blobs we want to index. // This is probably a bad idea to put here, but for now it's easier to work with that way. // TODO(burdiyan): eventually we might want to make this package agnostic to blob types. -func (bs *Storage) indexBlob(conn *sqlite.Conn, id int64, blob Blob) error { - switch v := blob.Decoded.(type) { +func (bs *indexer) indexBlob(conn *sqlite.Conn, id int64, c cid.Cid, blobData any) error { + switch v := blobData.(type) { case KeyDelegation: // Validate key delegation. { @@ -180,7 +186,7 @@ func (bs *Storage) indexBlob(conn *sqlite.Conn, id int64, blob Blob) error { var del KeyDelegation if err := cbornode.DecodeInto(blk.RawData(), &del); err != nil { - return fmt.Errorf("failed to decode key delegation when indexing change %s: %w", blob.CID, err) + return fmt.Errorf("failed to decode key delegation when indexing change %s: %w", c, err) } iss.KeyDelegationsIssuer, err = bs.ensurePublicKey(conn, del.Issuer) @@ -189,7 +195,7 @@ func (bs *Storage) indexBlob(conn *sqlite.Conn, id int64, blob Blob) error { } if iss.KeyDelegationsIssuer == 0 { - return fmt.Errorf("missing key delegation info %s of change %s", v.Delegation, blob.CID) + return fmt.Errorf("missing key delegation info %s of change %s", v.Delegation, c) } } @@ -230,11 +236,11 @@ func (bs *Storage) indexBlob(conn *sqlite.Conn, id int64, blob Blob) error { return err } if res.BlobsSize < 0 || res.BlobsID == 0 { - return fmt.Errorf("missing causal dependency %s of change %s", dep, blob.CID) + return fmt.Errorf("missing causal dependency %s of change %s", dep, c) } if err := hypersql.BlobLinksInsertOrIgnore(conn, id, "change/dep", res.BlobsID); err != nil { - return fmt.Errorf("failed to link dependency %s of change %s: %w", dep, blob.CID, err) + return fmt.Errorf("failed to link dependency %s of change %s: %w", dep, c, err) } } @@ -243,18 +249,18 @@ func (bs *Storage) indexBlob(conn *sqlite.Conn, id int64, blob Blob) error { } if v.Entity.HasPrefix("hm://d/") { - return bs.indexDocumentChange(conn, id, isspk.PublicKeysPrincipal, blob.CID, v) + return bs.indexDocumentChange(conn, id, isspk.PublicKeysPrincipal, c, v) } if v.Entity.HasPrefix("hm://g/") { - return bs.indexGroupChange(conn, id, isspk.PublicKeysPrincipal, blob.CID, v) + return bs.indexGroupChange(conn, id, isspk.PublicKeysPrincipal, c, v) } } return nil } -func (bs *Storage) ensureEntity(conn *sqlite.Conn, eid EntityID) (int64, error) { +func (bs *indexer) ensureEntity(conn *sqlite.Conn, eid EntityID) (int64, error) { look, err := hypersql.EntitiesLookupID(conn, string(eid)) if err != nil { return 0, err @@ -274,7 +280,7 @@ func (bs *Storage) ensureEntity(conn *sqlite.Conn, eid EntityID) (int64, error) return ins.EntitiesID, nil } -func (bs *Storage) ensurePublicKey(conn *sqlite.Conn, key core.Principal) (int64, error) { +func (bs *indexer) ensurePublicKey(conn *sqlite.Conn, key core.Principal) (int64, error) { res, err := hypersql.PublicKeysLookupID(conn, key) if err != nil { return 0, err @@ -296,7 +302,7 @@ func (bs *Storage) ensurePublicKey(conn *sqlite.Conn, key core.Principal) (int64 return ins.PublicKeysID, nil } -func (bs *Storage) indexGroupChange(conn *sqlite.Conn, blobID int64, author core.Principal, c cid.Cid, ch Change) error { +func (bs *indexer) indexGroupChange(conn *sqlite.Conn, blobID int64, author core.Principal, c cid.Cid, ch Change) error { hlc := ch.HLCTime.Pack() // Validate group change. @@ -461,7 +467,7 @@ func (bs *Storage) indexGroupChange(conn *sqlite.Conn, blobID int64, author core return nil } -func (bs *Storage) indexDocumentChange(conn *sqlite.Conn, blobID int64, author core.Principal, c cid.Cid, ch Change) error { +func (bs *indexer) indexDocumentChange(conn *sqlite.Conn, blobID int64, author core.Principal, c cid.Cid, ch Change) error { hlc := ch.HLCTime.Pack() // Validate document change. @@ -579,7 +585,7 @@ type LinkData struct { TargetVersion string `json:"v,omitempty"` } -func (bs *Storage) indexURL(conn *sqlite.Conn, blobID int64, key, anchor, rawURL string, ts int64) error { +func (bs *indexer) indexURL(conn *sqlite.Conn, blobID int64, key, anchor, rawURL string, ts int64) error { if rawURL == "" { return nil } diff --git a/backend/hyper/terra.go b/backend/hyper/terra.go index 4d16a84c79..f2b0723dc9 100644 --- a/backend/hyper/terra.go +++ b/backend/hyper/terra.go @@ -113,7 +113,7 @@ func (kd KeyDelegation) Verify() error { // Blob encodes the delegation into a blob. func (kd KeyDelegation) Blob() Blob { - hb, err := EncodeBlob(TypeKeyDelegation, kd) + hb, err := EncodeBlob(kd) if err != nil { panic(err) } diff --git a/backend/syncing/syncing.go b/backend/syncing/syncing.go index f1149b460d..1c0c656f94 100644 --- a/backend/syncing/syncing.go +++ b/backend/syncing/syncing.go @@ -300,7 +300,7 @@ func (s *Service) syncObject(ctx context.Context, sess exchange.Fetcher, obj *p2 if err := kd.Verify(); err != nil { return fmt.Errorf("failed to verify key delegation: %w", err) } - kdblob, err := hyper.EncodeBlob(hyper.TypeKeyDelegation, kd) + kdblob, err := hyper.EncodeBlob(kd) if err != nil { return err } @@ -327,7 +327,7 @@ func (s *Service) syncObject(ctx context.Context, sess exchange.Fetcher, obj *p2 } } - changeBlob, err := hyper.EncodeBlob(hyper.TypeChange, vc.change) + changeBlob, err := hyper.EncodeBlob(vc.change) if err != nil { return err } diff --git a/go.mod b/go.mod index 93dedcc355..4fd5ee004a 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/ipfs/go-ipld-cbor v0.0.6 github.com/ipfs/go-ipld-format v0.5.0 github.com/ipfs/go-log/v2 v2.5.1 + github.com/ipld/go-codec-dagpb v1.6.0 github.com/klauspost/compress v1.16.6 github.com/libp2p/go-libp2p v0.28.0 github.com/libp2p/go-libp2p-gostream v0.6.0 @@ -47,10 +48,10 @@ require ( go.uber.org/zap v1.24.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/sync v0.3.0 - golang.org/x/text v0.10.0 + golang.org/x/text v0.13.0 google.golang.org/grpc v1.53.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.31.0 ) require ( @@ -124,8 +125,7 @@ require ( github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipld/go-codec-dagpb v1.6.0 // indirect - github.com/ipld/go-ipld-prime v0.20.0 // indirect + github.com/ipld/go-ipld-prime v0.21.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -194,11 +194,11 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/dig v1.17.0 // indirect go.uber.org/fx v1.20.0 // indirect - golang.org/x/crypto v0.10.0 // indirect + golang.org/x/crypto v0.13.0 // indirect golang.org/x/mod v0.11.0 // indirect golang.org/x/net v0.11.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect golang.org/x/tools v0.10.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.13.0 // indirect diff --git a/go.sum b/go.sum index 145ed0161f..208520b9bd 100644 --- a/go.sum +++ b/go.sum @@ -242,7 +242,7 @@ github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJn github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= @@ -487,8 +487,8 @@ github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVzte github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= @@ -959,7 +959,7 @@ github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUO github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= +github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1079,8 +1079,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= 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= @@ -1235,12 +1235,12 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1249,8 +1249,8 @@ golang.org/x/text v0.3.5/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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= @@ -1381,8 +1381,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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=