diff --git a/blockchain/client.go b/blockchain/client.go index ccc2c4d..013262b 100644 --- a/blockchain/client.go +++ b/blockchain/client.go @@ -1,14 +1,29 @@ package blockchain import ( + "fmt" + "math" + "sync" + "sync/atomic" + gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4" + "github.com/centrifuge/go-substrate-rpc-client/v4/types" + "github.com/centrifuge/go-substrate-rpc-client/v4/types/codec" "github.com/cerebellum-network/cere-ddc-sdk-go/blockchain/pallets" ) +type EventsListener func(*pallets.Events) + type Client struct { *gsrpc.SubstrateAPI + eventsListeners map[int]EventsListener + mu sync.Mutex + isListening uint32 + stopListening func() + errsListening chan error + DdcClusters pallets.DdcClustersApi DdcCustomers pallets.DdcCustomersApi DdcNodes pallets.DdcNodesApi @@ -26,10 +41,97 @@ func NewClient(url string) (*Client, error) { } return &Client{ - SubstrateAPI: substrateApi, - DdcClusters: pallets.NewDdcClustersApi(substrateApi), - DdcCustomers: pallets.NewDdcCustomersApi(substrateApi, meta), - DdcNodes: pallets.NewDdcNodesApi(substrateApi, meta), - DdcPayouts: pallets.NewDdcPayoutsApi(substrateApi, meta), + SubstrateAPI: substrateApi, + eventsListeners: make(map[int]EventsListener), + DdcClusters: pallets.NewDdcClustersApi(substrateApi), + DdcCustomers: pallets.NewDdcCustomersApi(substrateApi, meta), + DdcNodes: pallets.NewDdcNodesApi(substrateApi, meta), + DdcPayouts: pallets.NewDdcPayoutsApi(substrateApi, meta), }, nil } + +func (c *Client) StartEventsListening() (func(), <-chan error, error) { + if !atomic.CompareAndSwapUint32(&c.isListening, 0, 1) { + return c.stopListening, c.errsListening, nil + } + + meta, err := c.RPC.State.GetMetadataLatest() + if err != nil { + return nil, nil, err + } + key, err := types.CreateStorageKey(meta, "System", "Events", nil) + if err != nil { + return nil, nil, err + } + sub, err := c.RPC.State.SubscribeStorageRaw([]types.StorageKey{key}) + if err != nil { + return nil, nil, err + } + + done := make(chan struct{}) + c.errsListening = make(chan error) + + go func() { + for { + select { + case <-done: + return + case set := <-sub.Chan(): + for _, change := range set.Changes { + if !codec.Eq(change.StorageKey, key) || !change.HasStorageData { + continue + } + + events := &pallets.Events{} + err = types.EventRecordsRaw(change.StorageData).DecodeEventRecords(meta, events) + if err != nil { + c.errsListening <- fmt.Errorf("events decoder: %w", err) + } + + for _, callback := range c.eventsListeners { + go callback(events) + } + } + } + } + }() + + once := sync.Once{} + c.stopListening = func() { + once.Do(func() { + done <- struct{}{} + sub.Unsubscribe() + c.isListening = 0 + }) + } + + return c.stopListening, c.errsListening, nil +} + +func (c *Client) RegisterEventsListener(callback EventsListener) (func(), error) { + var idx int + for i := 0; i <= math.MaxInt; i++ { + if _, ok := c.eventsListeners[i]; !ok { + idx = i + break + } + if i == math.MaxInt { + return nil, fmt.Errorf("too many events listeners") + } + } + + c.mu.Lock() + c.eventsListeners[idx] = callback + c.mu.Unlock() + + once := sync.Once{} + stop := func() { + once.Do(func() { + c.mu.Lock() + delete(c.eventsListeners, idx) + c.mu.Unlock() + }) + } + + return stop, nil +} diff --git a/blockchain/go.mod b/blockchain/go.mod index bc1726d..e6a6d70 100644 --- a/blockchain/go.mod +++ b/blockchain/go.mod @@ -2,7 +2,7 @@ module github.com/cerebellum-network/cere-ddc-sdk-go/blockchain go 1.18 -require github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.8 +require github.com/centrifuge/go-substrate-rpc-client/v4 v4.2.1 require ( github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect @@ -18,7 +18,7 @@ require ( github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect github.com/pierrec/xxHash v0.1.5 // indirect github.com/rs/cors v1.8.2 // indirect - github.com/vedhavyas/go-subkey v1.0.3 // indirect + github.com/vedhavyas/go-subkey/v2 v2.0.0 // indirect golang.org/x/crypto v0.7.0 // indirect golang.org/x/sys v0.6.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect diff --git a/blockchain/go.sum b/blockchain/go.sum index 612d59e..1d46f81 100644 --- a/blockchain/go.sum +++ b/blockchain/go.sum @@ -1,11 +1,10 @@ github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= -github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.8 h1:gHLD5S81As9u5DbefLahw1enVO6OdBSS8gBI2R6KNEQ= -github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.8/go.mod h1:5g1oM4Zu3BOaLpsKQ+O8PAv2kNuq+kPcA1VzFbsSqxE= +github.com/centrifuge/go-substrate-rpc-client/v4 v4.2.1 h1:io49TJ8IOIlzipioJc9pJlrjgdJvqktpUWYxVY5AUjE= +github.com/centrifuge/go-substrate-rpc-client/v4 v4.2.1/go.mod h1:k61SBXqYmnZO4frAJyH3iuqjolYrYsq79r8EstmklDY= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -47,8 +46,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= -github.com/vedhavyas/go-subkey v1.0.3 h1:iKR33BB/akKmcR2PMlXPBeeODjWLM90EL98OrOGs8CA= -github.com/vedhavyas/go-subkey v1.0.3/go.mod h1:CloUaFQSSTdWnINfBRFjVMkWXZANW+nd8+TI5jYcl6Y= +github.com/vedhavyas/go-subkey/v2 v2.0.0 h1:LemDIsrVtRSOkp0FA8HxP6ynfKjeOj3BY2U9UNfeDMA= +github.com/vedhavyas/go-subkey/v2 v2.0.0/go.mod h1:95aZ+XDCWAUUynjlmi7BtPExjXgXxByE0WfBwbmIRH4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/blockchain/pallets/ddcclusters.go b/blockchain/pallets/ddcclusters.go index 346a2ac..03dbe5c 100644 --- a/blockchain/pallets/ddcclusters.go +++ b/blockchain/pallets/ddcclusters.go @@ -21,6 +21,41 @@ type ClusterProps struct { NodeProviderAuthContract types.AccountID } +// Events +type ( + EventDdcClustersClusterCreated struct { + Phase types.Phase + ClusterId ClusterId + Topics []types.Hash + } + + EventDdcClustersClusterNodeAdded struct { + Phase types.Phase + ClusterId ClusterId + NodePubKey NodePubKey + Topics []types.Hash + } + + EventDdcClustersClusterNodeRemoved struct { + Phase types.Phase + ClusterId ClusterId + NodePubKey NodePubKey + Topics []types.Hash + } + + EventDdcClustersClusterParamsSet struct { + Phase types.Phase + ClusterId ClusterId + Topics []types.Hash + } + + EventDdcClustersClusterGovParamsSet struct { + Phase types.Phase + ClusterId ClusterId + Topics []types.Hash + } +) + type DdcClustersApi interface { GetClustersNodes(clusterId ClusterId) ([]NodePubKey, error) } diff --git a/blockchain/pallets/ddccustomers.go b/blockchain/pallets/ddccustomers.go index be4c75d..8af576d 100644 --- a/blockchain/pallets/ddccustomers.go +++ b/blockchain/pallets/ddccustomers.go @@ -25,6 +25,44 @@ type UnlockChunk struct { Block types.BlockNumber } +// Events +type ( + EventDdcCustomersDeposited struct { + Phase types.Phase + Owner types.AccountID + Amount types.U128 + Topics []types.Hash + } + EventDdcCustomersInitialDepositUnlock struct { + Phase types.Phase + Owner types.AccountID + Amount types.U128 + Topics []types.Hash + } + EventDdcCustomersWithdrawn struct { + Phase types.Phase + Owner types.AccountID + Amount types.U128 + Topics []types.Hash + } + EventDdcCustomersCharged struct { + Phase types.Phase + Owner types.AccountID + Amount types.U128 + Topics []types.Hash + } + EventDdcCustomersBucketCreated struct { + Phase types.Phase + BucketId BucketId + Topics []types.Hash + } + EventDdcCustomersBucketUpdated struct { + Phase types.Phase + BucketId BucketId + Topics []types.Hash + } +) + type DdcCustomersApi interface { GetBuckets(bucketId BucketId) (types.Option[Bucket], error) GetBucketsCount() (types.U64, error) @@ -36,9 +74,9 @@ type ddcCustomersApi struct { meta *types.Metadata } -func NewDdcCustomersApi(substrateAPI *gsrpc.SubstrateAPI, meta *types.Metadata) DdcCustomersApi { +func NewDdcCustomersApi(substrateApi *gsrpc.SubstrateAPI, meta *types.Metadata) DdcCustomersApi { return &ddcCustomersApi{ - substrateAPI, + substrateApi, meta, } } diff --git a/blockchain/pallets/ddcnodes.go b/blockchain/pallets/ddcnodes.go index 481865b..be73372 100644 --- a/blockchain/pallets/ddcnodes.go +++ b/blockchain/pallets/ddcnodes.go @@ -40,9 +40,9 @@ type ddcNodesApi struct { meta *types.Metadata } -func NewDdcNodesApi(substrateAPI *gsrpc.SubstrateAPI, meta *types.Metadata) DdcNodesApi { +func NewDdcNodesApi(substrateApi *gsrpc.SubstrateAPI, meta *types.Metadata) DdcNodesApi { return &ddcNodesApi{ - substrateAPI, + substrateApi, meta, } } diff --git a/blockchain/pallets/ddcpayouts.go b/blockchain/pallets/ddcpayouts.go index 637b132..21e9ec9 100644 --- a/blockchain/pallets/ddcpayouts.go +++ b/blockchain/pallets/ddcpayouts.go @@ -90,6 +90,124 @@ func (m State) Encode(encoder scale.Encoder) error { return nil } +// Events +type ( + EventDdcPayoutsBillingReportInitialized struct { + Phase types.Phase + ClusterId ClusterId + Topics []types.Hash + } + + EventDdcPayoutsChargingStarted struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Topics []types.Hash + } + + EventDdcPayoutsCharged struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + BatchIndex BatchIndex + CustomerId types.AccountID + Amount types.U128 + Topics []types.Hash + } + + EventDdcPayoutsChargeFailed struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + BatchIndex BatchIndex + CustomerId types.AccountID + Amount types.U128 + Topics []types.Hash + } + + EventDdcPayoutsIndebted struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + BatchIndex BatchIndex + CustomerId types.AccountID + Amount types.U128 + Topics []types.Hash + } + + EventDdcPayoutsChargingFinished struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Topics []types.Hash + } + + EventDdcPayoutsTreasuryFeesCollected struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Topics []types.Hash + } + + EventDdcPayoutsClusterReserveFeesCollected struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Amount types.U128 + Topics []types.Hash + } + + EventDdcPayoutsValidatorFeesCollected struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Amount types.U128 + Topics []types.Hash + } + + EventDdcPayoutsRewardingStarted struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Topics []types.Hash + } + + EventDdcPayouts struct { + Phase types.Phase + ClusterId ClusterId + Topics []types.Hash + } + + EventDdcPayoutsRewarded struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + NodeProviderId types.AccountID + Amount types.U128 + Topics []types.Hash + } + + EventDdcPayoutsRewardingFinished struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Topics []types.Hash + } + + EventDdcPayoutsBillingReportFinalized struct { + Phase types.Phase + ClusterId ClusterId + Era DdcEra + Topics []types.Hash + } + + EventDdcPayoutsAuthorisedCaller struct { + Phase types.Phase + AuthorisedCaller types.AccountID + Topics []types.Hash + } +) + type DdcPayoutsApi interface { GetActiveBillingReports(cluster ClusterId, era DdcEra) (types.Option[BillingReport], error) GetAuthorisedCaller() (types.Option[types.AccountID], error) @@ -101,9 +219,9 @@ type ddcPayoutsApi struct { meta *types.Metadata } -func NewDdcPayoutsApi(substrateAPI *gsrpc.SubstrateAPI, meta *types.Metadata) DdcPayoutsApi { +func NewDdcPayoutsApi(substrateApi *gsrpc.SubstrateAPI, meta *types.Metadata) DdcPayoutsApi { return &ddcPayoutsApi{ - substrateAPI, + substrateApi, meta, } } diff --git a/blockchain/pallets/events.go b/blockchain/pallets/events.go new file mode 100644 index 0000000..4f666e9 --- /dev/null +++ b/blockchain/pallets/events.go @@ -0,0 +1,37 @@ +package pallets + +import ( + "github.com/centrifuge/go-substrate-rpc-client/v4/types" +) + +type Events struct { + types.EventRecords + + DdcClusters_ClusterCreated []EventDdcClustersClusterCreated //nolint:stylecheck,golint + DdcClusters_ClusterNodeAdded []EventDdcClustersClusterNodeAdded //nolint:stylecheck,golint + DdcClusters_ClusterNodeRemoved []EventDdcClustersClusterNodeRemoved //nolint:stylecheck,golint + DdcClusters_ClusterParamsSet []EventDdcClustersClusterParamsSet //nolint:stylecheck,golint + DdcClusters_ClusterGovParamsSet []EventDdcClustersClusterGovParamsSet //nolint:stylecheck,golint + + DdcCustomers_Deposited []EventDdcCustomersDeposited //nolint:stylecheck,golint + DdcCustomers_InitialDepositUnlock []EventDdcCustomersInitialDepositUnlock //nolint:stylecheck,golint + DdcCustomers_Withdrawn []EventDdcCustomersWithdrawn //nolint:stylecheck,golint + DdcCustomers_Charged []EventDdcCustomersCharged //nolint:stylecheck,golint + DdcCustomers_BucketCreated []EventDdcCustomersBucketCreated //nolint:stylecheck,golint + DdcCustomers_BucketUpdated []EventDdcCustomersBucketUpdated //nolint:stylecheck,golint + + DdcPayouts_BillingReportInitialized []EventDdcPayoutsBillingReportInitialized //nolint:stylecheck,golint + DdcPayouts_ChargingStarted []EventDdcPayoutsChargingStarted //nolint:stylecheck,golint + DdcPayouts_Charged []EventDdcPayoutsCharged //nolint:stylecheck,golint + DdcPayouts_ChargeFailed []EventDdcPayoutsChargeFailed //nolint:stylecheck,golint + DdcPayouts_Indebted []EventDdcPayoutsIndebted //nolint:stylecheck,golint + DdcPayouts_ChargingFinished []EventDdcPayoutsChargingFinished //nolint:stylecheck,golint + DdcPayouts_TreasuryFeesCollected []EventDdcPayoutsTreasuryFeesCollected //nolint:stylecheck,golint + DdcPayouts_ClusterReserveFeesCollected []EventDdcPayoutsClusterReserveFeesCollected //nolint:stylecheck,golint + DdcPayouts_ValidatorFeesCollected []EventDdcPayoutsValidatorFeesCollected //nolint:stylecheck,golint + DdcPayouts_RewardingStarted []EventDdcPayoutsRewardingStarted //nolint:stylecheck,golint + DdcPayouts_Rewarded []EventDdcPayoutsRewarded //nolint:stylecheck,golint + DdcPayouts_RewardingFinished []EventDdcPayoutsRewardingFinished //nolint:stylecheck,golint + DdcPayouts_BillingReportFinalized []EventDdcPayoutsBillingReportFinalized //nolint:stylecheck,golint + DdcPayouts_AuthorisedCaller []EventDdcPayoutsAuthorisedCaller //nolint:stylecheck,golint +} diff --git a/go.work.sum b/go.work.sum index 5d0eb11..3b8edee 100644 --- a/go.work.sum +++ b/go.work.sum @@ -226,6 +226,8 @@ github.com/c-bata/go-prompt v0.2.2 h1:uyKRz6Z6DUyj49QVijyM339UJV9yhbr70gESwbNU3e github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= +github.com/centrifuge/go-substrate-rpc-client/v4 v4.2.1 h1:io49TJ8IOIlzipioJc9pJlrjgdJvqktpUWYxVY5AUjE= +github.com/centrifuge/go-substrate-rpc-client/v4 v4.2.1/go.mod h1:k61SBXqYmnZO4frAJyH3iuqjolYrYsq79r8EstmklDY= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= @@ -287,6 +289,8 @@ github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/dave/jennifer v1.2.0 h1:S15ZkFMRoJ36mGAQgWL1tnr0NQJh9rZ8qatseX/VbBc= +github.com/decred/base58 v1.0.4 h1:QJC6B0E0rXOPA8U/kw2rP+qiRJsUaE2Er+pYb3siUeA= +github.com/decred/base58 v1.0.4/go.mod h1:jJswKPEdvpFpvf7dsDvFZyLT22xZ9lWqEByX38oGd9E= github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73 h1:OGNva6WhsKst5OZf7eZOklDztV3hwtTHovdrLHV+MsA= @@ -469,6 +473,8 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104 h1:d8RFOZ2IiFtFWBcKEHAFYJcPTf0wY5q0exFNJZVWa1U= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b h1:QrHweqAtyJ9EwCaGHBu1fghwxIPiopAHV06JlXrMHjk= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b/go.mod h1:xxLb2ip6sSUts3g1irPVHyk/DGslwQsNOo9I7smJfNU= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= @@ -577,6 +583,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= +github.com/vedhavyas/go-subkey/v2 v2.0.0 h1:LemDIsrVtRSOkp0FA8HxP6ynfKjeOj3BY2U9UNfeDMA= +github.com/vedhavyas/go-subkey/v2 v2.0.0/go.mod h1:95aZ+XDCWAUUynjlmi7BtPExjXgXxByE0WfBwbmIRH4= github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 h1:+UB2BJA852UkGH42H+Oee69djmxS3ANzl2b/JtT1YiA= github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= @@ -613,6 +621,8 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= @@ -631,6 +641,7 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=