From b9c23ffbb2eed0b3cd9f602dad38928dc078596c Mon Sep 17 00:00:00 2001 From: ravi0131 Date: Tue, 14 May 2024 18:08:59 +0200 Subject: [PATCH 1/5] payment-channel for ckb --- payment-channel-ckb/.gitignore | 27 + payment-channel-ckb/.gitmodules | 3 + payment-channel-ckb/.idea/.gitignore | 8 + payment-channel-ckb/.idea/modules.xml | 8 + .../.idea/payment-channel-ckb.iml | 9 + payment-channel-ckb/.idea/vcs.xml | 6 + payment-channel-ckb/.vscode/launch.json | 17 + payment-channel-ckb/client/balances.go | 89 + payment-channel-ckb/client/channel.go | 91 + payment-channel-ckb/client/client.go | 252 + payment-channel-ckb/client/handle.go | 92 + payment-channel-ckb/client/util.go | 22 + payment-channel-ckb/deployment/deployment.go | 159 + payment-channel-ckb/deployment/keys.go | 33 + .../deployment/system_scripts.go | 58 + .../deployment/system_scripts_test.go | 21 + payment-channel-ckb/devnet/Makefile | 2 + .../devnet/contracts/.assets/go-perun.png | Bin 0 -> 150688 bytes .../contracts/.github/workflows/rust.yml | 38 + .../devnet/contracts/.gitignore | 14 + .../devnet/contracts/Cargo.lock | 842 +++ .../devnet/contracts/Cargo.toml | 15 + .../devnet/contracts/README.md | 45 + .../devnet/contracts/build/.gitkeep | 0 .../devnet/contracts/capsule.toml | 27 + .../devnet/contracts/contracts/.gitkeep | 0 .../perun-channel-lockscript/Cargo.toml | 10 + .../perun-channel-lockscript/src/entry.rs | 72 + .../perun-channel-lockscript/src/main.rs | 32 + .../perun-channel-typescript/Cargo.toml | 10 + .../perun-channel-typescript/src/entry.rs | 904 +++ .../perun-channel-typescript/src/main.rs | 32 + .../contracts/perun-common/Cargo.toml | 27 + .../contracts/perun-common/blockchain.mol | 108 + .../contracts/perun-common/offchain_types.mol | 8 + .../contracts/perun-common/src/error.rs | 115 + .../contracts/perun-common/src/helpers.rs | 448 ++ .../contracts/perun-common/src/lib.rs | 7 + .../contracts/perun-common/src/perun_types.rs | 6561 +++++++++++++++++ .../contracts/perun-common/src/sig.rs | 11 + .../contracts/perun-common/types.mol | 140 + .../perun-funds-lockscript/Cargo.toml | 10 + .../perun-funds-lockscript/src/entry.rs | 47 + .../perun-funds-lockscript/src/main.rs | 32 + .../contracts/contracts/sample-udt/Cargo.toml | 10 + .../contracts/sample-udt/src/entry.rs | 101 + .../contracts/sample-udt/src/main.rs | 32 + .../contracts/deployment/dev/deployment.toml | 41 + .../deployment/release/deployment.toml | 37 + .../devnet/contracts/migrations/.gitkeep | 0 .../devnet/contracts/tests/Cargo.lock | 1593 ++++ .../devnet/contracts/tests/Cargo.toml | 18 + .../devnet/contracts/tests/src/lib.rs | 63 + .../contracts/tests/src/perun/account.rs | 41 + .../contracts/tests/src/perun/action.rs | 22 + .../contracts/tests/src/perun/channel.rs | 374 + .../devnet/contracts/tests/src/perun/error.rs | 65 + .../contracts/tests/src/perun/harness.rs | 285 + .../devnet/contracts/tests/src/perun/mod.rs | 22 + .../contracts/tests/src/perun/mutators.rs | 69 + .../contracts/tests/src/perun/random.rs | 13 + .../devnet/contracts/tests/src/perun/state.rs | 17 + .../contracts/tests/src/perun/test/cell.rs | 74 + .../tests/src/perun/test/channel_id.rs | 38 + .../contracts/tests/src/perun/test/client.rs | 259 + .../tests/src/perun/test/funding_agreement.rs | 282 + .../contracts/tests/src/perun/test/keys.rs | 11 + .../contracts/tests/src/perun/test/mod.rs | 15 + .../tests/src/perun/test/transaction/abort.rs | 85 + .../tests/src/perun/test/transaction/close.rs | 96 + .../src/perun/test/transaction/common.rs | 41 + .../src/perun/test/transaction/dispute.rs | 94 + .../src/perun/test/transaction/force_close.rs | 94 + .../tests/src/perun/test/transaction/fund.rs | 123 + .../tests/src/perun/test/transaction/mod.rs | 19 + .../tests/src/perun/test/transaction/open.rs | 129 + .../devnet/contracts/tests/src/tests.rs | 486 ++ .../devnet/deploy_contracts.sh | 51 + .../devnet/devnet-session.yaml | 26 + .../devnet/fund_accounts.expect | 7 + payment-channel-ckb/devnet/fund_accounts.sh | 33 + payment-channel-ckb/devnet/print_accounts.sh | 13 + payment-channel-ckb/devnet/setup-devnet.sh | 96 + .../devnet/sudt-celldep-template.json | 17 + payment-channel-ckb/devnet/sudt_helper.sh | 66 + payment-channel-ckb/go.mod | 45 + payment-channel-ckb/go.sum | 1322 ++++ payment-channel-ckb/main.go | 258 + 88 files changed, 17035 insertions(+) create mode 100644 payment-channel-ckb/.gitignore create mode 100644 payment-channel-ckb/.gitmodules create mode 100644 payment-channel-ckb/.idea/.gitignore create mode 100644 payment-channel-ckb/.idea/modules.xml create mode 100644 payment-channel-ckb/.idea/payment-channel-ckb.iml create mode 100644 payment-channel-ckb/.idea/vcs.xml create mode 100644 payment-channel-ckb/.vscode/launch.json create mode 100644 payment-channel-ckb/client/balances.go create mode 100644 payment-channel-ckb/client/channel.go create mode 100644 payment-channel-ckb/client/client.go create mode 100644 payment-channel-ckb/client/handle.go create mode 100644 payment-channel-ckb/client/util.go create mode 100644 payment-channel-ckb/deployment/deployment.go create mode 100644 payment-channel-ckb/deployment/keys.go create mode 100644 payment-channel-ckb/deployment/system_scripts.go create mode 100644 payment-channel-ckb/deployment/system_scripts_test.go create mode 100644 payment-channel-ckb/devnet/Makefile create mode 100644 payment-channel-ckb/devnet/contracts/.assets/go-perun.png create mode 100644 payment-channel-ckb/devnet/contracts/.github/workflows/rust.yml create mode 100644 payment-channel-ckb/devnet/contracts/.gitignore create mode 100644 payment-channel-ckb/devnet/contracts/Cargo.lock create mode 100644 payment-channel-ckb/devnet/contracts/Cargo.toml create mode 100644 payment-channel-ckb/devnet/contracts/README.md create mode 100644 payment-channel-ckb/devnet/contracts/build/.gitkeep create mode 100644 payment-channel-ckb/devnet/contracts/capsule.toml create mode 100644 payment-channel-ckb/devnet/contracts/contracts/.gitkeep create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/Cargo.toml create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/entry.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/main.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/Cargo.toml create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/entry.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/main.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/Cargo.toml create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/blockchain.mol create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/offchain_types.mol create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/src/error.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/src/helpers.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/src/lib.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/src/perun_types.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/src/sig.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-common/types.mol create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/Cargo.toml create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/entry.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/main.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/sample-udt/Cargo.toml create mode 100644 payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/entry.rs create mode 100644 payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/main.rs create mode 100644 payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml create mode 100644 payment-channel-ckb/devnet/contracts/deployment/release/deployment.toml create mode 100644 payment-channel-ckb/devnet/contracts/migrations/.gitkeep create mode 100644 payment-channel-ckb/devnet/contracts/tests/Cargo.lock create mode 100644 payment-channel-ckb/devnet/contracts/tests/Cargo.toml create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/lib.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/account.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/action.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/channel.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/error.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/harness.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/mod.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/mutators.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/random.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/state.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/cell.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/channel_id.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/client.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/funding_agreement.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/keys.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/mod.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/abort.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/close.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/common.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/dispute.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/force_close.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/fund.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/mod.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/open.rs create mode 100644 payment-channel-ckb/devnet/contracts/tests/src/tests.rs create mode 100755 payment-channel-ckb/devnet/deploy_contracts.sh create mode 100644 payment-channel-ckb/devnet/devnet-session.yaml create mode 100644 payment-channel-ckb/devnet/fund_accounts.expect create mode 100755 payment-channel-ckb/devnet/fund_accounts.sh create mode 100755 payment-channel-ckb/devnet/print_accounts.sh create mode 100755 payment-channel-ckb/devnet/setup-devnet.sh create mode 100644 payment-channel-ckb/devnet/sudt-celldep-template.json create mode 100755 payment-channel-ckb/devnet/sudt_helper.sh create mode 100644 payment-channel-ckb/go.mod create mode 100644 payment-channel-ckb/go.sum create mode 100644 payment-channel-ckb/main.go diff --git a/payment-channel-ckb/.gitignore b/payment-channel-ckb/.gitignore new file mode 100644 index 0000000..146c59d --- /dev/null +++ b/payment-channel-ckb/.gitignore @@ -0,0 +1,27 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# log files +*.log + +perun-ckb-demo + +# Dependency directories (remove the comment below to include it) +# vendor/ +devnet/accounts +devnet/data +devnet/specs +devnet/ckb-miner.toml +devnet/ckb.toml +devnet/default.db-options +devnet/system_scripts diff --git a/payment-channel-ckb/.gitmodules b/payment-channel-ckb/.gitmodules new file mode 100644 index 0000000..5bc5ff8 --- /dev/null +++ b/payment-channel-ckb/.gitmodules @@ -0,0 +1,3 @@ +[submodule "devnet/contracts"] + path = devnet/contracts + url = git@github.com:perun-network/perun-ckb-contract diff --git a/payment-channel-ckb/.idea/.gitignore b/payment-channel-ckb/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/payment-channel-ckb/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/payment-channel-ckb/.idea/modules.xml b/payment-channel-ckb/.idea/modules.xml new file mode 100644 index 0000000..8b4f43e --- /dev/null +++ b/payment-channel-ckb/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/payment-channel-ckb/.idea/payment-channel-ckb.iml b/payment-channel-ckb/.idea/payment-channel-ckb.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/payment-channel-ckb/.idea/payment-channel-ckb.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/payment-channel-ckb/.idea/vcs.xml b/payment-channel-ckb/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/payment-channel-ckb/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/payment-channel-ckb/.vscode/launch.json b/payment-channel-ckb/.vscode/launch.json new file mode 100644 index 0000000..2a17be5 --- /dev/null +++ b/payment-channel-ckb/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}" + } + + ] +} \ No newline at end of file diff --git a/payment-channel-ckb/client/balances.go b/payment-channel-ckb/client/balances.go new file mode 100644 index 0000000..a322278 --- /dev/null +++ b/payment-channel-ckb/client/balances.go @@ -0,0 +1,89 @@ +package client + +import ( + "context" + "encoding/binary" + "fmt" + "log" + "math" + "math/big" + "strconv" + "time" + + "github.com/nervosnetwork/ckb-sdk-go/v2/indexer" + "github.com/nervosnetwork/ckb-sdk-go/v2/types" + "perun.network/perun-ckb-backend/wallet/address" +) + +type BalanceExtractor func(*indexer.LiveCell) *big.Int + +func ckbBalanceExtractor(cell *indexer.LiveCell) *big.Int { + return new(big.Int).SetUint64(cell.Output.Capacity) +} + +func sudtBalanceExtractor(cell *indexer.LiveCell) *big.Int { + if len(cell.OutputData) != 16 { + return big.NewInt(0) + } + return new(big.Int).SetUint64(binary.LittleEndian.Uint64(cell.OutputData)) +} + +func (p *PaymentClient) PollBalances() { + defer log.Println("PollBalances: stopped") + pollingInterval := time.Second + searchKey := &indexer.SearchKey{ + Script: address.AsParticipant(p.Account.Address()).PaymentScript, + ScriptType: types.ScriptTypeLock, + ScriptSearchMode: types.ScriptSearchModeExact, + Filter: nil, + WithData: true, + } + log.Println("PollBalances") + updateBalance := func() { + ctx, _ := context.WithTimeout(context.Background(), pollingInterval) + + cells, err := p.rpcClient.GetCells(ctx, searchKey, indexer.SearchOrderDesc, math.MaxUint32, "") + if err != nil { + log.Println("balance poll error: ", err) + return + } + ckbBalance := big.NewInt(0) + sudtBalance := big.NewInt(0) + for _, cell := range cells.Objects { + ckbBalance = new(big.Int).Add(ckbBalance, ckbBalanceExtractor(cell)) + sudtBalance = new(big.Int).Add(sudtBalance, sudtBalanceExtractor(cell)) + } + + p.balanceMutex.Lock() + if ckbBalance.Cmp(p.balance) != 0 || sudtBalance.Cmp(p.sudtBalance) != 0 { + // Update ckb balance. + p.balance = ckbBalance + //ckbBal := p.balance.Int64() + + // Update sudt balance. + p.sudtBalance = sudtBalance + + p.balanceMutex.Unlock() + //p.NotifyAllBalance(ckbBal) // TODO: Update demo tui to allow for big.Int balances + } else { + p.balanceMutex.Unlock() + } + } + updateBalance() + //return "CKbytes: " + p.balance.String() + ", SUDT: " + p.sudtBalance.String() + /* + // Poll the balance every 5 seconds. + for { + updateBalance() + time.Sleep(pollingInterval) + } + */ +} + +func FormatBalance(ckbBal, sudtBal *big.Int) string { + log.Printf("balances: ckb = %s || sudt = %s", ckbBal.String(), sudtBal.String()) + balCKByte, _ := ShannonToCKByte(ckbBal).Float64() + return fmt.Sprintf("[green]%s\t[yellow]%s[white]", + strconv.FormatFloat(balCKByte, 'f', 2, 64)+" CKByte", + fmt.Sprintf("%v", sudtBal.Int64())+" SUDT") +} diff --git a/payment-channel-ckb/client/channel.go b/payment-channel-ckb/client/channel.go new file mode 100644 index 0000000..05a5b61 --- /dev/null +++ b/payment-channel-ckb/client/channel.go @@ -0,0 +1,91 @@ +package client + +import ( + "context" + "fmt" + "math/big" + + "perun.network/go-perun/channel" + "perun.network/go-perun/client" +) + +type PaymentChannel struct { + ch *client.Channel + assets []channel.Asset +} + +// newPaymentChannel creates a new payment channel. +func newPaymentChannel(ch *client.Channel, assets []channel.Asset) *PaymentChannel { + return &PaymentChannel{ + ch: ch, + assets: assets, + } +} + +func (c PaymentChannel) State() *channel.State { + return c.ch.State().Clone() +} + +func (c PaymentChannel) SendPayment(amounts map[channel.Asset]float64) { + // Transfer the given amount from us to peer. + // Use UpdateBy to update the channel state. + err := c.ch.Update(context.TODO(), func(state *channel.State) { + actor := c.ch.Idx() + peer := 1 - actor + //fmt.Println("Send payment handler called") + for a, amount := range amounts { + fmt.Println(a) + fmt.Println(amount) + if amount < 0 { + continue + } + /* + switch a := a.(type) { + case *asset.Asset: + if a.IsCKBytes { + fmt.Println("inside condition isCKBytes") + shannonAmount := CKByteToShannon(big.NewFloat(amount)) + state.Allocation.TransferBalance(actor, peer, a, shannonAmount) + } else { + fmt.Println("inside if conditional !isCKBytes") + intAmount := new(big.Int).SetUint64(uint64(amount)) + state.Allocation.TransferBalance(actor, peer, a, intAmount) + } + } + */ + + shannonAmount := CKByteToShannon(big.NewFloat(amount)) + state.Allocation.TransferBalance(actor, peer, a, shannonAmount) + + } + + }) + if err != nil { + panic(err) + } + if err != nil { + panic(err) // We panic on error to keep the code simple. + } +} + +// Settle settles the payment channel and withdraws the funds. +func (c PaymentChannel) Settle() { + // Finalize the channel to enable fast settlement. + if !c.ch.State().IsFinal { + err := c.ch.Update(context.TODO(), func(state *channel.State) { + state.IsFinal = true + }) + if err != nil { + panic(err) + } + } + + // Settle concludes the channel and withdraws the funds. + err := c.ch.Settle(context.TODO()) + if err != nil { + panic(err) + } + + // Close frees up channel resources. + c.ch.Close() +} diff --git a/payment-channel-ckb/client/client.go b/payment-channel-ckb/client/client.go new file mode 100644 index 0000000..90d62d8 --- /dev/null +++ b/payment-channel-ckb/client/client.go @@ -0,0 +1,252 @@ +package client + +import ( + "context" + "fmt" + "log" + "math/big" + + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/nervosnetwork/ckb-sdk-go/v2/rpc" + "github.com/nervosnetwork/ckb-sdk-go/v2/types" + "perun.network/go-perun/channel" + gpchannel "perun.network/go-perun/channel" + "perun.network/go-perun/channel/persistence" + "perun.network/go-perun/client" + gpwallet "perun.network/go-perun/wallet" + "perun.network/go-perun/watcher/local" + "perun.network/go-perun/wire" + "perun.network/go-perun/wire/net/simple" + "perun.network/perun-ckb-backend/backend" + "perun.network/perun-ckb-backend/channel/adjudicator" + "perun.network/perun-ckb-backend/channel/asset" + "perun.network/perun-ckb-backend/channel/funder" + ckbclient "perun.network/perun-ckb-backend/client" + "perun.network/perun-ckb-backend/wallet" + "perun.network/perun-ckb-backend/wallet/address" + "polycry.pt/poly-go/sync" +) + +type PaymentClient struct { + balanceMutex sync.Mutex + Name string + balance *big.Int + sudtBalance *big.Int + Account *wallet.Account + wAddr wire.Address + Network types.Network + PerunClient *client.Client + + channels chan *PaymentChannel + rpcClient rpc.Client +} + +func NewPaymentClient( + name string, + network types.Network, + deployment backend.Deployment, + bus wire.Bus, + rpcUrl string, + account *wallet.Account, + key secp256k1.PrivateKey, + wallet *wallet.EphemeralWallet, + persistRestorer persistence.PersistRestorer, +) (*PaymentClient, error) { + backendRPCClient, err := rpc.Dial(rpcUrl) + if err != nil { + return nil, err + } + signer := backend.NewSignerInstance(address.AsParticipant(account.Address()).ToCKBAddress(network), key, network) + + ckbClient, err := ckbclient.NewClient(backendRPCClient, *signer, deployment) + if err != nil { + return nil, err + } + f := funder.NewDefaultFunder(ckbClient, deployment) + a := adjudicator.NewAdjudicator(ckbClient) + watcher, err := local.NewWatcher(a) + if err != nil { + return nil, err + } + wAddr := simple.NewAddress(account.Address().String()) + perunClient, err := client.New(wAddr, bus, f, a, wallet, watcher) + if err != nil { + return nil, err + } + perunClient.EnablePersistence(persistRestorer) + + balanceRPC, err := rpc.Dial(rpcUrl) + if err != nil { + return nil, err + } + p := &PaymentClient{ + Name: name, + balance: big.NewInt(0), + sudtBalance: big.NewInt(0), + Account: account, + wAddr: wAddr, + Network: network, + PerunClient: perunClient, + channels: make(chan *PaymentChannel, 1), + rpcClient: balanceRPC, + } + + //go p.PollBalances() + go perunClient.Handle(p, p) + return p, nil +} + +// WalletAddress returns the wallet address of the client. +func (p *PaymentClient) WalletAddress() gpwallet.Address { + return p.Account.Address() +} + +func (p *PaymentClient) WireAddress() wire.Address { + return p.wAddr +} + +func (p *PaymentClient) GetSudtBalance() *big.Int { + p.balanceMutex.Lock() + defer p.balanceMutex.Unlock() + return new(big.Int).Set(p.sudtBalance) +} + +// TODO: Remove as probably not required +/* +func (p *PaymentClient) NotifyAllBalance(ckbBal int64) string { + str := FormatBalance(new(big.Int).SetInt64(ckbBal), p.GetSudtBalance()) + return str +} +*/ + +// GetBalances retrieves the current balances of the client. +func (p *PaymentClient) GetBalances() string { + p.PollBalances() + return FormatBalance(p.balance, p.sudtBalance) +} + +// OpenChannel opens a new channel with the specified peer and funding. +func (p *PaymentClient) OpenChannel(peer wire.Address, amounts map[gpchannel.Asset]float64) *PaymentChannel { + // We define the channel participants. The proposer always has index 0. Here + // we use the on-chain addresses as off-chain addresses, but we could also + // use different ones. + log.Println("OpenChannel called") + participants := []wire.Address{p.WireAddress(), peer} + + assets := make([]gpchannel.Asset, len(amounts)) + i := 0 + for a := range amounts { + assets[i] = a + i++ + } + + // We create an initial allocation which defines the starting balances. + initAlloc := gpchannel.NewAllocation(2, assets...) + log.Println(initAlloc.Assets) + for a, amount := range amounts { + switch a := a.(type) { + case *asset.Asset: + if a.IsCKBytes { + initAlloc.SetAssetBalances(a, []gpchannel.Bal{ + CKByteToShannon(big.NewFloat(amount)), // Our initial balance. + CKByteToShannon(big.NewFloat(amount)), // Peer's initial balance. + }) + } else { + intAmount := new(big.Int).SetUint64(uint64(amount)) + initAlloc.SetAssetBalances(a, []gpchannel.Bal{ + intAmount, // Our initial balance. + intAmount, // Peer's initial balance. + }) + } + default: + panic("Asset is not of type *asset.Asset") + } + + } + log.Println("Created Allocation") + + // Prepare the channel proposal by defining the channel parameters. + challengeDuration := uint64(10) // On-chain challenge duration in seconds. + proposal, err := client.NewLedgerChannelProposal( + challengeDuration, + p.Account.Address(), + initAlloc, + participants, + ) + if err != nil { + panic(err) + } + + log.Println("Created Proposal") + + // Send the proposal. + ch, err := p.PerunClient.ProposeChannel(context.TODO(), proposal) + if err != nil { + panic(err) + } + + log.Println("Sent Channel") + + // Start the on-chain event watcher. It automatically handles disputes. + p.startWatching(ch) + + log.Println("Started Watching") + + //p.Channel = newPaymentChannel(ch, assets) + return newPaymentChannel(ch, assets) +} + +// startWatching starts the dispute watcher for the specified channel. +func (p *PaymentClient) startWatching(ch *client.Channel) { + go func() { + err := ch.Watch(p) + if err != nil { + fmt.Printf("Watcher returned with error: %v", err) + } + }() +} + +func (p *PaymentClient) AcceptedChannel() *PaymentChannel { + return <-p.channels +} + +func (p *PaymentClient) Shutdown() { + p.PerunClient.Close() +} + +func (c *PaymentClient) Restore() []*PaymentChannel { + var restoredChannels []*client.Channel + + //TODO: Remove this hack. Find why asset is not found upon restoring + c.PerunClient.OnNewChannel(func(ch *client.Channel) { + /* + state := ch.State().Clone() + ckbyte := asset.Asset{ + IsCKBytes: true, + SUDT: nil, + } + //create a new allocation where asset type is defined + alloc := gpchannel.NewAllocation(2, ckbyte) + ckbBalances := state.Allocation.Balances[0] + alloc.SetAssetBalances(ckbyte, ckbBalances) + */ + restoredChannels = append(restoredChannels, ch) + }) + + err := c.PerunClient.Restore(context.TODO()) + if err != nil { + fmt.Println("Error restoring channels") + } + + paymentChannels := make([]*PaymentChannel, len(restoredChannels)) + assets := make([]channel.Asset, 1) + assets = append(assets, &asset.Asset{ + IsCKBytes: true, + SUDT: nil, + }) + for i, ch := range restoredChannels { + paymentChannels[i] = newPaymentChannel(ch, assets) + } + + return paymentChannels +} diff --git a/payment-channel-ckb/client/handle.go b/payment-channel-ckb/client/handle.go new file mode 100644 index 0000000..b509ac1 --- /dev/null +++ b/payment-channel-ckb/client/handle.go @@ -0,0 +1,92 @@ +package client + +import ( + "context" + "fmt" + "log" + + "perun.network/go-perun/channel" + "perun.network/go-perun/client" +) + +// HandleProposal is the callback for incoming channel proposals. +func (p *PaymentClient) HandleProposal(prop client.ChannelProposal, r *client.ProposalResponder) { + lcp, err := func() (*client.LedgerChannelProposalMsg, error) { + // Ensure that we got a ledger channel proposal. + lcp, ok := prop.(*client.LedgerChannelProposalMsg) + if !ok { + return nil, fmt.Errorf("invalid proposal type: %T", p) + } + + // Check that we have the correct number of participants. + if lcp.NumPeers() != 2 { + return nil, fmt.Errorf("invalid number of participants: %d", lcp.NumPeers()) + } + // Check that the channel has the expected assets and funding balances. + for i, assetAlloc := range lcp.FundingAgreement { + if assetAlloc[0].Cmp(assetAlloc[1]) != 0 { + return nil, fmt.Errorf("invalid funding balance for asset %d: %v", i, assetAlloc) + } + + } + return lcp, nil + }() + if err != nil { + _ = r.Reject(context.TODO(), err.Error()) + } + + // Create a channel accept message and send it. + accept := lcp.Accept( + p.WalletAddress(), // The Account we use in the channel. + client.WithRandomNonce(), // Our share of the channel nonce. + ) + ch, err := r.Accept(context.TODO(), accept) + if err != nil { + log.Printf("Error accepting channel proposal: %v", err) + return + } + + //TODO: startWatching + // Start the on-chain event watcher. It automatically handles disputes. + p.startWatching(ch) + + // Store channel. + p.channels <- newPaymentChannel(ch, lcp.InitBals.Clone().Assets) + //p.AcceptedChannel() +} + +// HandleUpdate is the callback for incoming channel updates. +func (p *PaymentClient) HandleUpdate(cur *channel.State, next client.ChannelUpdate, r *client.UpdateResponder) { + // We accept every update that increases our balance. + err := func() error { + err := channel.AssertAssetsEqual(cur.Assets, next.State.Assets) + if err != nil { + return fmt.Errorf("invalid assets: %v", err) + } + + receiverIdx := 1 - next.ActorIdx // This works because we are in a two-party channel. + for _, a := range cur.Assets { + curBal := cur.Allocation.Balance(receiverIdx, a) + nextBal := next.State.Allocation.Balance(receiverIdx, a) + if nextBal.Cmp(curBal) < 0 { + return fmt.Errorf("invalid balance: %v", nextBal) + } + } + + return nil + }() + if err != nil { + _ = r.Reject(context.TODO(), err.Error()) + } + + // Send the acceptance message. + err = r.Accept(context.TODO()) + if err != nil { + panic(err) + } +} + +// HandleAdjudicatorEvent is the callback for smart contract events. +func (p *PaymentClient) HandleAdjudicatorEvent(e channel.AdjudicatorEvent) { + log.Printf("Adjudicator event: type = %T, client = %v", e, p.Account) +} diff --git a/payment-channel-ckb/client/util.go b/payment-channel-ckb/client/util.go new file mode 100644 index 0000000..e0d8c11 --- /dev/null +++ b/payment-channel-ckb/client/util.go @@ -0,0 +1,22 @@ +package client + +import ( + "math/big" +) + +// CKByteToShannon converts a given amount in CKByte to Shannon. +func CKByteToShannon(ckbyteAmount *big.Float) (shannonAmount *big.Int) { + shannonPerCKByte := new(big.Int).Exp(big.NewInt(10), big.NewInt(8), nil) + shannonPerCKByteFloat := new(big.Float).SetInt(shannonPerCKByte) + shannonAmountFloat := new(big.Float).Mul(ckbyteAmount, shannonPerCKByteFloat) + shannonAmount, _ = shannonAmountFloat.Int(nil) + return shannonAmount +} + +// ShannonToCKByte converts a given amount in Shannon to CKByte. +func ShannonToCKByte(shannonAmount *big.Int) *big.Float { + shannonPerCKByte := new(big.Int).Exp(big.NewInt(10), big.NewInt(8), nil) + shannonPerCKByteFloat := new(big.Float).SetInt(shannonPerCKByte) + shannonAmountFloat := new(big.Float).SetInt(shannonAmount) + return new(big.Float).Quo(shannonAmountFloat, shannonPerCKByteFloat) +} diff --git a/payment-channel-ckb/deployment/deployment.go b/payment-channel-ckb/deployment/deployment.go new file mode 100644 index 0000000..376c050 --- /dev/null +++ b/payment-channel-ckb/deployment/deployment.go @@ -0,0 +1,159 @@ +package deployment + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io" + "os" + "path" + "strings" + + "github.com/nervosnetwork/ckb-sdk-go/v2/types" + "perun.network/perun-ckb-backend/backend" +) + +const PFLSMinCapacity = 4100000032 + +type SUDTInfo struct { + Script *types.Script + CellDep *types.CellDep +} + +type Migration struct { + CellRecipes []struct { + Name string `json:"name"` + TxHash string `json:"tx_hash"` + Index uint32 `json:"index"` + OccupiedCapacity int64 `json:"occupied_capacity"` + DataHash string `json:"data_hash"` + TypeId interface{} `json:"type_id"` + } `json:"cell_recipes"` + DepGroupRecipes []interface{} `json:"dep_group_recipes"` +} + +func (m Migration) MakeDeployment(systemScripts SystemScripts, sudtOwnerLockArg string) (backend.Deployment, SUDTInfo, error) { + pcts := m.CellRecipes[0] + if pcts.Name != "pcts" { + return backend.Deployment{}, SUDTInfo{}, fmt.Errorf("first cell recipe must be pcts") + } + pcls := m.CellRecipes[1] + if pcls.Name != "pcls" { + return backend.Deployment{}, SUDTInfo{}, fmt.Errorf("second cell recipe must be pcls") + } + pfls := m.CellRecipes[2] + if pfls.Name != "pfls" { + return backend.Deployment{}, SUDTInfo{}, fmt.Errorf("third cell recipe must be pfls") + } + sudtInfo, err := m.GetSUDT() + if err != nil { + return backend.Deployment{}, SUDTInfo{}, err + } + // NOTE: The SUDT lock-arg always contains a newline character at the end. + hexString := strings.ReplaceAll(sudtOwnerLockArg[2:], "\n", "") + hexString = strings.ReplaceAll(hexString, "\r", "") + hexString = strings.ReplaceAll(hexString, " ", "") + sudtInfo.Script.Args, err = hex.DecodeString(hexString) + if err != nil { + return backend.Deployment{}, SUDTInfo{}, fmt.Errorf("invalid sudt owner lock arg: %v", err) + } + + return backend.Deployment{ + Network: types.NetworkTest, + PCTSDep: types.CellDep{ + OutPoint: &types.OutPoint{ + TxHash: types.HexToHash(pcts.TxHash), + Index: m.CellRecipes[0].Index, + }, + DepType: types.DepTypeCode, + }, + PCLSDep: types.CellDep{ + OutPoint: &types.OutPoint{ + TxHash: types.HexToHash(pcls.TxHash), + Index: m.CellRecipes[0].Index, + }, + DepType: types.DepTypeCode, + }, + PFLSDep: types.CellDep{ + OutPoint: &types.OutPoint{ + TxHash: types.HexToHash(pfls.TxHash), + Index: m.CellRecipes[0].Index, + }, + DepType: types.DepTypeCode, + }, + PCTSCodeHash: types.HexToHash(pcts.DataHash), + PCTSHashType: types.HashTypeData1, + PCLSCodeHash: types.HexToHash(pcls.DataHash), + PCLSHashType: types.HashTypeData1, + PFLSCodeHash: types.HexToHash(pfls.DataHash), + PFLSHashType: types.HashTypeData1, + PFLSMinCapacity: PFLSMinCapacity, + DefaultLockScript: types.Script{ + CodeHash: systemScripts.Secp256k1Blake160SighashAll.ScriptID.CodeHash, + HashType: systemScripts.Secp256k1Blake160SighashAll.ScriptID.HashType, + Args: make([]byte, 32), + }, + DefaultLockScriptDep: systemScripts.Secp256k1Blake160SighashAll.CellDep, + SUDTDeps: map[types.Hash]types.CellDep{ + sudtInfo.Script.Hash(): *sudtInfo.CellDep, + }, + SUDTs: map[types.Hash]types.Script{ + sudtInfo.Script.Hash(): *sudtInfo.Script, + }, + }, *sudtInfo, nil +} + +func (m Migration) GetSUDT() (*SUDTInfo, error) { + sudt := m.CellRecipes[3] + if sudt.Name != "sudt" { + return nil, fmt.Errorf("fourth cell recipe must be sudt") + } + + sudtScript := types.Script{ + CodeHash: types.HexToHash(sudt.DataHash), + HashType: types.HashTypeData1, + Args: []byte{}, + } + sudtCellDep := types.CellDep{ + OutPoint: &types.OutPoint{ + TxHash: types.HexToHash(sudt.TxHash), + Index: sudt.Index, + }, + DepType: types.DepTypeCode, + } + return &SUDTInfo{ + Script: &sudtScript, + CellDep: &sudtCellDep, + }, nil +} + +func GetDeployment(migrationDir, systemScriptsDir, sudtOwnerLockArg string) (backend.Deployment, SUDTInfo, error) { + dir, err := os.ReadDir(migrationDir) + if err != nil { + return backend.Deployment{}, SUDTInfo{}, err + } + if len(dir) != 1 { + return backend.Deployment{}, SUDTInfo{}, fmt.Errorf("migration dir must contain exactly one file") + } + migrationName := dir[0].Name() + migrationFile, err := os.Open(path.Join(migrationDir, migrationName)) + defer migrationFile.Close() + if err != nil { + return backend.Deployment{}, SUDTInfo{}, err + } + migrationData, err := io.ReadAll(migrationFile) + if err != nil { + return backend.Deployment{}, SUDTInfo{}, err + } + var migration Migration + err = json.Unmarshal(migrationData, &migration) + if err != nil { + return backend.Deployment{}, SUDTInfo{}, err + } + + ss, err := GetSystemScripts(systemScriptsDir) + if err != nil { + return backend.Deployment{}, SUDTInfo{}, err + } + return migration.MakeDeployment(ss, sudtOwnerLockArg) +} diff --git a/payment-channel-ckb/deployment/keys.go b/payment-channel-ckb/deployment/keys.go new file mode 100644 index 0000000..1d7d6bc --- /dev/null +++ b/payment-channel-ckb/deployment/keys.go @@ -0,0 +1,33 @@ +package deployment + +import ( + "encoding/hex" + "fmt" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "io" + "os" + "strings" +) + +func GetKey(path string) (*secp256k1.PrivateKey, error) { + keyFile, err := os.Open(path) + if err != nil { + return nil, err + } + defer keyFile.Close() + + rawBytes, err := io.ReadAll(keyFile) + if err != nil { + return nil, err + } + lines := strings.Split(string(rawBytes), "\n") + if len(lines) != 2 { + return nil, fmt.Errorf("key file must contain exactly two lines") + } + x := strings.Trim(lines[0], " \n") + xBytes, err := hex.DecodeString(x) + if err != nil { + return nil, err + } + return secp256k1.PrivKeyFromBytes(xBytes), nil +} diff --git a/payment-channel-ckb/deployment/system_scripts.go b/payment-channel-ckb/deployment/system_scripts.go new file mode 100644 index 0000000..77ee117 --- /dev/null +++ b/payment-channel-ckb/deployment/system_scripts.go @@ -0,0 +1,58 @@ +package deployment + +import ( + "encoding/json" + "io" + "os" + "path" + + "github.com/nervosnetwork/ckb-sdk-go/v2/types" +) + +type SystemScripts struct { + DAO struct { + CellDep types.CellDep `json:"cell_dep"` + ScriptID ScriptID `json:"script_id"` + } `json:"dao"` + Secp256k1Blake160MultisigAll struct { + CellDep types.CellDep `json:"cell_dep"` + ScriptID ScriptID `json:"script_id"` + } `json:"secp256k1_blake160_multisig_all"` + Secp256k1Blake160SighashAll struct { + CellDep types.CellDep `json:"cell_dep"` + ScriptID ScriptID `json:"script_id"` + } `json:"secp256k1_blake160_sighash_all"` + Secp256k1Data types.OutPoint `json:"secp256k1_data"` + TypeID struct { + ScriptID ScriptID `json:"script_id"` + } `json:"type_id"` +} + +type ScriptID struct { + CodeHash types.Hash `json:"code_hash"` + HashType types.ScriptHashType `json:"hash_type"` +} + +const systemScriptName = "default_scripts.json" + +func GetSystemScripts(systemScriptDir string) (SystemScripts, error) { + var ss SystemScripts + err := readJSON(systemScriptDir, &ss) + if err != nil { + return SystemScripts{}, err + } + return ss, nil +} + +func readJSON(systemScriptDir string, systemScripts *SystemScripts) error { + systemScriptFile, err := os.Open(path.Join(systemScriptDir, systemScriptName)) + defer func() { _ = systemScriptFile.Close() }() + if err != nil { + return err + } + systemScriptContent, err := io.ReadAll(systemScriptFile) + if err != nil { + return err + } + return json.Unmarshal(systemScriptContent, systemScripts) +} diff --git a/payment-channel-ckb/deployment/system_scripts_test.go b/payment-channel-ckb/deployment/system_scripts_test.go new file mode 100644 index 0000000..d7246a0 --- /dev/null +++ b/payment-channel-ckb/deployment/system_scripts_test.go @@ -0,0 +1,21 @@ +package deployment_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + "perun.network/perun-ckb-demo/deployment" +) + +func TestSystemScripts(t *testing.T) { + var ss deployment.SystemScripts + require.NoError(t, json.Unmarshal([]byte(systemScriptCase), &ss)) + msg, err := json.Marshal(ss) + require.NoError(t, err) + recovered := new(deployment.SystemScripts) + require.NoError(t, json.Unmarshal(msg, recovered)) + require.Equal(t, ss, *recovered) +} + +var systemScriptCase string = "{\"dao\":{\"cell_dep\":{\"dep_type\":\"code\",\"out_point\":{\"index\":\"0x2\",\"tx_hash\":\"0x297d19805fee99a53a6274a976df562d678beeff286776e1cd5ac9d8e1870780\"}},\"script_id\":{\"code_hash\":\"0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e\",\"hash_type\":\"type\"}},\"secp256k1_blake160_multisig_all\":{\"cell_dep\":{\"dep_type\":\"dep_group\",\"out_point\":{\"index\":\"0x1\",\"tx_hash\":\"0xad69fbce31c6d8a8516789dec3cd4ddecbeb63619b4fa6cd3a7d00cdc788bf33\"}},\"script_id\":{\"code_hash\":\"0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8\",\"hash_type\":\"type\"}},\"secp256k1_blake160_sighash_all\":{\"cell_dep\":{\"dep_type\":\"dep_group\",\"out_point\":{\"index\":\"0x0\",\"tx_hash\":\"0xad69fbce31c6d8a8516789dec3cd4ddecbeb63619b4fa6cd3a7d00cdc788bf33\"}},\"script_id\":{\"code_hash\":\"0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8\",\"hash_type\":\"type\"}},\"secp256k1_data\":{\"out_point\":{\"index\":\"0x3\",\"tx_hash\":\"0x297d19805fee99a53a6274a976df562d678beeff286776e1cd5ac9d8e1870780\"}},\"type_id\":{\"script_id\":{\"code_hash\":\"0x00000000000000000000000000000000000000000000000000545950455f4944\",\"hash_type\":\"type\"}}}" diff --git a/payment-channel-ckb/devnet/Makefile b/payment-channel-ckb/devnet/Makefile new file mode 100644 index 0000000..621fcad --- /dev/null +++ b/payment-channel-ckb/devnet/Makefile @@ -0,0 +1,2 @@ +dev: + tmuxp load ./devnet-session.yaml diff --git a/payment-channel-ckb/devnet/contracts/.assets/go-perun.png b/payment-channel-ckb/devnet/contracts/.assets/go-perun.png new file mode 100644 index 0000000000000000000000000000000000000000..6d8787bc738a1a711e97f8603987542675d6e3ee GIT binary patch literal 150688 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

8nZB^GeR(LCMaAb{OIE4WU)d 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

j?gU|`V_x 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 literal 0 HcmV?d00001 diff --git a/payment-channel-ckb/devnet/contracts/.github/workflows/rust.yml b/payment-channel-ckb/devnet/contracts/.github/workflows/rust.yml new file mode 100644 index 0000000..948acce --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/.github/workflows/rust.yml @@ -0,0 +1,38 @@ +name: Rust + +on: + push: + branches: [ "dev" ] + pull_request: + branches: [ "dev" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + tests/target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - name: Capsule + run: cargo install --version 0.9.2 ckb-capsule + - name: Build perun-common + run: cargo build + working-directory: contracts/perun-common + - name: Test perun-common + run: cargo test + working-directory: contracts/perun-common + - name: Build contracts + run: capsule build + - name: Test contracts + run: capsule test diff --git a/payment-channel-ckb/devnet/contracts/.gitignore b/payment-channel-ckb/devnet/contracts/.gitignore new file mode 100644 index 0000000..8ce9103 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/.gitignore @@ -0,0 +1,14 @@ +# Rust +target/* +.cache/.cargo/* +contracts/**/target/* +tests/target/* +migrations/** + +# C +contracts/c/build/* + +# others +build/* +!.gitkeep +.tmp/ diff --git a/payment-channel-ckb/devnet/contracts/Cargo.lock b/payment-channel-ckb/devnet/contracts/Cargo.lock new file mode 100644 index 0000000..d54baf9 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/Cargo.lock @@ -0,0 +1,842 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "blake2b-ref" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95916998c798756098a4eb1b3f2cd510659705a9817bf203d61abd30fbec3e7b" + +[[package]] +name = "blake2b-rs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89a8565807f21b913288968e391819e7f9b2f0f46c7b89549c051cccf3a2771" +dependencies = [ + "cc", + "cty", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "buddy-alloc" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3240a4cb09cf0da6a51641bd40ce90e96ea6065e3a1adc46434029254bcc2d09" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ckb-channel" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "920f26cc48cadcaf6f7bcc3960fde9f9f355633b6361da8ef31e1e1c00fc8858" +dependencies = [ + "crossbeam-channel", +] + +[[package]] +name = "ckb-error" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446a519d8a847d97f1c8ece739dc1748751a9a2179249c96c45cced0825a7aa5" +dependencies = [ + "anyhow", + "ckb-occupied-capacity", + "derive_more", + "thiserror", +] + +[[package]] +name = "ckb-fixed-hash" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00cbbc455b23748b32e06d16628a03e30d56ffa057f17093fdf5b42d4fb6c879" +dependencies = [ + "ckb-fixed-hash-core", + "ckb-fixed-hash-macros", +] + +[[package]] +name = "ckb-fixed-hash-core" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e644a4e026625b4be5a04cdf6c02043080e79feaf77d9cdbb2f0e6553f751" +dependencies = [ + "faster-hex", + "serde", + "thiserror", +] + +[[package]] +name = "ckb-fixed-hash-macros" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cfc980ef88c217825172eb46df269f47890f5e78a38214416f13b3bd17a4b4" +dependencies = [ + "ckb-fixed-hash-core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ckb-hash" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d9b683e89ae4ffdd5aaf4172eab00b6bbe7ea24e2abf77d3eb850ba36e8983" +dependencies = [ + "blake2b-ref", + "blake2b-rs", +] + +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ccb671c5921be8a84686e6212ca184cb1d7c51cadcdbfcbd1cc3f042f5dfb8" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ckb-occupied-capacity" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2a1dd0d4ba5dafba1e30d437c1148b20f42edb76b6794323e05bda626754eb" +dependencies = [ + "ckb-occupied-capacity-core", + "ckb-occupied-capacity-macros", +] + +[[package]] +name = "ckb-occupied-capacity-core" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ebba3d564098a84c83f4740e1dce48a5e2da759becdb47e3c7965f0808e6e92" +dependencies = [ + "serde", +] + +[[package]] +name = "ckb-occupied-capacity-macros" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6321bba85cdf9724029d8c906851dd4a90906869b42f9100b16645a1261d4c" +dependencies = [ + "ckb-occupied-capacity-core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ckb-rational" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2519249f8d47fa758d3fb3cf3049327c69ce0f2acd79d61427482c8661d3dbd" +dependencies = [ + "numext-fixed-uint", + "serde", +] + +[[package]] +name = "ckb-standalone-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22d7cbbdab96e6b809a102cf88bfec28795a0a3c06bfdea4abe4de89777801cd" +dependencies = [ + "cfg-if", + "molecule", +] + +[[package]] +name = "ckb-std" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a6ad40455c446ad6fbb303dae24827fc309f43558f59d1f1b863a9de3e9f81" +dependencies = [ + "buddy-alloc", + "cc", + "ckb-standalone-types", + "cstr_core", +] + +[[package]] +name = "ckb-types" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c22b3b1ca8f88a8f48e2f73321c0605281c9c6f1e1c4d651c6138265c22291e" +dependencies = [ + "bit-vec", + "bytes", + "ckb-channel", + "ckb-error", + "ckb-fixed-hash", + "ckb-hash", + "ckb-merkle-mountain-range", + "ckb-occupied-capacity", + "ckb-rational", + "derive_more", + "merkle-cbt", + "molecule", + "numext-fixed-uint", + "once_cell", +] + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "cpufeatures" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cstr_core" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd98742e4fdca832d40cab219dc2e3048de17d873248f83f17df47c1bea70956" +dependencies = [ + "cty", + "memchr", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest", + "ff", + "generic-array", + "group", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "faster-hex" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e2ce894d53b295cf97b05685aa077950ff3e8541af83217fc720a6437169f8" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "heapsize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +dependencies = [ + "winapi", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2", + "sha3", +] + +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "merkle-cbt" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171d2f700835121c3b04ccf0880882987a050fd5c7ae88148abf537d33dd3a56" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "molecule" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc8276c02a006bddad7d1c28c1a88f30421e1b5f0ba0ca96ceb8077c7d20c01" +dependencies = [ + "bytes", + "cfg-if", + "faster-hex", +] + +[[package]] +name = "numext-constructor" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "621fe0f044729f810c6815cdd77e8f5e0cd803ce4f6a38380ebfc1322af98661" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "numext-fixed-uint" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c68c76f96d589d1009a666c5072f37f3114d682696505f2cf445f27766c7d70" +dependencies = [ + "numext-fixed-uint-core", + "numext-fixed-uint-hack", +] + +[[package]] +name = "numext-fixed-uint-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aab1d6457b97b49482f22a92f0f58a2f39bdd7f3b2f977eae67e8bc206aa980" +dependencies = [ + "heapsize", + "numext-constructor", + "rand", + "serde", + "thiserror", +] + +[[package]] +name = "numext-fixed-uint-hack" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200f8d55c36ec1b6a8cf810115be85d4814f045e0097dfd50033ba25adb4c9e" +dependencies = [ + "numext-fixed-uint-core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "perun-channel-lockscript" +version = "0.1.0" +dependencies = [ + "ckb-std", + "perun-common", +] + +[[package]] +name = "perun-channel-typescript" +version = "0.1.0" +dependencies = [ + "ckb-std", + "perun-common", +] + +[[package]] +name = "perun-common" +version = "0.1.0" +dependencies = [ + "blake2b-rs", + "buddy-alloc", + "ckb-occupied-capacity", + "ckb-standalone-types", + "ckb-std", + "ckb-types", + "k256", + "molecule", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "perun-funds-lockscript" +version = "0.1.0" +dependencies = [ + "ckb-std", + "perun-common", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "rustc-std-workspace-alloc" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff66d57013a5686e1917ed6a025d54dd591fcda71a41fe07edf4d16726aefa86" + +[[package]] +name = "rustc-std-workspace-core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1956f5517128a2b6f23ab2dadf1a976f4f5b27962e7724c2bf3d45e539ec098c" + +[[package]] +name = "sample-udt" +version = "0.1.0" +dependencies = [ + "ckb-std", + "perun-common", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.14", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf316d5356ed6847742d036f8a39c3b8435cac10bd528a4bd461928a6ab34d5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.14", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/payment-channel-ckb/devnet/contracts/Cargo.toml b/payment-channel-ckb/devnet/contracts/Cargo.toml new file mode 100644 index 0000000..bd68a6e --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/Cargo.toml @@ -0,0 +1,15 @@ +[workspace] +members = [ "contracts/perun-channel-lockscript" + , "contracts/perun-channel-typescript" + , "contracts/perun-funds-lockscript" + , "contracts/perun-common" + , "contracts/sample-udt" + ] +exclude = ["tests"] + +[profile.release] +overflow-checks = true +opt-level = 's' +lto = false +codegen-units = 1 +panic = 'abort' diff --git a/payment-channel-ckb/devnet/contracts/README.md b/payment-channel-ckb/devnet/contracts/README.md new file mode 100644 index 0000000..0f60dfb --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/README.md @@ -0,0 +1,45 @@ +


+ Perun +

+ +

Perun CKB Contracts

+ +

+ License: Apache 2.0 + CI status +

+ +# [Perun](https://perun.network/) CKB contracts + +This repository contains the scripts used to realize Perun channels on CKB. +There are three scripts available: + +## perun-channel-lockscript +This script is used to handle access-rights to the live Perun channel cell. +It ensures that only participants of the Perun channel in question are able to +consume the live channel cell. + +## perun-channel-typescript +This script is used to handle a Perun channel's state progression on-chain. +Basically a NFT script with extra functionality. + +## perun-funds-lockscript +This script handle access rights to all funds belonging to a Perun channel. +It ensures that only channel participants are able to consume said funds. + +Build contracts: + +``` sh +capsule build +``` + +Run tests: + +``` sh +capsule test +``` + +## perun-common +Additionally to the available contracts we extracted common functionality into +its own `perun-common` crate which gives some additional helpers and +convenience functions when interacting with types used in Perun contracts. diff --git a/payment-channel-ckb/devnet/contracts/build/.gitkeep b/payment-channel-ckb/devnet/contracts/build/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/payment-channel-ckb/devnet/contracts/capsule.toml b/payment-channel-ckb/devnet/contracts/capsule.toml new file mode 100644 index 0000000..a6549a9 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/capsule.toml @@ -0,0 +1,27 @@ +# [rust] +# # path of rust contracts workspace directory, +# # a `Cargo.toml` file is expected under the directory. +# workspace_dir = "." +# toolchain = "nightly-2022-08-01" +# docker_image = "thewawar/ckb-capsule:2022-08-01" + +# capsule version +version = "0.9.2" +# path of deployment config file +deployment = "deployment/dev/deployment.toml" + +[[contracts]] +name = "perun-channel-lockscript" +template_type = "Rust" + +[[contracts]] +name = "perun-channel-typescript" +template_type = "Rust" + +[[contracts]] +name = "perun-funds-lockscript" +template_type = "Rust" + +[[contracts]] +name = "sample-udt" +template_type = "Rust" diff --git a/payment-channel-ckb/devnet/contracts/contracts/.gitkeep b/payment-channel-ckb/devnet/contracts/contracts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/Cargo.toml b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/Cargo.toml new file mode 100644 index 0000000..049cf5b --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "perun-channel-lockscript" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ckb-std = "0.10.0" +perun-common = { path = "../perun-common", default-features = false, features = ["contract"] } diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/entry.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/entry.rs new file mode 100644 index 0000000..d8ea048 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/entry.rs @@ -0,0 +1,72 @@ +// Import from `core` instead of from `std` since we are in no-std mode +use core::result::Result; + +// Import CKB syscalls and structures +// https://docs.rs/ckb-std/ +use ckb_std::{ + ckb_constants::Source, + ckb_types::{bytes::Bytes, prelude::*}, + high_level::{load_cell_lock_hash, load_cell_type, load_script}, + syscalls::SysError, +}; +use perun_common::{error::Error, perun_types::ChannelConstants}; + +// The perun-channel-lockscript (pcls) is used to lock access to interacting with a channel and is attached as lock script +// to the channel-cell (the cell which uses the perun-channel-type-script (pcts) as its type script). +// A channel defines two participants, each of which has their own unlock_script_hash (also defined in the ChannelConstants.params.{party_a,party_b}). +// The pcls allows a transaction to interact with the channel, if at least one input cell is present with: +// - cell's lock script hash == unlock_script_hash of party_a or +// - cell's lock script hash == unlock_script_hash of party_b +// We recommend using the secp256k1_blake160_sighash_all script as unlock script and corresponding payment args for the participants. +// +// Note: This means, that each participant needs to use a secp256k1_blake160_sighash_all as input to interact with the channel. +// This should not be a substantial restriction, since a payment input will likely be used anyway (e.g. for funding or fees). + +pub fn main() -> Result<(), Error> { + let script = load_script()?; + let args: Bytes = script.args().unpack(); + // return an error if args is invalid + if !args.is_empty() { + return Err(Error::PCLSWithArgs); + } + + // locate the ChannelConstants in the type script of the input cell. + let type_script = load_cell_type(0, Source::GroupInput)?.expect("type script not found"); + let type_script_args: Bytes = type_script.args().unpack(); + + let constants = ChannelConstants::from_slice(&type_script_args) + .expect("unable to parse args as channel parameters"); + + let is_participant = verify_is_participant( + &constants.params().party_a().unlock_script_hash().unpack(), + &constants.params().party_b().unlock_script_hash().unpack(), + )?; + + if !is_participant { + return Err(Error::NotParticipant); + } + + return Ok(()); +} + +/// check_is_participant checks if the current transaction is executed by a channel participant. +/// It does so by looking for an input cell with the same lock script hash as the unlock_script_hash +pub fn verify_is_participant( + unlock_script_hash_a: &[u8; 32], + unlock_script_hash_b: &[u8; 32], +) -> Result { + for i in 0.. { + // Loop over all input cells. + let cell_lock_script_hash = match load_cell_lock_hash(i, Source::Input) { + Ok(lock_hash) => lock_hash, + Err(SysError::IndexOutOfBound) => return Ok(false), + Err(err) => return Err(err.into()), + }; + if cell_lock_script_hash[..] == unlock_script_hash_a[..] + || cell_lock_script_hash[..] == unlock_script_hash_b[..] + { + return Ok(true); + } + } + Ok(false) +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/main.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/main.rs new file mode 100644 index 0000000..9306fc4 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-lockscript/src/main.rs @@ -0,0 +1,32 @@ +//! Generated by capsule +//! +//! `main.rs` is used to define rust lang items and modules. +//! See `entry.rs` for the `main` function. +//! See `error.rs` for the `Error` type. + +#![no_std] +#![no_main] +#![feature(asm_sym)] +#![feature(lang_items)] +#![feature(alloc_error_handler)] +#![feature(panic_info_message)] + +// define modules +mod entry; + +use ckb_std::default_alloc; +use core::arch::asm; + +ckb_std::entry!(program_entry); +default_alloc!(); + +/// program entry +/// +/// Both `argc` and `argv` can be omitted. +fn program_entry(_argc: u64, _argv: *const *const u8) -> i8 { + // Call main function and return error code + match entry::main() { + Ok(_) => 0, + Err(err) => err as i8, + } +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/Cargo.toml b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/Cargo.toml new file mode 100644 index 0000000..85ccd63 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "perun-channel-typescript" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ckb-std = "0.10.0" +perun-common = { path = "../perun-common", default-features = false, features = ["contract"] } diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/entry.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/entry.rs new file mode 100644 index 0000000..e581e4d --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/entry.rs @@ -0,0 +1,904 @@ +// Import from `core` instead of from `std` since we are in no-std mode +use core::result::Result; +// Import heap related library from `alloc` +// https://doc.rust-lang.org/alloc/index.html +use alloc::{self, vec}; + +// Import CKB syscalls and structures +// https://docs.rs/ckb-std/ +use ckb_std::{ + ckb_constants::Source, + ckb_types::{ + bytes::Bytes, + packed::{Byte32, Script}, + prelude::*, + }, + debug, + high_level::{ + load_cell_capacity, load_cell_data, load_cell_lock, load_cell_lock_hash, load_header, + load_script, load_script_hash, load_transaction, load_witness_args, + }, + syscalls::{self, SysError}, +}; +use perun_common::{ + error::Error, + helpers::blake2b256, + perun_types::{ + Balances, ChannelConstants, ChannelParameters, ChannelState, ChannelStatus, ChannelToken, + ChannelWitness, ChannelWitnessUnion, SEC1EncodedPubKey, + }, + sig::verify_signature, +}; + +const SUDT_MIN_LEN: usize = 16; + +/// ChannelAction describes what kind of interaction with the channel is currently happening. +/// +/// If there is an old ChannelStatus, it is the status of the channel before the interaction. +/// The old ChannelStatus lives in the cell data of the pcts input cell. +/// It is stored in the parallel outputs_data array of the transaction that produced the consumed +/// channel output cell. +/// +/// If there is a new ChannelStatus, it is the status of the channel after the interaction. +/// The new ChannelStatus lives in the cell data of the pcts output cell. It is stored in the +/// parallel outputs_data array of the consuming transaction +pub enum ChannelAction { + /// Progress indicates that a channel is being progressed. This means that a channel cell is consumed + /// in the inputs and the same channel with updated state is progressed in the outputs. + /// The possible redeemers associated with the Progress action are Fund and Dispute. + Progress { + old_status: ChannelStatus, + new_status: ChannelStatus, + }, // one PCTS input, one PCTS output + /// Start indicates that a channel is being started. This means that a **new channel** lives in the + /// output cells of this transaction. No channel cell is consumes as an input. + /// As Start does not consume a channel cell, there is no Witness associated with the Start action. + Start { new_status: ChannelStatus }, // no PCTS input, one PCTS output + /// Close indicates that a channel is being closed. This means that a channel's cell is consumed without being + /// recreated in the outputs with updated state. The possible redeemers associated with the Close action are + /// Close, Abort and ForceClose. + /// The channel type script assures that all funds are payed out to the correct parties upon closing. + Close { old_status: ChannelStatus }, // one PCTS input , no PCTS output +} + +pub fn main() -> Result<(), Error> { + let script = load_script()?; + let args: Bytes = script.args().unpack(); + + // return an error if args is empty + if args.is_empty() { + return Err(Error::NoArgs); + } + + // We verify that there is at most one channel in the GroupInputs and GroupOutputs respectively. + verify_max_one_channel()?; + debug!("verify_max_one_channel passed"); + + // The channel constants do not change during the lifetime of a channel. They are located in the + // args field of the pcts. + let channel_constants = + ChannelConstants::from_slice(&args).expect("unable to parse args as ChannelConstants"); + debug!("parsing channel constants passed"); + + // Verify that the channel parameters are compatible with the currently supported + // features of perun channels. + verify_channel_params_compatibility(&channel_constants.params())?; + debug!("verify_channel_params_compatibility passed"); + + // Next, we determine whether the transaction starts, progresses or closes the channel and fetch + // the respective old and/or new channel status. + let channel_action = get_channel_action()?; + debug!("get_channel_action passed"); + + match channel_action { + ChannelAction::Start { new_status } => check_valid_start(&new_status, &channel_constants), + ChannelAction::Progress { + old_status, + new_status, + } => { + let channel_witness = load_witness()?; + debug!("load_witness passed"); + check_valid_progress( + &old_status, + &new_status, + &channel_witness, + &channel_constants, + ) + } + ChannelAction::Close { old_status } => { + let channel_witness = load_witness()?; + debug!("load_witness passed"); + check_valid_close(&old_status, &channel_witness, &channel_constants) + } + } +} + +pub fn check_valid_start( + new_status: &ChannelStatus, + channel_constants: &ChannelConstants, +) -> Result<(), Error> { + const FUNDER_INDEX: usize = 0; + + debug!("check_valid_start"); + + // Upon start of a channel, the channel constants are stored in the args field of the pcts output. + // We uniquely identify a channel through the combination of the channel id (hash of ChannelParameters, + // which is part of the ChannelConstants) and the "thread token". + // The thread token contains an OutPoint and the channel type script verifies, that that outpoint is + // consumed in the inputs of the transaction that starts the channel. + // This means: Once a (pcts-hash, channel-id, thread-token) tuple appears once on chain and is recognized + // as the on-chain representation of this channel by all peers, no other "copy" or "fake" of that channel + // can be created on chain, as an OutPoint can only be consumed once. + + // here, we verify that the OutPoint in the thread token is actually consumed. + verify_thread_token_integrity(&channel_constants.thread_token())?; + debug!("verify_thread_token_integrity passed"); + + // We verify that the channel id is the hash of the channel parameters. + verify_channel_id_integrity( + &new_status.state().channel_id(), + &channel_constants.params(), + )?; + debug!("verify_channel_id_integrity passed"); + + // We verify that the pcts is guarded by the pcls script specified in the channel constants + verify_valid_lock_script(channel_constants)?; + debug!("verify_valid_lock_script passed"); + + // We verify that the channel participants have different payment addresses + // For this purpose we consider a payment address to be the script hash of the lock script used for payments to that party + verify_different_payment_addresses(channel_constants)?; + debug!("verify_different_payment_addresses passed"); + + // We verify that there are no funds locked by the pfls hash of this channel in the inputs of the transaction. + // This check is not strictly necessary for the current implementation of the pfls, but it is good practice to + // verify this anyway, as there is no reason to include funds locked for any channel in the input of a transaction + // that creates a new channel besides trying some kind of attack. + verify_no_funds_in_inputs(channel_constants)?; + debug!("verify_no_funds_in_inputs passed"); + + // We verify that the state the channel starts with is valid according to the utxo-adaption of the perun protocol. + // For example, the channel must not be final and the version number must be 0. + verify_state_valid_as_start( + &new_status.state(), + channel_constants.pfls_min_capacity().unpack(), + )?; + debug!("verify_state_valid_as_start passed"); + + // Here we verify that the first party completes its funding and that itsfunds are actually locked to the pfls with correct args. + verify_funding_in_outputs( + FUNDER_INDEX, + &new_status.state().balances(), + channel_constants, + )?; + debug!("verify_funding_in_outputs passed"); + + // We check that the funded bit in the channel status is set to true, exactly if the funding is complete. + verify_funded_status(new_status, true)?; + debug!("verify_funded_status passed"); + + // We verify that the channel status is not disputed upon start. + verify_status_not_disputed(new_status)?; + debug!("verify_status_not_disputed passed"); + Ok(()) +} + +pub fn check_valid_progress( + old_status: &ChannelStatus, + new_status: &ChannelStatus, + witness: &ChannelWitness, + channel_constants: &ChannelConstants, +) -> Result<(), Error> { + debug!("check_valid_progress"); + + // At this point we know that the transaction progresses the channel. There are two different + // kinds of channel progression: Funding and Dispute. Which kind of progression is performed + // depends on the witness. + + // Some checks are common to both kinds of progression and are performed here. + // We check that both the old and the new state have the same channel id. + verify_equal_channel_id(&old_status.state(), &new_status.state())?; + debug!("verify_equal_channel_id passed"); + + // No kind of channel progression should pay out any funds locked by the pfls, so we just check + // that there are no funds locked by the pfls in the inputs of the transaction. + verify_no_funds_in_inputs(channel_constants)?; + debug!("verify_no_funds_in_inputs passed"); + // Here we verify that the cell with the PCTS in the outputs is locked by the same lock script + // as the input channel cell. + verify_channel_continues_locked()?; + debug!("verify_channel_continues_locked passed"); + + match witness.to_enum() { + ChannelWitnessUnion::Fund(_) => { + const FUNDER_INDEX: usize = 1; + debug!("ChannelWitnessUnion::Fund"); + + // The funding array in a channel status reflects how much each party has funded up to that point. + // Funding must not alter the channel's state. + verify_equal_channel_state(&old_status.state(), &new_status.state())?; + debug!("verify_equal_channel_state passed"); + + // Funding an already funded status is invalid. + verify_status_not_funded(&old_status)?; + debug!("verify_status_not_funded passed"); + + verify_funding_in_outputs( + FUNDER_INDEX, + &old_status.state().balances(), + channel_constants, + )?; + debug!("verify_funding_in_outputs passed"); + + // Funding a disputed status is invalid. This should not be able to happen anyway, but we check + // it nontheless. + verify_status_not_disputed(new_status)?; + debug!("verify_status_not_disputed passed"); + + // We check that the funded bit in the channel status is set to true, iff the funding is complete. + verify_funded_status(&new_status, false)?; + debug!("verify_funded_status passed"); + Ok(()) + } + ChannelWitnessUnion::Dispute(d) => { + debug!("ChannelWitnessUnion::Dispute"); + + // An honest party will dispute a channel, e.g. if its peer does not respond and it wants to close + // the channel. For this, the honest party needs to provide the latest state (in the "new" channel status) + // as well as a valid signature by each party on that state (in the witness). After the expiration of the + // relative time lock (challenge duration), the honest party can forcibly close the channel. + // If a malicious party disputes with an old channel state, an honest party can dispute again with + // the latest state (with higher version number) and the corresponding signatures within the challenge + // duration. + + // First, we verify the integrity of the channel state. For this, the following must hold: + // - channel id is equal + // - version number is increasing (see verify_increasing_version_number) + // - sum of balances is equal + // - old state is not final + verify_channel_state_progression(old_status, &new_status.state())?; + debug!("verify_channel_state_progression passed"); + + // One cannot dispute if funding is not complete. + verify_status_funded(old_status)?; + debug!("verify_status_funded passed"); + + // The disputed flag in the new status must be set. This indicates that the channel can be closed + // forcibly after the expiration of the challenge duration in a later transaction. + verify_status_disputed(new_status)?; + debug!("verify_status_disputed passed"); + + // We verify that the signatures of both parties are valid on the new channel state. + verify_valid_state_sigs( + &d.sig_a().unpack(), + &d.sig_b().unpack(), + &new_status.state(), + &channel_constants.params().party_a().pub_key(), + &channel_constants.params().party_b().pub_key(), + )?; + debug!("verify_valid_state_sigs passed"); + Ok(()) + } + // Close, ForceClose and Abort may not happen as channel progression (if there is a continuing channel output). + ChannelWitnessUnion::Close(_) => Err(Error::ChannelCloseWithChannelOutput), + ChannelWitnessUnion::ForceClose(_) => Err(Error::ChannelForceCloseWithChannelOutput), + ChannelWitnessUnion::Abort(_) => Err(Error::ChannelAbortWithChannelOutput), + } +} + +pub fn check_valid_close( + old_status: &ChannelStatus, + channel_witness: &ChannelWitness, + channel_constants: &ChannelConstants, +) -> Result<(), Error> { + debug!("check_valid_close"); + + // At this point we know that this transaction closes the channel. There are three different kinds of + // closing: Abort, ForceClose and Close. Which kind of closing is performed depends on the witness. + // Every channel closing transaction must pay out all funds the the channel participants. The amount + // to be payed to each party + let channel_capacity = load_cell_capacity(0, Source::GroupInput)?; + match channel_witness.to_enum() { + ChannelWitnessUnion::Abort(_) => { + const PARTY_B_INDEX: usize = 1; + + debug!("ChannelWitnessUnion::Abort"); + + // An abort can be performed at any time by a channel participant on a channel for which funding + // is not yet complete. It allows the initial party to reclaim its funds if e.g. the other party + // refuses to fund the channel. + verify_status_not_funded(old_status)?; + debug!("verify_status_not_funded passed"); + + // We verify that every party is payed the amount of funds that it has locked to the channel so far. + // If abourt is called, Party A must have fully funded the channel and Party B can not have funded + // the channel because of our funding protocol. + verify_all_payed( + &old_status.state().balances().clear_index(PARTY_B_INDEX)?, + channel_capacity, + channel_constants, + true, + )?; + debug!("verify_all_payed passed"); + Ok(()) + } + ChannelWitnessUnion::ForceClose(_) => { + debug!("ChannelWitnessUnion::ForceClose"); + // A force close can be performed after the channel was disputed and the challenge duration has + // expired. Upon force close, each party is payed according to the balance distribution in the + // latest state. + verify_status_funded(old_status)?; + debug!("verify_status_funded passed"); + verify_time_lock_expired(channel_constants.params().challenge_duration().unpack())?; + debug!("verify_time_lock_expired passed"); + verify_status_disputed(old_status)?; + debug!("verify_status_disputed passed"); + verify_all_payed( + &old_status.state().balances(), + channel_capacity, + channel_constants, + false, + )?; + debug!("verify_all_payed passed"); + Ok(()) + } + ChannelWitnessUnion::Close(c) => { + debug!("check_valid_close: Close"); + + // A channel can be closed by either party at any time after funding is complete. + // For this the party needs to provide a final state (final bit set) and signatures + // by all peers on that state. + verify_equal_channel_id(&old_status.state(), &c.state())?; + debug!("check_valid_close: Channel id verified"); + verify_status_funded(old_status)?; + debug!("check_valid_close: Status funded verified"); + verify_state_finalized(&c.state())?; + debug!("check_valid_close: State finalized verified"); + verify_valid_state_sigs( + &c.sig_a().unpack(), + &c.sig_b().unpack(), + &c.state(), + &channel_constants.params().party_a().pub_key(), + &channel_constants.params().party_b().pub_key(), + )?; + // We verify that each party is payed according to the balance distribution in the final state. + verify_all_payed( + &c.state().balances(), + channel_capacity, + channel_constants, + false, + )?; + debug!("verify_all_payed passed"); + Ok(()) + } + ChannelWitnessUnion::Fund(_) => Err(Error::ChannelFundWithoutChannelOutput), + ChannelWitnessUnion::Dispute(_) => Err(Error::ChannelDisputeWithoutChannelOutput), + } +} + +pub fn load_witness() -> Result { + debug!("load_witness"); + + let witness_args = load_witness_args(0, Source::GroupInput)?; + let witness_bytes: Bytes = witness_args + .input_type() + .to_opt() + .ok_or(Error::NoWitness)? + .unpack(); + let channel_witness = ChannelWitness::from_slice(&witness_bytes)?; + Ok(channel_witness) +} + +pub fn verify_increasing_version_number( + old_status: &ChannelStatus, + new_state: &ChannelState, +) -> Result<(), Error> { + debug!( + "verify_increasing_version_number old_state disputed: {}", + old_status.disputed().to_bool() + ); + debug!( + "verify_increasing_version_number old: {}, new: {}", + old_status.state().version().unpack(), + new_state.version().unpack() + ); + // Allow registering initial state + if !old_status.disputed().to_bool() + && old_status.state().version().unpack() == 0 + && new_state.version().unpack() == 0 + { + return Ok(()); + } + if old_status.state().version().unpack() < new_state.version().unpack() { + return Ok(()); + } + Err(Error::VersionNumberNotIncreasing) +} + +pub fn verify_valid_state_sigs( + sig_a: &Bytes, + sig_b: &Bytes, + state: &ChannelState, + pub_key_a: &SEC1EncodedPubKey, + pub_key_b: &SEC1EncodedPubKey, +) -> Result<(), Error> { + let msg_hash = blake2b256(state.as_slice()); + verify_signature(&msg_hash, sig_a, pub_key_a.as_slice())?; + debug!("verify_valid_state_sigs: Signature A verified"); + verify_signature(&msg_hash, sig_b, pub_key_b.as_slice())?; + debug!("verify_valid_state_sigs: Signature B verified"); + Ok(()) +} + +pub fn verify_state_not_finalized(state: &ChannelState) -> Result<(), Error> { + if state.is_final().to_bool() { + return Err(Error::StateIsFinal); + } + Ok(()) +} + +pub fn verify_status_funded(status: &ChannelStatus) -> Result<(), Error> { + if !status.funded().to_bool() { + return Err(Error::ChannelNotFunded); + } + Ok(()) +} + +pub fn verify_equal_sum_of_balances( + old_balances: &Balances, + new_balances: &Balances, +) -> Result<(), Error> { + if !old_balances.equal_in_sum(new_balances)? { + return Err(Error::SumOfBalancesNotEqual); + } + Ok(()) +} + +pub fn verify_channel_continues_locked() -> Result<(), Error> { + let input_lock_script = load_cell_lock(0, Source::GroupInput)?; + let output_lock_script = load_cell_lock(0, Source::GroupOutput)?; + if input_lock_script.as_slice()[..] != output_lock_script.as_slice()[..] { + return Err(Error::ChannelDoesNotContinue); + } + Ok(()) +} + +pub fn verify_no_funds_in_inputs(channel_constants: &ChannelConstants) -> Result<(), Error> { + let num_inputs = load_transaction()?.raw().inputs().len(); + for i in 0..num_inputs { + let cell_lock_hash = load_cell_lock(i, Source::Input)?; + if cell_lock_hash.code_hash().unpack()[..] + == channel_constants.pfls_code_hash().unpack()[..] + { + return Err(Error::FundsInInputs); + } + } + Ok(()) +} + +pub fn verify_equal_channel_state( + old_state: &ChannelState, + new_state: &ChannelState, +) -> Result<(), Error> { + if old_state.as_slice()[..] == new_state.as_slice()[..] { + return Ok(()); + } + Err(Error::ChannelStateNotEqual) +} + +pub fn verify_funding_in_outputs( + idx: usize, + initial_balance: &Balances, + channel_constants: &ChannelConstants, +) -> Result<(), Error> { + let ckbytes_locked_for_sudts = initial_balance.sudts().get_locked_ckbytes(); + let to_fund = initial_balance.ckbytes().get(idx)? + ckbytes_locked_for_sudts; + if to_fund == 0 { + return Ok(()); + } + + let mut udt_sum = + vec![0u128, initial_balance.sudts().len().try_into().unwrap()].into_boxed_slice(); + + let expected_pcts_script_hash = load_script_hash()?; + let outputs = load_transaction()?.raw().outputs(); + let expected_pfls_code_hash = channel_constants.pfls_code_hash().unpack(); + let expected_pfls_hash_type = channel_constants.pfls_hash_type(); + let mut capacity_sum: u64 = 0; + for (i, output) in outputs.into_iter().enumerate() { + if output.lock().code_hash().unpack()[..] == expected_pfls_code_hash[..] + && output.lock().hash_type().eq(&expected_pfls_hash_type) + { + let output_lock_args: Bytes = output.lock().args().unpack(); + let script_hash_in_pfls_args = Byte32::from_slice(&output_lock_args)?.unpack(); + if script_hash_in_pfls_args[..] == expected_pcts_script_hash[..] { + capacity_sum += output.capacity().unpack(); + } else { + return Err(Error::InvalidPFLSInOutputs); + } + if output.type_().is_some() { + let (sudt_idx, amount) = get_sudt_amout( + initial_balance, + i, + &output.type_().to_opt().expect("checked above"), + )?; + udt_sum[sudt_idx] += amount; + } + } + } + if capacity_sum != to_fund { + debug!( + "verify_funding_in_outputs: capacity_sum: {}, to_fund: {}", + capacity_sum, to_fund + ); + return Err(Error::OwnFundingNotInOutputs); + } + if !initial_balance.sudts().fully_represented(idx, &udt_sum)? { + return Err(Error::OwnFundingNotInOutputs); + } + + Ok(()) +} + +pub fn verify_funded_status(status: &ChannelStatus, is_start: bool) -> Result<(), Error> { + if !is_start { + if !status.funded().to_bool() { + return Err(Error::FundedBitStatusNotCorrect); + } + return Ok(()); + } + if status.state().balances().ckbytes().get(1)? != 0 { + if status.funded().to_bool() { + return Err(Error::FundedBitStatusNotCorrect); + } + return Ok(()); + } + if status.state().balances().sudts().len() != 0 { + if status.funded().to_bool() { + return Err(Error::FundedBitStatusNotCorrect); + } + return Ok(()); + } + if !status.funded().to_bool() { + return Err(Error::FundedBitStatusNotCorrect); + } + Ok(()) +} + +pub fn verify_status_not_funded(status: &ChannelStatus) -> Result<(), Error> { + if status.funded().to_bool() { + return Err(Error::StateIsFunded); + } + Ok(()) +} + +pub fn verify_channel_params_compatibility(params: &ChannelParameters) -> Result<(), Error> { + if params.app().to_opt().is_some() { + return Err(Error::AppChannelsNotSupported); + } + if !params.is_ledger_channel().to_bool() { + return Err(Error::NonLedgerChannelsNotSupported); + } + if params.is_virtual_channel().to_bool() { + return Err(Error::VirtualChannelsNotSupported); + } + Ok(()) +} + +pub fn verify_equal_channel_id( + old_state: &ChannelState, + new_state: &ChannelState, +) -> Result<(), Error> { + if old_state.channel_id().unpack()[..] != new_state.channel_id().unpack()[..] { + return Err(Error::ChannelIdMismatch); + } + Ok(()) +} + +pub fn verify_channel_state_progression( + old_status: &ChannelStatus, + new_state: &ChannelState, +) -> Result<(), Error> { + verify_equal_channel_id(&old_status.state(), new_state)?; + verify_increasing_version_number(old_status, new_state)?; + verify_equal_sum_of_balances(&old_status.state().balances(), &new_state.balances())?; + verify_state_not_finalized(&old_status.state())?; + Ok(()) +} + +pub fn verify_thread_token_integrity(thread_token: &ChannelToken) -> Result<(), Error> { + let inputs = load_transaction()?.raw().inputs(); + for input in inputs.into_iter() { + if input.previous_output().as_slice()[..] == thread_token.out_point().as_slice()[..] { + return Ok(()); + } + } + Err(Error::InvalidThreadToken) +} + +pub fn verify_channel_id_integrity( + channel_id: &Byte32, + params: &ChannelParameters, +) -> Result<(), Error> { + let digest = blake2b256(params.as_slice()); + if digest[..] != channel_id.unpack()[..] { + return Err(Error::InvalidChannelId); + } + Ok(()) +} + +pub fn verify_state_valid_as_start( + state: &ChannelState, + pfls_min_capacity: u64, +) -> Result<(), Error> { + if state.version().unpack() != 0 { + return Err(Error::StartWithNonZeroVersion); + } + if state.is_final().to_bool() { + return Err(Error::StartWithFinalizedState); + } + + // We verify that each participant's initial balance is at least the minimum capacity of a PFLS (or zero), + // to ensure that funding is possible for the initial balance distribution. + let balance_a = state.balances().ckbytes().get(0)?; + let balance_b = state.balances().ckbytes().get(1)?; + if balance_a < pfls_min_capacity && balance_a != 0 { + return Err(Error::BalanceBelowPFLSMinCapacity); + } + if balance_b < pfls_min_capacity && balance_b != 0 { + return Err(Error::BalanceBelowPFLSMinCapacity); + } + Ok(()) +} + +pub fn verify_valid_lock_script(channel_constants: &ChannelConstants) -> Result<(), Error> { + let lock_script = load_cell_lock(0, Source::GroupOutput)?; + if lock_script.code_hash().unpack()[..] != channel_constants.pcls_code_hash().unpack()[..] { + return Err(Error::InvalidPCLSCodeHash); + } + if !lock_script + .hash_type() + .eq(&channel_constants.pcls_hash_type()) + { + return Err(Error::InvalidPCLSHashType); + } + + if !lock_script.args().is_empty() { + return Err(Error::PCLSWithArgs); + } + Ok(()) +} + +pub fn verify_status_not_disputed(status: &ChannelStatus) -> Result<(), Error> { + if status.disputed().to_bool() { + return Err(Error::StatusDisputed); + } + Ok(()) +} + +pub fn verify_status_disputed(status: &ChannelStatus) -> Result<(), Error> { + if !status.disputed().to_bool() { + return Err(Error::StatusNotDisputed); + } + Ok(()) +} + +pub fn verify_all_payed( + final_balance: &Balances, + channel_capacity: u64, + channel_constants: &ChannelConstants, + is_abort: bool, +) -> Result<(), Error> { + debug!("verify_all_payed"); + debug!("is_abort: {}", is_abort); + let minimum_payment_a = channel_constants + .params() + .party_a() + .payment_min_capacity() + .unpack(); + let minimum_payment_b: u64 = channel_constants + .params() + .party_b() + .payment_min_capacity() + .unpack(); + + let reimburse_a = final_balance.sudts().get_locked_ckbytes(); + let mut reimburse_b = 0u64; + if !is_abort { + reimburse_b = reimburse_a; + } + + let ckbytes_balance_a = final_balance.ckbytes().get(0)? + channel_capacity + reimburse_a; + let payment_script_hash_a = channel_constants + .params() + .party_a() + .payment_script_hash() + .unpack(); + + let ckbytes_balance_b = final_balance.ckbytes().get(1)? + reimburse_b; + let payment_script_hash_b = channel_constants + .params() + .party_b() + .payment_script_hash() + .unpack(); + + debug!("ckbytes_balance_a: {}", ckbytes_balance_a); + debug!("ckbytes_balance_b: {}", ckbytes_balance_b); + + let mut ckbytes_outputs_a = 0; + let mut ckbytes_outputs_b = 0; + + let mut udt_outputs_a = + vec![0u128; final_balance.sudts().len().try_into().unwrap()].into_boxed_slice(); + let mut udt_outputs_b = + vec![0u128; final_balance.sudts().len().try_into().unwrap()].into_boxed_slice(); + + let outputs = load_transaction()?.raw().outputs(); + + // Note: Currently it is allowed to pay out a party's CKBytes in the capacity field of an + // output, that is used as SUDT payment. + for (i, output) in outputs.into_iter().enumerate() { + let output_lock_script_hash = load_cell_lock_hash(i, Source::Output)?; + + if output_lock_script_hash[..] == payment_script_hash_a[..] { + if output.type_().is_some() { + let (sudt_idx, amount) = get_sudt_amout( + final_balance, + i, + &output.type_().to_opt().expect("checked above"), + )?; + udt_outputs_a[sudt_idx] += amount; + } + ckbytes_outputs_a += output.capacity().unpack(); + } + if output_lock_script_hash[..] == payment_script_hash_b[..] { + if output.type_().is_some() { + let (sudt_idx, amount) = get_sudt_amout( + final_balance, + i, + &output.type_().to_opt().expect("checked above"), + )?; + udt_outputs_b[sudt_idx] += amount; + } + ckbytes_outputs_b += output.capacity().unpack(); + } + } + debug!("ckbytes_outputs_a: {}", ckbytes_outputs_a); + debug!("ckbytes_outputs_b: {}", ckbytes_outputs_b); + + // Parties with balances below the minimum capacity of the payment script + // are not required to be payed. + if (ckbytes_balance_a > ckbytes_outputs_a && ckbytes_balance_a >= minimum_payment_a) + || (ckbytes_balance_b > ckbytes_outputs_b && ckbytes_balance_b >= minimum_payment_b) + { + return Err(Error::NotAllPayed); + } + + debug!("udt_outputs_a: {:?}", udt_outputs_a); + debug!("udt_outputs_b: {:?}", udt_outputs_b); + + if !final_balance.sudts().fully_represented(0, &udt_outputs_a)? { + return Err(Error::NotAllPayed); + } + if !final_balance.sudts().fully_represented(1, &udt_outputs_b)? { + return Err(Error::NotAllPayed); + } + Ok(()) +} + +// TODO: We might want to verify that the capacity of the sudt output is at least the max_capacity of the SUDT asset. +// Not doing so may result in the ability to steal funds up to the +// (max_capacity of the SUDT asset - actual occupied capacity of the SUDT type script), if the SUDT asset's max_capacity +// is smaller than the payment_min_capacity of the participant. We do not do this for now, because it is an extreme edge case +// and the max_capacity of an SUDT should never be set that low. +pub fn get_sudt_amout( + balances: &Balances, + output_idx: usize, + type_script: &Script, +) -> Result<(usize, u128), Error> { + let mut buf = [0u8; SUDT_MIN_LEN]; + + let (sudt_idx, _) = balances.sudts().get_distribution(type_script)?; + let sudt_data = load_cell_data(output_idx, Source::Output)?; + if sudt_data.len() < SUDT_MIN_LEN { + return Err(Error::InvalidSUDTDataLength); + } + buf.copy_from_slice(&sudt_data[..SUDT_MIN_LEN]); + return Ok((sudt_idx, u128::from_le_bytes(buf))); +} + +pub fn verify_time_lock_expired(time_lock: u64) -> Result<(), Error> { + let old_header = load_header(0, Source::GroupInput)?; + let old_timestamp = old_header.raw().timestamp().unpack(); + let current_time = find_closest_current_time(); + if old_timestamp + time_lock > current_time { + return Err(Error::TimeLockNotExpired); + } + Ok(()) +} + +pub fn find_closest_current_time() -> u64 { + let mut latest_time = 0; + for i in 0.. { + match load_header(i, Source::HeaderDep) { + Ok(header) => { + let timestamp = header.raw().timestamp().unpack(); + if timestamp > latest_time { + latest_time = timestamp; + } + } + Err(_) => break, + } + } + latest_time +} + +pub fn verify_state_finalized(state: &ChannelState) -> Result<(), Error> { + if !state.is_final().to_bool() { + return Err(Error::StateNotFinal); + } + Ok(()) +} + +pub fn get_channel_action() -> Result { + let input_status_opt = load_cell_data(0, Source::GroupInput) + .ok() + .map(|data| ChannelStatus::from_slice(data.as_slice())) + .map_or(Ok(None), |v| v.map(Some))?; + + let output_status_opt = load_cell_data(0, Source::GroupOutput) + .ok() + .map(|data| ChannelStatus::from_slice(data.as_slice())) + .map_or(Ok(None), |v| v.map(Some))?; + + match (input_status_opt, output_status_opt) { + (Some(old_status), Some(new_status)) => Ok(ChannelAction::Progress { + old_status, + new_status, + }), + (Some(old_status), None) => Ok(ChannelAction::Close { old_status }), + (None, Some(new_status)) => Ok(ChannelAction::Start { new_status }), + (None, None) => Err(Error::UnableToLoadAnyChannelStatus), + } +} + +/// verify_max_one_channel verifies that there is at most one channel in the group input and group output respectively. +pub fn verify_max_one_channel() -> Result<(), Error> { + if count_cells(Source::GroupInput)? > 1 || count_cells(Source::GroupOutput)? > 1 { + return Err(Error::MoreThanOneChannel); + } else { + return Ok(()); + } +} + +pub fn count_cells(source: Source) -> Result { + let mut null_buf: [u8; 0] = []; + for i in 0.. { + match syscalls::load_cell(&mut null_buf, 0, i, source) { + Ok(_) => continue, + Err(SysError::LengthNotEnough(_)) => continue, + Err(SysError::IndexOutOfBound) => return Ok(i), + Err(err) => return Err(err.into()), + } + } + Ok(0) +} + +pub fn verify_different_payment_addresses( + channel_constants: &ChannelConstants, +) -> Result<(), Error> { + if channel_constants + .params() + .party_a() + .payment_script_hash() + .unpack()[..] + == channel_constants + .params() + .party_b() + .payment_script_hash() + .unpack()[..] + { + return Err(Error::SamePaymentAddress); + } + Ok(()) +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/main.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/main.rs new file mode 100644 index 0000000..9306fc4 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-channel-typescript/src/main.rs @@ -0,0 +1,32 @@ +//! Generated by capsule +//! +//! `main.rs` is used to define rust lang items and modules. +//! See `entry.rs` for the `main` function. +//! See `error.rs` for the `Error` type. + +#![no_std] +#![no_main] +#![feature(asm_sym)] +#![feature(lang_items)] +#![feature(alloc_error_handler)] +#![feature(panic_info_message)] + +// define modules +mod entry; + +use ckb_std::default_alloc; +use core::arch::asm; + +ckb_std::entry!(program_entry); +default_alloc!(); + +/// program entry +/// +/// Both `argc` and `argv` can be omitted. +fn program_entry(_argc: u64, _argv: *const *const u8) -> i8 { + // Call main function and return error code + match entry::main() { + Ok(_) => 0, + Err(err) => err as i8, + } +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/Cargo.toml b/payment-channel-ckb/devnet/contracts/contracts/perun-common/Cargo.toml new file mode 100644 index 0000000..fb7ec7b --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "perun-common" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ckb-std = "0.10.0" +blake2b-rs = "0.2.0" +ckb-standalone-types = { version = "0.1.2", default-features = false, optional = true } +ckb-types = { version = "=0.108.0", optional = true } +k256 = { version = "0.11.6", default-features = false, features = ["ecdsa", "keccak256", "arithmetic"]} +alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" } +core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" } +buddy-alloc = { version = "0.4.2", optional = true } +ckb-occupied-capacity = { version = "0.108.0", optional = true } + +[dependencies.molecule] +version = "0.7.3" +default-features = false + +[features] +default = ["contract"] +testing = ["std", "ckb-types", "ckb-occupied-capacity"] +std = [] +contract = ["ckb-standalone-types"] diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/blockchain.mol b/payment-channel-ckb/devnet/contracts/contracts/perun-common/blockchain.mol new file mode 100644 index 0000000..091441c --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/blockchain.mol @@ -0,0 +1,108 @@ +/* Basic Types */ + +array Uint32 [byte; 4]; +array Uint64 [byte; 8]; +array Uint128 [byte; 16]; +array Byte32 [byte; 32]; +array Uint256 [byte; 32]; + +vector Bytes ; +option BytesOpt (Bytes); + +vector BytesVec ; +vector Byte32Vec ; + +/* Types for Chain */ + +option ScriptOpt (Script); + +array ProposalShortId [byte; 10]; + +vector UncleBlockVec ; +vector TransactionVec ; +vector ProposalShortIdVec ; +vector CellDepVec ; +vector CellInputVec ; +vector CellOutputVec ; + +table Script { + code_hash: Byte32, + hash_type: byte, + args: Bytes, +} + +struct OutPoint { + tx_hash: Byte32, + index: Uint32, +} + +struct CellInput { + since: Uint64, + previous_output: OutPoint, +} + +table CellOutput { + capacity: Uint64, + lock: Script, + type_: ScriptOpt, +} + +struct CellDep { + out_point: OutPoint, + dep_type: byte, +} + +table RawTransaction { + version: Uint32, + cell_deps: CellDepVec, + header_deps: Byte32Vec, + inputs: CellInputVec, + outputs: CellOutputVec, + outputs_data: BytesVec, +} + +table Transaction { + raw: RawTransaction, + witnesses: BytesVec, +} + +struct RawHeader { + version: Uint32, + compact_target: Uint32, + timestamp: Uint64, + number: Uint64, + epoch: Uint64, + parent_hash: Byte32, + transactions_root: Byte32, + proposals_hash: Byte32, + uncles_hash: Byte32, + dao: Byte32, +} + +struct Header { + raw: RawHeader, + nonce: Uint128, +} + +table UncleBlock { + header: Header, + proposals: ProposalShortIdVec, +} + +table Block { + header: Header, + uncles: UncleBlockVec, + transactions: TransactionVec, + proposals: ProposalShortIdVec, +} + +table CellbaseWitness { + lock: Script, + message: Bytes, +} + +table WitnessArgs { + lock: BytesOpt, // Lock args + input_type: BytesOpt, // Type args for input + output_type: BytesOpt, // Type args for output +} \ No newline at end of file diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/offchain_types.mol b/payment-channel-ckb/devnet/contracts/contracts/perun-common/offchain_types.mol new file mode 100644 index 0000000..ba4758e --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/offchain_types.mol @@ -0,0 +1,8 @@ +import blockchain; +import types; + +table OffChainParticipant { + pub_key: SEC1EncodedPubKey, + payment_script: Script, + unlock_script: Script, +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/error.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/error.rs new file mode 100644 index 0000000..c40a0e7 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/error.rs @@ -0,0 +1,115 @@ +use core::fmt::Debug; + +use ckb_std::error::SysError; +use k256::ecdsa::Error as SigError; +use molecule::error::VerificationError; + +/// Error +#[derive(Debug)] +#[repr(i8)] +pub enum Error { + // System Errors + IndexOutOfBound = 1, + ItemMissing, + LengthNotEnough, + Encoding, + // Verification Errors + TotalSizeNotMatch, + HeaderIsBroken, + UnknownItem, + OffsetsNotMatch, + FieldCountNotMatch, + + // Signature Errors + SignatureVerificationError, + + // Add customized errors here... + NoArgs, + NoWitness, + ChannelIdMismatch, + VersionNumberNotIncreasing, + StateIsFinal, + StateNotFinal, + ChannelNotFunded, + NotParticipant, + SumOfBalancesNotEqual, + OwnIndexNotFound, + ChannelDoesNotContinue, + MultipleMatchingOutputs, + FundsInInputs, + AppChannelsNotSupported, + NonLedgerChannelsNotSupported, + VirtualChannelsNotSupported, + ChannelStateNotEqual, + FundingChanged, + FundingNotInStatus, + OwnFundingNotInOutputs, + FundedBitStatusNotCorrect, + StateIsFunded, + + ChannelFundWithoutChannelOutput, + ChannelDisputeWithoutChannelOutput, + ChannelCloseWithChannelOutput, + ChannelForceCloseWithChannelOutput, + ChannelAbortWithChannelOutput, + + InvalidThreadToken, + InvalidChannelId, + StartWithNonZeroVersion, + StartWithFinalizedState, + InvalidPCLSCodeHash, + InvalidPCLSHashType, + PCLSWithArgs, + StatusDisputed, + StatusNotDisputed, + FundingNotZero, + NotAllPayed, + TimeLockNotExpired, + InvalidTimestamp, + UnableToLoadAnyChannelStatus, + InvalidSignature, + InvalidMessage, + InvalidPFLSInOutputs, + PCTSNotFound, + FoundDifferentChannel, + MoreThanOneChannel, + BalanceBelowPFLSMinCapacity, + SamePaymentAddress, + TypeScriptInPaymentOutput, + TypeScriptInPFLSOutput, + InvalidSUDT, + InvalidSUDTDataLength, + DecreasingAmount, +} + +impl From for Error { + fn from(err: SysError) -> Self { + use SysError::*; + match err { + IndexOutOfBound => Self::IndexOutOfBound, + ItemMissing => Self::ItemMissing, + LengthNotEnough(_) => Self::LengthNotEnough, + Encoding => Self::Encoding, + Unknown(err_code) => panic!("unexpected sys error {}", err_code), + } + } +} + +impl From for Error { + fn from(err: VerificationError) -> Self { + use VerificationError::*; + match err { + TotalSizeNotMatch(_, _, _) => Self::TotalSizeNotMatch, + HeaderIsBroken(_, _, _) => Self::HeaderIsBroken, + UnknownItem(_, _, _) => Self::UnknownItem, + OffsetsNotMatch(_) => Self::OffsetsNotMatch, + FieldCountNotMatch(_, _, _) => Self::FieldCountNotMatch, + } + } +} + +impl From for Error { + fn from(_: SigError) -> Self { + return Self::SignatureVerificationError; + } +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/helpers.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/helpers.rs new file mode 100644 index 0000000..e5f6e79 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/helpers.rs @@ -0,0 +1,448 @@ +use blake2b_rs::Blake2bBuilder; + +#[cfg(feature = "std")] +use { + crate::perun_types::ChannelState, ckb_types::bytes, ckb_types::packed::*, + ckb_types::prelude::*, std::vec::Vec, +}; + +#[cfg(not(feature = "std"))] +use { + ckb_standalone_types::packed::*, + ckb_standalone_types::prelude::*, + molecule::prelude::{vec, Vec}, +}; + +use crate::perun_types::{ + Balances, Bool, BoolUnion, ChannelParameters, ChannelStatus, SEC1EncodedPubKey, +}; +use crate::{ + error::Error, + perun_types::{CKByteDistribution, SUDTAllocation, SUDTBalances, SUDTDistribution}, +}; + +impl Bool { + pub fn to_bool(&self) -> bool { + match self.to_enum() { + BoolUnion::True(_) => true, + BoolUnion::False(_) => false, + } + } + pub fn from_bool(b: bool) -> Self { + if b { + return ctrue!(); + } else { + return cfalse!(); + } + } +} + +#[macro_export] +macro_rules! ctrue { + () => { + $crate::perun_types::BoolBuilder::default() + .set($crate::perun_types::BoolUnion::True( + $crate::perun_types::True::default(), + )) + .build() + }; +} +pub(crate) use ctrue; + +#[macro_export] +macro_rules! cfalse { + () => { + $crate::perun_types::BoolBuilder::default() + .set($crate::perun_types::BoolUnion::False( + $crate::perun_types::False::default(), + )) + .build() + }; +} +pub(crate) use cfalse; + +#[macro_export] +macro_rules! redeemer { + ($name:ident) => { + $crate::perun_types::ChannelWitnessBuilder::default() + .set($crate::perun_types::ChannelWitnessUnion::$name( + Default::default(), + )) + .build() + }; + ($x:expr) => { + $crate::perun_types::ChannelWitnessBuilder::default() + .set($x) + .build() + }; +} + +#[macro_export] +macro_rules! fund { + () => { + $crate::perun_types::ChannelWitnessUnion::Fund($crate::perun_types::Fund::default()) + }; +} + +#[macro_export] +macro_rules! close { + ($state:expr, $siga:expr, $sigb:expr) => { + $crate::perun_types::ChannelWitnessUnion::Close( + $crate::perun_types::Close::new_builder() + .state($state) + .sig_a($siga) + .sig_b($sigb) + .build(), + ) + }; +} + +#[macro_export] +macro_rules! dispute { + ($siga:expr, $sigb:expr) => { + $crate::perun_types::ChannelWitnessUnion::Dispute( + $crate::perun_types::Dispute::new_builder() + .sig_a($siga) + .sig_b($sigb) + .build(), + ) + }; +} + +impl SUDTDistribution { + pub fn sum(&self) -> u128 { + let a: u128 = self.nth0().unpack(); + let b: u128 = self.nth1().unpack(); + a + b + } + + pub fn equal(&self, other: &Balances) -> bool { + self.as_slice()[..] == other.as_slice()[..] + } + + pub fn get(&self, i: usize) -> Result { + match i { + 0 => Ok(self.nth0().unpack()), + 1 => Ok(self.nth1().unpack()), + _ => Err(Error::IndexOutOfBound), + } + } + + pub fn clear_index(&self, idx: usize) -> Result { + match idx { + 0 => Ok(self.clone().as_builder().nth0(0u128.pack()).build()), + 1 => Ok(self.clone().as_builder().nth1(0u128.pack()).build()), + _ => Err(Error::IndexOutOfBound), + } + } + + pub fn from_array(a: [u128; 2]) -> Self { + SUDTDistribution::new_builder() + .nth0(a[0].pack()) + .nth1(a[1].pack()) + .build() + } + + pub fn to_array(&self) -> [u128; 2] { + [self.nth0().unpack(), self.nth1().unpack()] + } +} + +impl Balances { + pub fn clear_index(&self, idx: usize) -> Result { + let ckbytes = self.ckbytes().clear_index(idx)?; + let mut sudts: Vec = Vec::new(); + for sb in self.sudts().into_iter() { + sudts.push( + sb.clone() + .as_builder() + .distribution(sb.distribution().clear_index(idx)?) + .build(), + ); + } + Ok(self + .clone() + .as_builder() + .ckbytes(ckbytes) + .sudts(SUDTAllocation::new_builder().set(sudts).build()) + .build()) + } + + pub fn zero_at_index(&self, idx: usize) -> Result { + if self.ckbytes().get(idx)? != 0u64 { + return Ok(false); + } + for sb in self.sudts().into_iter() { + if sb.distribution().get(idx)? != 0u128 { + return Ok(false); + } + } + return Ok(true); + } + + pub fn equal_at_index(&self, other: &Balances, idx: usize) -> Result { + if self.ckbytes().get(idx)? != other.ckbytes().get(idx)? { + return Ok(false); + } + if self.sudts().len() != other.sudts().len() { + return Ok(false); + } + for (i, sb) in self.sudts().into_iter().enumerate() { + let other_sb = other.sudts().get(i).ok_or(Error::IndexOutOfBound)?; + if sb.asset().as_slice() != other_sb.as_slice() { + return Ok(false); + } + if sb.distribution().get(idx)? != other_sb.distribution().get(idx)? { + return Ok(false); + } + } + return Ok(true); + } + + pub fn equal_in_sum(&self, other: &Balances) -> Result { + if self.ckbytes().sum() != other.ckbytes().sum() { + return Ok(false); + } + if self.sudts().len() != other.sudts().len() { + return Ok(false); + } + for (i, sb) in self.sudts().into_iter().enumerate() { + let other_sb = other.sudts().get(i).ok_or(Error::IndexOutOfBound)?; + if sb.asset().as_slice() != other_sb.asset().as_slice() { + return Ok(false); + } + if sb.distribution().sum() != other_sb.distribution().sum() { + return Ok(false); + } + } + return Ok(true); + } + + pub fn equal(&self, other: &Balances) -> bool { + self.as_slice()[..] == other.as_slice()[..] + } +} + +impl SUDTAllocation { + pub fn get_locked_ckbytes(&self) -> u64 { + let mut sum: u64 = 0u64; + for sudt in self.clone().into_iter() { + let min_cap: u64 = sudt.asset().max_capacity().unpack(); + sum += min_cap; + } + return sum; + } + + pub fn get_distribution(&self, sudt: &Script) -> Result<(usize, SUDTDistribution), Error> { + for (i, sb) in self.clone().into_iter().enumerate() { + if sb.asset().type_script().as_slice() == sudt.as_slice() { + return Ok((i, sb.distribution())); + } + } + return Err(Error::InvalidSUDT); + } + + pub fn fully_represented(&self, idx: usize, values: &[u128]) -> Result { + if values.len() < self.len() { + return Ok(false); + } + for (i, sb) in self.clone().into_iter().enumerate() { + let v = sb.distribution().get(idx)?; + if values[i] < v { + return Ok(false); + } + } + return Ok(true); + } +} + +impl CKByteDistribution { + pub fn sum(&self) -> u64 { + let a: u64 = self.nth0().unpack(); + let b: u64 = self.nth1().unpack(); + a + b + } + + pub fn equal(&self, other: &Balances) -> bool { + self.as_slice()[..] == other.as_slice()[..] + } + + pub fn get(&self, i: usize) -> Result { + match i { + 0 => Ok(self.nth0().unpack()), + 1 => Ok(self.nth1().unpack()), + _ => Err(Error::IndexOutOfBound), + } + } + + pub fn clear_index(&self, idx: usize) -> Result { + match idx { + 0 => Ok(self.clone().as_builder().nth0(0u64.pack()).build()), + 1 => Ok(self.clone().as_builder().nth1(0u64.pack()).build()), + _ => Err(Error::IndexOutOfBound), + } + } + + pub fn from_array(array: [u64; 2]) -> Self { + CKByteDistribution::new_builder() + .nth0(array[0].pack()) + .nth1(array[1].pack()) + .build() + } + + pub fn to_array(&self) -> [u64; 2] { + [self.nth0().unpack(), self.nth1().unpack()] + } +} + +pub fn geq_components(fst: &CKByteDistribution, snd: &CKByteDistribution) -> bool { + let a_fst: u64 = fst.nth0().unpack(); + let a_snd: u64 = snd.nth0().unpack(); + let b_fst: u64 = fst.nth1().unpack(); + let b_snd: u64 = snd.nth1().unpack(); + a_fst >= a_snd && b_fst >= b_snd +} + +pub const CKB_HASH_PERSONALIZATION: &[u8] = b"ckb-default-hash"; + +pub fn blake2b256(data: &[u8]) -> [u8; 32] { + let mut result = [0u8; 32]; + let mut blake2b = Blake2bBuilder::new(32) + //.personal(CKB_HASH_PERSONALIZATION) + .build(); + blake2b.update(data); + blake2b.finalize(&mut result); + result +} + +impl ChannelStatus { + // mk_funded creates a new ChannelStatus with the funded flag set to true. + pub fn mk_funded(self) -> ChannelStatus { + self.clone().as_builder().funded(ctrue!()).build() + } + + #[cfg(feature = "std")] + /// mk_close_outputs creates the outputs for a close transaction according to the current + /// channel state. It does not matter whether the ChannelState in question is finalized or not. + pub fn mk_close_outputs( + self, + mk_lock_script: impl FnMut(u8) -> Script, + ) -> Vec<(CellOutput, bytes::Bytes)> { + self.state().mk_outputs(mk_lock_script) + } +} + +#[cfg(feature = "std")] +impl ChannelState { + pub fn mk_outputs( + self, + mk_lock_script: impl FnMut(u8) -> Script, + ) -> Vec<(CellOutput, bytes::Bytes)> { + return self.balances().mk_outputs(mk_lock_script, vec![0, 1]); + } +} + +#[cfg(feature = "std")] +impl Balances { + pub fn mk_outputs( + self, + mut mk_lock_script: impl FnMut(u8) -> Script, + indices: Vec, + ) -> Vec<(CellOutput, bytes::Bytes)> { + let mut ckbytes = self + .ckbytes() + .mk_outputs(&mut mk_lock_script, indices.clone()); + let mut sudts = self.sudts().mk_outputs(mk_lock_script, indices); + ckbytes.append(&mut sudts); + return ckbytes; + } +} + +#[cfg(feature = "std")] +impl CKByteDistribution { + pub fn mk_outputs( + self, + mut mk_lock_script: impl FnMut(u8) -> Script, + indices: Vec, + ) -> Vec<(CellOutput, bytes::Bytes)> { + // TODO: Outputs should contain min-capacity for script size... + indices + .iter() + .fold(vec![], |mut acc: Vec<(CellOutput, bytes::Bytes)>, index| { + let cap = self.get(index.clone() as usize).expect("invalid index"); + acc.push(( + CellOutput::new_builder() + .capacity(cap.pack()) + .lock(mk_lock_script(*index)) + .build(), + bytes::Bytes::new(), + )); + acc + }) + } +} + +#[cfg(feature = "std")] +impl SUDTAllocation { + pub fn mk_outputs( + self, + mut mk_lock_script: impl FnMut(u8) -> Script, + indices: Vec, + ) -> Vec<(CellOutput, bytes::Bytes)> { + let mut outputs: Vec<(CellOutput, bytes::Bytes)> = Vec::new(); + for (i, balance) in self.into_iter().enumerate() { + let udt_type = balance.asset().type_script(); + let udt_type_opt = ScriptOpt::new_builder().set(Some(udt_type)).build(); + let cap: u64 = balance.asset().max_capacity().unpack(); + for f in indices.iter() { + if balance + .distribution() + .get(*f as usize) + .expect("invalid index") + == 0u128 + { + outputs.push(( + CellOutput::new_builder() + .capacity(cap.pack()) + .lock(mk_lock_script(*f)) + .build(), + bytes::Bytes::new(), + )); + } else { + outputs.push(( + CellOutput::new_builder() + .capacity(cap.pack()) + .lock(mk_lock_script(*f)) + .type_(udt_type_opt.clone()) + .build(), + bytes::Bytes::from( + balance + .distribution() + .get(*f as usize) + .expect("invalid index") + .to_le_bytes() + .to_vec(), + ), + )); + } + } + } + return outputs; + } +} + +impl ChannelParameters { + /// mk_party_pubkeys creates a vector of each participants public key in the correct order. + pub fn mk_party_pubkeys(self) -> Vec> { + vec![ + self.party_a().pub_key().to_vec(), + self.party_b().pub_key().to_vec(), + ] + } +} + +impl SEC1EncodedPubKey { + pub fn to_vec(&self) -> Vec { + self.as_bytes().to_vec() + } +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/lib.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/lib.rs new file mode 100644 index 0000000..39d0017 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/lib.rs @@ -0,0 +1,7 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod error; +pub mod helpers; +#[allow(clippy::all)] +pub mod perun_types; +pub mod sig; diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/perun_types.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/perun_types.rs new file mode 100644 index 0000000..61fe220 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/perun_types.rs @@ -0,0 +1,6561 @@ +// Generated by Molecule 0.7.3 +#![allow(unused_imports)] + +#[cfg(feature = "std")] +use {ckb_types::packed::*, ckb_types::prelude::*}; + +#[cfg(not(feature = "std"))] +use {ckb_standalone_types::packed::*, ckb_standalone_types::prelude::*}; + +use molecule::prelude::*; + +#[derive(Clone)] +pub struct SEC1EncodedPubKey(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for SEC1EncodedPubKey { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for SEC1EncodedPubKey { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for SEC1EncodedPubKey { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for SEC1EncodedPubKey { + fn default() -> Self { + let v: Vec = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + SEC1EncodedPubKey::new_unchecked(v.into()) + } +} +impl SEC1EncodedPubKey { + pub const TOTAL_SIZE: usize = 33; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 33; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn nth1(&self) -> Byte { + Byte::new_unchecked(self.0.slice(1..2)) + } + pub fn nth2(&self) -> Byte { + Byte::new_unchecked(self.0.slice(2..3)) + } + pub fn nth3(&self) -> Byte { + Byte::new_unchecked(self.0.slice(3..4)) + } + pub fn nth4(&self) -> Byte { + Byte::new_unchecked(self.0.slice(4..5)) + } + pub fn nth5(&self) -> Byte { + Byte::new_unchecked(self.0.slice(5..6)) + } + pub fn nth6(&self) -> Byte { + Byte::new_unchecked(self.0.slice(6..7)) + } + pub fn nth7(&self) -> Byte { + Byte::new_unchecked(self.0.slice(7..8)) + } + pub fn nth8(&self) -> Byte { + Byte::new_unchecked(self.0.slice(8..9)) + } + pub fn nth9(&self) -> Byte { + Byte::new_unchecked(self.0.slice(9..10)) + } + pub fn nth10(&self) -> Byte { + Byte::new_unchecked(self.0.slice(10..11)) + } + pub fn nth11(&self) -> Byte { + Byte::new_unchecked(self.0.slice(11..12)) + } + pub fn nth12(&self) -> Byte { + Byte::new_unchecked(self.0.slice(12..13)) + } + pub fn nth13(&self) -> Byte { + Byte::new_unchecked(self.0.slice(13..14)) + } + pub fn nth14(&self) -> Byte { + Byte::new_unchecked(self.0.slice(14..15)) + } + pub fn nth15(&self) -> Byte { + Byte::new_unchecked(self.0.slice(15..16)) + } + pub fn nth16(&self) -> Byte { + Byte::new_unchecked(self.0.slice(16..17)) + } + pub fn nth17(&self) -> Byte { + Byte::new_unchecked(self.0.slice(17..18)) + } + pub fn nth18(&self) -> Byte { + Byte::new_unchecked(self.0.slice(18..19)) + } + pub fn nth19(&self) -> Byte { + Byte::new_unchecked(self.0.slice(19..20)) + } + pub fn nth20(&self) -> Byte { + Byte::new_unchecked(self.0.slice(20..21)) + } + pub fn nth21(&self) -> Byte { + Byte::new_unchecked(self.0.slice(21..22)) + } + pub fn nth22(&self) -> Byte { + Byte::new_unchecked(self.0.slice(22..23)) + } + pub fn nth23(&self) -> Byte { + Byte::new_unchecked(self.0.slice(23..24)) + } + pub fn nth24(&self) -> Byte { + Byte::new_unchecked(self.0.slice(24..25)) + } + pub fn nth25(&self) -> Byte { + Byte::new_unchecked(self.0.slice(25..26)) + } + pub fn nth26(&self) -> Byte { + Byte::new_unchecked(self.0.slice(26..27)) + } + pub fn nth27(&self) -> Byte { + Byte::new_unchecked(self.0.slice(27..28)) + } + pub fn nth28(&self) -> Byte { + Byte::new_unchecked(self.0.slice(28..29)) + } + pub fn nth29(&self) -> Byte { + Byte::new_unchecked(self.0.slice(29..30)) + } + pub fn nth30(&self) -> Byte { + Byte::new_unchecked(self.0.slice(30..31)) + } + pub fn nth31(&self) -> Byte { + Byte::new_unchecked(self.0.slice(31..32)) + } + pub fn nth32(&self) -> Byte { + Byte::new_unchecked(self.0.slice(32..33)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> SEC1EncodedPubKeyReader<'r> { + SEC1EncodedPubKeyReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for SEC1EncodedPubKey { + type Builder = SEC1EncodedPubKeyBuilder; + const NAME: &'static str = "SEC1EncodedPubKey"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + SEC1EncodedPubKey(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SEC1EncodedPubKeyReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SEC1EncodedPubKeyReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([ + self.nth0(), + self.nth1(), + self.nth2(), + self.nth3(), + self.nth4(), + self.nth5(), + self.nth6(), + self.nth7(), + self.nth8(), + self.nth9(), + self.nth10(), + self.nth11(), + self.nth12(), + self.nth13(), + self.nth14(), + self.nth15(), + self.nth16(), + self.nth17(), + self.nth18(), + self.nth19(), + self.nth20(), + self.nth21(), + self.nth22(), + self.nth23(), + self.nth24(), + self.nth25(), + self.nth26(), + self.nth27(), + self.nth28(), + self.nth29(), + self.nth30(), + self.nth31(), + self.nth32(), + ]) + } +} +#[derive(Clone, Copy)] +pub struct SEC1EncodedPubKeyReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for SEC1EncodedPubKeyReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for SEC1EncodedPubKeyReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for SEC1EncodedPubKeyReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> SEC1EncodedPubKeyReader<'r> { + pub const TOTAL_SIZE: usize = 33; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 33; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn nth1(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[1..2]) + } + pub fn nth2(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[2..3]) + } + pub fn nth3(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[3..4]) + } + pub fn nth4(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[4..5]) + } + pub fn nth5(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[5..6]) + } + pub fn nth6(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[6..7]) + } + pub fn nth7(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[7..8]) + } + pub fn nth8(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[8..9]) + } + pub fn nth9(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[9..10]) + } + pub fn nth10(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[10..11]) + } + pub fn nth11(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[11..12]) + } + pub fn nth12(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[12..13]) + } + pub fn nth13(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[13..14]) + } + pub fn nth14(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[14..15]) + } + pub fn nth15(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[15..16]) + } + pub fn nth16(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[16..17]) + } + pub fn nth17(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[17..18]) + } + pub fn nth18(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[18..19]) + } + pub fn nth19(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[19..20]) + } + pub fn nth20(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[20..21]) + } + pub fn nth21(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[21..22]) + } + pub fn nth22(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[22..23]) + } + pub fn nth23(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[23..24]) + } + pub fn nth24(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[24..25]) + } + pub fn nth25(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[25..26]) + } + pub fn nth26(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[26..27]) + } + pub fn nth27(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[27..28]) + } + pub fn nth28(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[28..29]) + } + pub fn nth29(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[29..30]) + } + pub fn nth30(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[30..31]) + } + pub fn nth31(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[31..32]) + } + pub fn nth32(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[32..33]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for SEC1EncodedPubKeyReader<'r> { + type Entity = SEC1EncodedPubKey; + const NAME: &'static str = "SEC1EncodedPubKeyReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + SEC1EncodedPubKeyReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct SEC1EncodedPubKeyBuilder(pub(crate) [Byte; 33]); +impl ::core::fmt::Debug for SEC1EncodedPubKeyBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for SEC1EncodedPubKeyBuilder { + fn default() -> Self { + SEC1EncodedPubKeyBuilder([ + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + Byte::default(), + ]) + } +} +impl SEC1EncodedPubKeyBuilder { + pub const TOTAL_SIZE: usize = 33; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 33; + pub fn set(mut self, v: [Byte; 33]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } + pub fn nth1(mut self, v: Byte) -> Self { + self.0[1] = v; + self + } + pub fn nth2(mut self, v: Byte) -> Self { + self.0[2] = v; + self + } + pub fn nth3(mut self, v: Byte) -> Self { + self.0[3] = v; + self + } + pub fn nth4(mut self, v: Byte) -> Self { + self.0[4] = v; + self + } + pub fn nth5(mut self, v: Byte) -> Self { + self.0[5] = v; + self + } + pub fn nth6(mut self, v: Byte) -> Self { + self.0[6] = v; + self + } + pub fn nth7(mut self, v: Byte) -> Self { + self.0[7] = v; + self + } + pub fn nth8(mut self, v: Byte) -> Self { + self.0[8] = v; + self + } + pub fn nth9(mut self, v: Byte) -> Self { + self.0[9] = v; + self + } + pub fn nth10(mut self, v: Byte) -> Self { + self.0[10] = v; + self + } + pub fn nth11(mut self, v: Byte) -> Self { + self.0[11] = v; + self + } + pub fn nth12(mut self, v: Byte) -> Self { + self.0[12] = v; + self + } + pub fn nth13(mut self, v: Byte) -> Self { + self.0[13] = v; + self + } + pub fn nth14(mut self, v: Byte) -> Self { + self.0[14] = v; + self + } + pub fn nth15(mut self, v: Byte) -> Self { + self.0[15] = v; + self + } + pub fn nth16(mut self, v: Byte) -> Self { + self.0[16] = v; + self + } + pub fn nth17(mut self, v: Byte) -> Self { + self.0[17] = v; + self + } + pub fn nth18(mut self, v: Byte) -> Self { + self.0[18] = v; + self + } + pub fn nth19(mut self, v: Byte) -> Self { + self.0[19] = v; + self + } + pub fn nth20(mut self, v: Byte) -> Self { + self.0[20] = v; + self + } + pub fn nth21(mut self, v: Byte) -> Self { + self.0[21] = v; + self + } + pub fn nth22(mut self, v: Byte) -> Self { + self.0[22] = v; + self + } + pub fn nth23(mut self, v: Byte) -> Self { + self.0[23] = v; + self + } + pub fn nth24(mut self, v: Byte) -> Self { + self.0[24] = v; + self + } + pub fn nth25(mut self, v: Byte) -> Self { + self.0[25] = v; + self + } + pub fn nth26(mut self, v: Byte) -> Self { + self.0[26] = v; + self + } + pub fn nth27(mut self, v: Byte) -> Self { + self.0[27] = v; + self + } + pub fn nth28(mut self, v: Byte) -> Self { + self.0[28] = v; + self + } + pub fn nth29(mut self, v: Byte) -> Self { + self.0[29] = v; + self + } + pub fn nth30(mut self, v: Byte) -> Self { + self.0[30] = v; + self + } + pub fn nth31(mut self, v: Byte) -> Self { + self.0[31] = v; + self + } + pub fn nth32(mut self, v: Byte) -> Self { + self.0[32] = v; + self + } +} +impl molecule::prelude::Builder for SEC1EncodedPubKeyBuilder { + type Entity = SEC1EncodedPubKey; + const NAME: &'static str = "SEC1EncodedPubKeyBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + writer.write_all(self.0[1].as_slice())?; + writer.write_all(self.0[2].as_slice())?; + writer.write_all(self.0[3].as_slice())?; + writer.write_all(self.0[4].as_slice())?; + writer.write_all(self.0[5].as_slice())?; + writer.write_all(self.0[6].as_slice())?; + writer.write_all(self.0[7].as_slice())?; + writer.write_all(self.0[8].as_slice())?; + writer.write_all(self.0[9].as_slice())?; + writer.write_all(self.0[10].as_slice())?; + writer.write_all(self.0[11].as_slice())?; + writer.write_all(self.0[12].as_slice())?; + writer.write_all(self.0[13].as_slice())?; + writer.write_all(self.0[14].as_slice())?; + writer.write_all(self.0[15].as_slice())?; + writer.write_all(self.0[16].as_slice())?; + writer.write_all(self.0[17].as_slice())?; + writer.write_all(self.0[18].as_slice())?; + writer.write_all(self.0[19].as_slice())?; + writer.write_all(self.0[20].as_slice())?; + writer.write_all(self.0[21].as_slice())?; + writer.write_all(self.0[22].as_slice())?; + writer.write_all(self.0[23].as_slice())?; + writer.write_all(self.0[24].as_slice())?; + writer.write_all(self.0[25].as_slice())?; + writer.write_all(self.0[26].as_slice())?; + writer.write_all(self.0[27].as_slice())?; + writer.write_all(self.0[28].as_slice())?; + writer.write_all(self.0[29].as_slice())?; + writer.write_all(self.0[30].as_slice())?; + writer.write_all(self.0[31].as_slice())?; + writer.write_all(self.0[32].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + SEC1EncodedPubKey::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct CKByteDistribution(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for CKByteDistribution { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for CKByteDistribution { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for CKByteDistribution { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + write!(f, "{}", self.nth0())?; + write!(f, ", {}", self.nth1())?; + write!(f, "]") + } +} +impl ::core::default::Default for CKByteDistribution { + fn default() -> Self { + let v: Vec = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + CKByteDistribution::new_unchecked(v.into()) + } +} +impl CKByteDistribution { + pub const TOTAL_SIZE: usize = 16; + pub const ITEM_SIZE: usize = 8; + pub const ITEM_COUNT: usize = 2; + pub fn nth0(&self) -> Uint64 { + Uint64::new_unchecked(self.0.slice(0..8)) + } + pub fn nth1(&self) -> Uint64 { + Uint64::new_unchecked(self.0.slice(8..16)) + } + pub fn as_reader<'r>(&'r self) -> CKByteDistributionReader<'r> { + CKByteDistributionReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for CKByteDistribution { + type Builder = CKByteDistributionBuilder; + const NAME: &'static str = "CKByteDistribution"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + CKByteDistribution(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + CKByteDistributionReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + CKByteDistributionReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0(), self.nth1()]) + } +} +#[derive(Clone, Copy)] +pub struct CKByteDistributionReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for CKByteDistributionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for CKByteDistributionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for CKByteDistributionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + write!(f, "{}", self.nth0())?; + write!(f, ", {}", self.nth1())?; + write!(f, "]") + } +} +impl<'r> CKByteDistributionReader<'r> { + pub const TOTAL_SIZE: usize = 16; + pub const ITEM_SIZE: usize = 8; + pub const ITEM_COUNT: usize = 2; + pub fn nth0(&self) -> Uint64Reader<'r> { + Uint64Reader::new_unchecked(&self.as_slice()[0..8]) + } + pub fn nth1(&self) -> Uint64Reader<'r> { + Uint64Reader::new_unchecked(&self.as_slice()[8..16]) + } +} +impl<'r> molecule::prelude::Reader<'r> for CKByteDistributionReader<'r> { + type Entity = CKByteDistribution; + const NAME: &'static str = "CKByteDistributionReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + CKByteDistributionReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct CKByteDistributionBuilder(pub(crate) [Uint64; 2]); +impl ::core::fmt::Debug for CKByteDistributionBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for CKByteDistributionBuilder { + fn default() -> Self { + CKByteDistributionBuilder([Uint64::default(), Uint64::default()]) + } +} +impl CKByteDistributionBuilder { + pub const TOTAL_SIZE: usize = 16; + pub const ITEM_SIZE: usize = 8; + pub const ITEM_COUNT: usize = 2; + pub fn set(mut self, v: [Uint64; 2]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Uint64) -> Self { + self.0[0] = v; + self + } + pub fn nth1(mut self, v: Uint64) -> Self { + self.0[1] = v; + self + } +} +impl molecule::prelude::Builder for CKByteDistributionBuilder { + type Entity = CKByteDistribution; + const NAME: &'static str = "CKByteDistributionBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + writer.write_all(self.0[1].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + CKByteDistribution::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct SUDTDistribution(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for SUDTDistribution { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for SUDTDistribution { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for SUDTDistribution { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + write!(f, "{}", self.nth0())?; + write!(f, ", {}", self.nth1())?; + write!(f, "]") + } +} +impl ::core::default::Default for SUDTDistribution { + fn default() -> Self { + let v: Vec = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ]; + SUDTDistribution::new_unchecked(v.into()) + } +} +impl SUDTDistribution { + pub const TOTAL_SIZE: usize = 32; + pub const ITEM_SIZE: usize = 16; + pub const ITEM_COUNT: usize = 2; + pub fn nth0(&self) -> Uint128 { + Uint128::new_unchecked(self.0.slice(0..16)) + } + pub fn nth1(&self) -> Uint128 { + Uint128::new_unchecked(self.0.slice(16..32)) + } + pub fn as_reader<'r>(&'r self) -> SUDTDistributionReader<'r> { + SUDTDistributionReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for SUDTDistribution { + type Builder = SUDTDistributionBuilder; + const NAME: &'static str = "SUDTDistribution"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + SUDTDistribution(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTDistributionReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTDistributionReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0(), self.nth1()]) + } +} +#[derive(Clone, Copy)] +pub struct SUDTDistributionReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for SUDTDistributionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for SUDTDistributionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for SUDTDistributionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + write!(f, "{}", self.nth0())?; + write!(f, ", {}", self.nth1())?; + write!(f, "]") + } +} +impl<'r> SUDTDistributionReader<'r> { + pub const TOTAL_SIZE: usize = 32; + pub const ITEM_SIZE: usize = 16; + pub const ITEM_COUNT: usize = 2; + pub fn nth0(&self) -> Uint128Reader<'r> { + Uint128Reader::new_unchecked(&self.as_slice()[0..16]) + } + pub fn nth1(&self) -> Uint128Reader<'r> { + Uint128Reader::new_unchecked(&self.as_slice()[16..32]) + } +} +impl<'r> molecule::prelude::Reader<'r> for SUDTDistributionReader<'r> { + type Entity = SUDTDistribution; + const NAME: &'static str = "SUDTDistributionReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + SUDTDistributionReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct SUDTDistributionBuilder(pub(crate) [Uint128; 2]); +impl ::core::fmt::Debug for SUDTDistributionBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for SUDTDistributionBuilder { + fn default() -> Self { + SUDTDistributionBuilder([Uint128::default(), Uint128::default()]) + } +} +impl SUDTDistributionBuilder { + pub const TOTAL_SIZE: usize = 32; + pub const ITEM_SIZE: usize = 16; + pub const ITEM_COUNT: usize = 2; + pub fn set(mut self, v: [Uint128; 2]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Uint128) -> Self { + self.0[0] = v; + self + } + pub fn nth1(mut self, v: Uint128) -> Self { + self.0[1] = v; + self + } +} +impl molecule::prelude::Builder for SUDTDistributionBuilder { + type Entity = SUDTDistribution; + const NAME: &'static str = "SUDTDistributionBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + writer.write_all(self.0[1].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + SUDTDistribution::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct SUDTAllocation(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for SUDTAllocation { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for SUDTAllocation { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for SUDTAllocation { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + for i in 0..self.len() { + if i == 0 { + write!(f, "{}", self.get_unchecked(i))?; + } else { + write!(f, ", {}", self.get_unchecked(i))?; + } + } + write!(f, "]") + } +} +impl ::core::default::Default for SUDTAllocation { + fn default() -> Self { + let v: Vec = vec![4, 0, 0, 0]; + SUDTAllocation::new_unchecked(v.into()) + } +} +impl SUDTAllocation { + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn item_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn len(&self) -> usize { + self.item_count() + } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn get(&self, idx: usize) -> Option { + if idx >= self.len() { + None + } else { + Some(self.get_unchecked(idx)) + } + } + pub fn get_unchecked(&self, idx: usize) -> SUDTBalances { + let slice = self.as_slice(); + let start_idx = molecule::NUMBER_SIZE * (1 + idx); + let start = molecule::unpack_number(&slice[start_idx..]) as usize; + if idx == self.len() - 1 { + SUDTBalances::new_unchecked(self.0.slice(start..)) + } else { + let end_idx = start_idx + molecule::NUMBER_SIZE; + let end = molecule::unpack_number(&slice[end_idx..]) as usize; + SUDTBalances::new_unchecked(self.0.slice(start..end)) + } + } + pub fn as_reader<'r>(&'r self) -> SUDTAllocationReader<'r> { + SUDTAllocationReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for SUDTAllocation { + type Builder = SUDTAllocationBuilder; + const NAME: &'static str = "SUDTAllocation"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + SUDTAllocation(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTAllocationReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTAllocationReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().extend(self.into_iter()) + } +} +#[derive(Clone, Copy)] +pub struct SUDTAllocationReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for SUDTAllocationReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for SUDTAllocationReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for SUDTAllocationReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + for i in 0..self.len() { + if i == 0 { + write!(f, "{}", self.get_unchecked(i))?; + } else { + write!(f, ", {}", self.get_unchecked(i))?; + } + } + write!(f, "]") + } +} +impl<'r> SUDTAllocationReader<'r> { + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn item_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn len(&self) -> usize { + self.item_count() + } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn get(&self, idx: usize) -> Option> { + if idx >= self.len() { + None + } else { + Some(self.get_unchecked(idx)) + } + } + pub fn get_unchecked(&self, idx: usize) -> SUDTBalancesReader<'r> { + let slice = self.as_slice(); + let start_idx = molecule::NUMBER_SIZE * (1 + idx); + let start = molecule::unpack_number(&slice[start_idx..]) as usize; + if idx == self.len() - 1 { + SUDTBalancesReader::new_unchecked(&self.as_slice()[start..]) + } else { + let end_idx = start_idx + molecule::NUMBER_SIZE; + let end = molecule::unpack_number(&slice[end_idx..]) as usize; + SUDTBalancesReader::new_unchecked(&self.as_slice()[start..end]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for SUDTAllocationReader<'r> { + type Entity = SUDTAllocation; + const NAME: &'static str = "SUDTAllocationReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + SUDTAllocationReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!( + Self, + TotalSizeNotMatch, + molecule::NUMBER_SIZE * 2, + slice_len + ); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + for pair in offsets.windows(2) { + let start = pair[0]; + let end = pair[1]; + SUDTBalancesReader::verify(&slice[start..end], compatible)?; + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct SUDTAllocationBuilder(pub(crate) Vec); +impl SUDTAllocationBuilder { + pub fn set(mut self, v: Vec) -> Self { + self.0 = v; + self + } + pub fn push(mut self, v: SUDTBalances) -> Self { + self.0.push(v); + self + } + pub fn extend>(mut self, iter: T) -> Self { + for elem in iter { + self.0.push(elem); + } + self + } + pub fn replace(&mut self, index: usize, v: SUDTBalances) -> Option { + self.0 + .get_mut(index) + .map(|item| ::core::mem::replace(item, v)) + } +} +impl molecule::prelude::Builder for SUDTAllocationBuilder { + type Entity = SUDTAllocation; + const NAME: &'static str = "SUDTAllocationBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (self.0.len() + 1) + + self + .0 + .iter() + .map(|inner| inner.as_slice().len()) + .sum::() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let item_count = self.0.len(); + if item_count == 0 { + writer.write_all(&molecule::pack_number( + molecule::NUMBER_SIZE as molecule::Number, + ))?; + } else { + let (total_size, offsets) = self.0.iter().fold( + ( + molecule::NUMBER_SIZE * (item_count + 1), + Vec::with_capacity(item_count), + ), + |(start, mut offsets), inner| { + offsets.push(start); + (start + inner.as_slice().len(), offsets) + }, + ); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + for inner in self.0.iter() { + writer.write_all(inner.as_slice())?; + } + } + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + SUDTAllocation::new_unchecked(inner.into()) + } +} +pub struct SUDTAllocationIterator(SUDTAllocation, usize, usize); +impl ::core::iter::Iterator for SUDTAllocationIterator { + type Item = SUDTBalances; + fn next(&mut self) -> Option { + if self.1 >= self.2 { + None + } else { + let ret = self.0.get_unchecked(self.1); + self.1 += 1; + Some(ret) + } + } +} +impl ::core::iter::ExactSizeIterator for SUDTAllocationIterator { + fn len(&self) -> usize { + self.2 - self.1 + } +} +impl ::core::iter::IntoIterator for SUDTAllocation { + type Item = SUDTBalances; + type IntoIter = SUDTAllocationIterator; + fn into_iter(self) -> Self::IntoIter { + let len = self.len(); + SUDTAllocationIterator(self, 0, len) + } +} +impl<'r> SUDTAllocationReader<'r> { + pub fn iter<'t>(&'t self) -> SUDTAllocationReaderIterator<'t, 'r> { + SUDTAllocationReaderIterator(&self, 0, self.len()) + } +} +pub struct SUDTAllocationReaderIterator<'t, 'r>(&'t SUDTAllocationReader<'r>, usize, usize); +impl<'t: 'r, 'r> ::core::iter::Iterator for SUDTAllocationReaderIterator<'t, 'r> { + type Item = SUDTBalancesReader<'t>; + fn next(&mut self) -> Option { + if self.1 >= self.2 { + None + } else { + let ret = self.0.get_unchecked(self.1); + self.1 += 1; + Some(ret) + } + } +} +impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator for SUDTAllocationReaderIterator<'t, 'r> { + fn len(&self) -> usize { + self.2 - self.1 + } +} +#[derive(Clone)] +pub struct SUDTAsset(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for SUDTAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for SUDTAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for SUDTAsset { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "type_script", self.type_script())?; + write!(f, ", {}: {}", "max_capacity", self.max_capacity())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for SUDTAsset { + fn default() -> Self { + let v: Vec = vec![ + 73, 0, 0, 0, 12, 0, 0, 0, 65, 0, 0, 0, 53, 0, 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + SUDTAsset::new_unchecked(v.into()) + } +} +impl SUDTAsset { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn type_script(&self) -> Script { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Script::new_unchecked(self.0.slice(start..end)) + } + pub fn max_capacity(&self) -> Uint64 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + Uint64::new_unchecked(self.0.slice(start..end)) + } else { + Uint64::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> SUDTAssetReader<'r> { + SUDTAssetReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for SUDTAsset { + type Builder = SUDTAssetBuilder; + const NAME: &'static str = "SUDTAsset"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + SUDTAsset(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTAssetReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTAssetReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .type_script(self.type_script()) + .max_capacity(self.max_capacity()) + } +} +#[derive(Clone, Copy)] +pub struct SUDTAssetReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for SUDTAssetReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for SUDTAssetReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for SUDTAssetReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "type_script", self.type_script())?; + write!(f, ", {}: {}", "max_capacity", self.max_capacity())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> SUDTAssetReader<'r> { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn type_script(&self) -> ScriptReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ScriptReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn max_capacity(&self) -> Uint64Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + Uint64Reader::new_unchecked(&self.as_slice()[start..end]) + } else { + Uint64Reader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for SUDTAssetReader<'r> { + type Entity = SUDTAsset; + const NAME: &'static str = "SUDTAssetReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + SUDTAssetReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + ScriptReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + Uint64Reader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct SUDTAssetBuilder { + pub(crate) type_script: Script, + pub(crate) max_capacity: Uint64, +} +impl SUDTAssetBuilder { + pub const FIELD_COUNT: usize = 2; + pub fn type_script(mut self, v: Script) -> Self { + self.type_script = v; + self + } + pub fn max_capacity(mut self, v: Uint64) -> Self { + self.max_capacity = v; + self + } +} +impl molecule::prelude::Builder for SUDTAssetBuilder { + type Entity = SUDTAsset; + const NAME: &'static str = "SUDTAssetBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.type_script.as_slice().len() + + self.max_capacity.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.type_script.as_slice().len(); + offsets.push(total_size); + total_size += self.max_capacity.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.type_script.as_slice())?; + writer.write_all(self.max_capacity.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + SUDTAsset::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct SUDTBalances(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for SUDTBalances { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for SUDTBalances { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for SUDTBalances { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "asset", self.asset())?; + write!(f, ", {}: {}", "distribution", self.distribution())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for SUDTBalances { + fn default() -> Self { + let v: Vec = vec![ + 117, 0, 0, 0, 12, 0, 0, 0, 85, 0, 0, 0, 73, 0, 0, 0, 12, 0, 0, 0, 65, 0, 0, 0, 53, 0, + 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + ]; + SUDTBalances::new_unchecked(v.into()) + } +} +impl SUDTBalances { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn asset(&self) -> SUDTAsset { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + SUDTAsset::new_unchecked(self.0.slice(start..end)) + } + pub fn distribution(&self) -> SUDTDistribution { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + SUDTDistribution::new_unchecked(self.0.slice(start..end)) + } else { + SUDTDistribution::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> SUDTBalancesReader<'r> { + SUDTBalancesReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for SUDTBalances { + type Builder = SUDTBalancesBuilder; + const NAME: &'static str = "SUDTBalances"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + SUDTBalances(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTBalancesReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SUDTBalancesReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .asset(self.asset()) + .distribution(self.distribution()) + } +} +#[derive(Clone, Copy)] +pub struct SUDTBalancesReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for SUDTBalancesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for SUDTBalancesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for SUDTBalancesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "asset", self.asset())?; + write!(f, ", {}: {}", "distribution", self.distribution())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> SUDTBalancesReader<'r> { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn asset(&self) -> SUDTAssetReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + SUDTAssetReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn distribution(&self) -> SUDTDistributionReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + SUDTDistributionReader::new_unchecked(&self.as_slice()[start..end]) + } else { + SUDTDistributionReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for SUDTBalancesReader<'r> { + type Entity = SUDTBalances; + const NAME: &'static str = "SUDTBalancesReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + SUDTBalancesReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + SUDTAssetReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + SUDTDistributionReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct SUDTBalancesBuilder { + pub(crate) asset: SUDTAsset, + pub(crate) distribution: SUDTDistribution, +} +impl SUDTBalancesBuilder { + pub const FIELD_COUNT: usize = 2; + pub fn asset(mut self, v: SUDTAsset) -> Self { + self.asset = v; + self + } + pub fn distribution(mut self, v: SUDTDistribution) -> Self { + self.distribution = v; + self + } +} +impl molecule::prelude::Builder for SUDTBalancesBuilder { + type Entity = SUDTBalances; + const NAME: &'static str = "SUDTBalancesBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.asset.as_slice().len() + + self.distribution.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.asset.as_slice().len(); + offsets.push(total_size); + total_size += self.distribution.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.asset.as_slice())?; + writer.write_all(self.distribution.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + SUDTBalances::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Balances(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Balances { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Balances { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Balances { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "ckbytes", self.ckbytes())?; + write!(f, ", {}: {}", "sudts", self.sudts())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for Balances { + fn default() -> Self { + let v: Vec = vec![ + 32, 0, 0, 0, 12, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, + ]; + Balances::new_unchecked(v.into()) + } +} +impl Balances { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn ckbytes(&self) -> CKByteDistribution { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + CKByteDistribution::new_unchecked(self.0.slice(start..end)) + } + pub fn sudts(&self) -> SUDTAllocation { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + SUDTAllocation::new_unchecked(self.0.slice(start..end)) + } else { + SUDTAllocation::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> BalancesReader<'r> { + BalancesReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Balances { + type Builder = BalancesBuilder; + const NAME: &'static str = "Balances"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Balances(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + BalancesReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + BalancesReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .ckbytes(self.ckbytes()) + .sudts(self.sudts()) + } +} +#[derive(Clone, Copy)] +pub struct BalancesReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for BalancesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for BalancesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for BalancesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "ckbytes", self.ckbytes())?; + write!(f, ", {}: {}", "sudts", self.sudts())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> BalancesReader<'r> { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn ckbytes(&self) -> CKByteDistributionReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + CKByteDistributionReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn sudts(&self) -> SUDTAllocationReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + SUDTAllocationReader::new_unchecked(&self.as_slice()[start..end]) + } else { + SUDTAllocationReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for BalancesReader<'r> { + type Entity = Balances; + const NAME: &'static str = "BalancesReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + BalancesReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + CKByteDistributionReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + SUDTAllocationReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct BalancesBuilder { + pub(crate) ckbytes: CKByteDistribution, + pub(crate) sudts: SUDTAllocation, +} +impl BalancesBuilder { + pub const FIELD_COUNT: usize = 2; + pub fn ckbytes(mut self, v: CKByteDistribution) -> Self { + self.ckbytes = v; + self + } + pub fn sudts(mut self, v: SUDTAllocation) -> Self { + self.sudts = v; + self + } +} +impl molecule::prelude::Builder for BalancesBuilder { + type Entity = Balances; + const NAME: &'static str = "BalancesBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.ckbytes.as_slice().len() + + self.sudts.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.ckbytes.as_slice().len(); + offsets.push(total_size); + total_size += self.sudts.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.ckbytes.as_slice())?; + writer.write_all(self.sudts.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Balances::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct True(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for True { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for True { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for True { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for True { + fn default() -> Self { + let v: Vec = vec![0]; + True::new_unchecked(v.into()) + } +} +impl True { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> TrueReader<'r> { + TrueReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for True { + type Builder = TrueBuilder; + const NAME: &'static str = "True"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + True(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TrueReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TrueReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0()]) + } +} +#[derive(Clone, Copy)] +pub struct TrueReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for TrueReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for TrueReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for TrueReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> TrueReader<'r> { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for TrueReader<'r> { + type Entity = True; + const NAME: &'static str = "TrueReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + TrueReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct TrueBuilder(pub(crate) [Byte; 1]); +impl ::core::fmt::Debug for TrueBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for TrueBuilder { + fn default() -> Self { + TrueBuilder([Byte::default()]) + } +} +impl TrueBuilder { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn set(mut self, v: [Byte; 1]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } +} +impl molecule::prelude::Builder for TrueBuilder { + type Entity = True; + const NAME: &'static str = "TrueBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + True::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct False(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for False { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for False { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for False { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for False { + fn default() -> Self { + let v: Vec = vec![0]; + False::new_unchecked(v.into()) + } +} +impl False { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> FalseReader<'r> { + FalseReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for False { + type Builder = FalseBuilder; + const NAME: &'static str = "False"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + False(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + FalseReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + FalseReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0()]) + } +} +#[derive(Clone, Copy)] +pub struct FalseReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for FalseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for FalseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for FalseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> FalseReader<'r> { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for FalseReader<'r> { + type Entity = False; + const NAME: &'static str = "FalseReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + FalseReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct FalseBuilder(pub(crate) [Byte; 1]); +impl ::core::fmt::Debug for FalseBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for FalseBuilder { + fn default() -> Self { + FalseBuilder([Byte::default()]) + } +} +impl FalseBuilder { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn set(mut self, v: [Byte; 1]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } +} +impl molecule::prelude::Builder for FalseBuilder { + type Entity = False; + const NAME: &'static str = "FalseBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + False::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Bool(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Bool { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Bool { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Bool { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl ::core::default::Default for Bool { + fn default() -> Self { + let v: Vec = vec![0, 0, 0, 0, 0]; + Bool::new_unchecked(v.into()) + } +} +impl Bool { + pub const ITEMS_COUNT: usize = 2; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> BoolUnion { + let inner = self.0.slice(molecule::NUMBER_SIZE..); + match self.item_id() { + 0 => True::new_unchecked(inner).into(), + 1 => False::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } + pub fn as_reader<'r>(&'r self) -> BoolReader<'r> { + BoolReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Bool { + type Builder = BoolBuilder; + const NAME: &'static str = "Bool"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Bool(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + BoolReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + BoolReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_enum()) + } +} +#[derive(Clone, Copy)] +pub struct BoolReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for BoolReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for BoolReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for BoolReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl<'r> BoolReader<'r> { + pub const ITEMS_COUNT: usize = 2; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> BoolUnionReader<'r> { + let inner = &self.as_slice()[molecule::NUMBER_SIZE..]; + match self.item_id() { + 0 => TrueReader::new_unchecked(inner).into(), + 1 => FalseReader::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } +} +impl<'r> molecule::prelude::Reader<'r> for BoolReader<'r> { + type Entity = Bool; + const NAME: &'static str = "BoolReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + BoolReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let item_id = molecule::unpack_number(slice); + let inner_slice = &slice[molecule::NUMBER_SIZE..]; + match item_id { + 0 => TrueReader::verify(inner_slice, compatible), + 1 => FalseReader::verify(inner_slice, compatible), + _ => ve!(Self, UnknownItem, Self::ITEMS_COUNT, item_id), + }?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct BoolBuilder(pub(crate) BoolUnion); +impl BoolBuilder { + pub const ITEMS_COUNT: usize = 2; + pub fn set(mut self, v: I) -> Self + where + I: ::core::convert::Into, + { + self.0 = v.into(); + self + } +} +impl molecule::prelude::Builder for BoolBuilder { + type Entity = Bool; + const NAME: &'static str = "BoolBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE + self.0.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(&molecule::pack_number(self.0.item_id()))?; + writer.write_all(self.0.as_slice()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Bool::new_unchecked(inner.into()) + } +} +#[derive(Debug, Clone)] +pub enum BoolUnion { + True(True), + False(False), +} +#[derive(Debug, Clone, Copy)] +pub enum BoolUnionReader<'r> { + True(TrueReader<'r>), + False(FalseReader<'r>), +} +impl ::core::default::Default for BoolUnion { + fn default() -> Self { + BoolUnion::True(::core::default::Default::default()) + } +} +impl ::core::fmt::Display for BoolUnion { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + BoolUnion::True(ref item) => { + write!(f, "{}::{}({})", Self::NAME, True::NAME, item) + } + BoolUnion::False(ref item) => { + write!(f, "{}::{}({})", Self::NAME, False::NAME, item) + } + } + } +} +impl<'r> ::core::fmt::Display for BoolUnionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + BoolUnionReader::True(ref item) => { + write!(f, "{}::{}({})", Self::NAME, True::NAME, item) + } + BoolUnionReader::False(ref item) => { + write!(f, "{}::{}({})", Self::NAME, False::NAME, item) + } + } + } +} +impl BoolUnion { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + BoolUnion::True(ref item) => write!(f, "{}", item), + BoolUnion::False(ref item) => write!(f, "{}", item), + } + } +} +impl<'r> BoolUnionReader<'r> { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + BoolUnionReader::True(ref item) => write!(f, "{}", item), + BoolUnionReader::False(ref item) => write!(f, "{}", item), + } + } +} +impl ::core::convert::From for BoolUnion { + fn from(item: True) -> Self { + BoolUnion::True(item) + } +} +impl ::core::convert::From for BoolUnion { + fn from(item: False) -> Self { + BoolUnion::False(item) + } +} +impl<'r> ::core::convert::From> for BoolUnionReader<'r> { + fn from(item: TrueReader<'r>) -> Self { + BoolUnionReader::True(item) + } +} +impl<'r> ::core::convert::From> for BoolUnionReader<'r> { + fn from(item: FalseReader<'r>) -> Self { + BoolUnionReader::False(item) + } +} +impl BoolUnion { + pub const NAME: &'static str = "BoolUnion"; + pub fn as_bytes(&self) -> molecule::bytes::Bytes { + match self { + BoolUnion::True(item) => item.as_bytes(), + BoolUnion::False(item) => item.as_bytes(), + } + } + pub fn as_slice(&self) -> &[u8] { + match self { + BoolUnion::True(item) => item.as_slice(), + BoolUnion::False(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + BoolUnion::True(_) => 0, + BoolUnion::False(_) => 1, + } + } + pub fn item_name(&self) -> &str { + match self { + BoolUnion::True(_) => "True", + BoolUnion::False(_) => "False", + } + } + pub fn as_reader<'r>(&'r self) -> BoolUnionReader<'r> { + match self { + BoolUnion::True(item) => item.as_reader().into(), + BoolUnion::False(item) => item.as_reader().into(), + } + } +} +impl<'r> BoolUnionReader<'r> { + pub const NAME: &'r str = "BoolUnionReader"; + pub fn as_slice(&self) -> &'r [u8] { + match self { + BoolUnionReader::True(item) => item.as_slice(), + BoolUnionReader::False(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + BoolUnionReader::True(_) => 0, + BoolUnionReader::False(_) => 1, + } + } + pub fn item_name(&self) -> &str { + match self { + BoolUnionReader::True(_) => "True", + BoolUnionReader::False(_) => "False", + } + } +} +#[derive(Clone)] +pub struct A(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for A { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for A { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for A { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for A { + fn default() -> Self { + let v: Vec = vec![0]; + A::new_unchecked(v.into()) + } +} +impl A { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> AReader<'r> { + AReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for A { + type Builder = ABuilder; + const NAME: &'static str = "A"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + A(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + AReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + AReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0()]) + } +} +#[derive(Clone, Copy)] +pub struct AReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for AReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for AReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for AReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> AReader<'r> { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for AReader<'r> { + type Entity = A; + const NAME: &'static str = "AReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + AReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct ABuilder(pub(crate) [Byte; 1]); +impl ::core::fmt::Debug for ABuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for ABuilder { + fn default() -> Self { + ABuilder([Byte::default()]) + } +} +impl ABuilder { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn set(mut self, v: [Byte; 1]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } +} +impl molecule::prelude::Builder for ABuilder { + type Entity = A; + const NAME: &'static str = "ABuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + A::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct B(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for B { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for B { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for B { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for B { + fn default() -> Self { + let v: Vec = vec![0]; + B::new_unchecked(v.into()) + } +} +impl B { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> BReader<'r> { + BReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for B { + type Builder = BBuilder; + const NAME: &'static str = "B"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + B(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + BReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + BReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0()]) + } +} +#[derive(Clone, Copy)] +pub struct BReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for BReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for BReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for BReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> BReader<'r> { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for BReader<'r> { + type Entity = B; + const NAME: &'static str = "BReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + BReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct BBuilder(pub(crate) [Byte; 1]); +impl ::core::fmt::Debug for BBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for BBuilder { + fn default() -> Self { + BBuilder([Byte::default()]) + } +} +impl BBuilder { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn set(mut self, v: [Byte; 1]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } +} +impl molecule::prelude::Builder for BBuilder { + type Entity = B; + const NAME: &'static str = "BBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + B::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct App(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for App { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for App { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for App { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl ::core::default::Default for App { + fn default() -> Self { + let v: Vec = vec![]; + App::new_unchecked(v.into()) + } +} +impl App { + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option { + if self.is_none() { + None + } else { + Some(Bytes::new_unchecked(self.0.clone())) + } + } + pub fn as_reader<'r>(&'r self) -> AppReader<'r> { + AppReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for App { + type Builder = AppBuilder; + const NAME: &'static str = "App"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + App(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + AppReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + AppReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_opt()) + } +} +#[derive(Clone, Copy)] +pub struct AppReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for AppReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for AppReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for AppReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl<'r> AppReader<'r> { + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option> { + if self.is_none() { + None + } else { + Some(BytesReader::new_unchecked(self.as_slice())) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for AppReader<'r> { + type Entity = App; + const NAME: &'static str = "AppReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + AppReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + if !slice.is_empty() { + BytesReader::verify(&slice[..], compatible)?; + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct AppBuilder(pub(crate) Option); +impl AppBuilder { + pub fn set(mut self, v: Option) -> Self { + self.0 = v; + self + } +} +impl molecule::prelude::Builder for AppBuilder { + type Entity = App; + const NAME: &'static str = "AppBuilder"; + fn expected_length(&self) -> usize { + self.0 + .as_ref() + .map(|ref inner| inner.as_slice().len()) + .unwrap_or(0) + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + self.0 + .as_ref() + .map(|ref inner| writer.write_all(inner.as_slice())) + .unwrap_or(Ok(())) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + App::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Participant(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Participant { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Participant { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Participant { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!( + f, + "{}: {}", + "payment_script_hash", + self.payment_script_hash() + )?; + write!( + f, + ", {}: {}", + "payment_min_capacity", + self.payment_min_capacity() + )?; + write!( + f, + ", {}: {}", + "unlock_script_hash", + self.unlock_script_hash() + )?; + write!(f, ", {}: {}", "pub_key", self.pub_key())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for Participant { + fn default() -> Self { + let v: Vec = vec![ + 125, 0, 0, 0, 20, 0, 0, 0, 52, 0, 0, 0, 60, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + Participant::new_unchecked(v.into()) + } +} +impl Participant { + pub const FIELD_COUNT: usize = 4; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn payment_script_hash(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn payment_min_capacity(&self) -> Uint64 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Uint64::new_unchecked(self.0.slice(start..end)) + } + pub fn unlock_script_hash(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn pub_key(&self) -> SEC1EncodedPubKey { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[20..]) as usize; + SEC1EncodedPubKey::new_unchecked(self.0.slice(start..end)) + } else { + SEC1EncodedPubKey::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> ParticipantReader<'r> { + ParticipantReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Participant { + type Builder = ParticipantBuilder; + const NAME: &'static str = "Participant"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Participant(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ParticipantReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ParticipantReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .payment_script_hash(self.payment_script_hash()) + .payment_min_capacity(self.payment_min_capacity()) + .unlock_script_hash(self.unlock_script_hash()) + .pub_key(self.pub_key()) + } +} +#[derive(Clone, Copy)] +pub struct ParticipantReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ParticipantReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ParticipantReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ParticipantReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!( + f, + "{}: {}", + "payment_script_hash", + self.payment_script_hash() + )?; + write!( + f, + ", {}: {}", + "payment_min_capacity", + self.payment_min_capacity() + )?; + write!( + f, + ", {}: {}", + "unlock_script_hash", + self.unlock_script_hash() + )?; + write!(f, ", {}: {}", "pub_key", self.pub_key())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> ParticipantReader<'r> { + pub const FIELD_COUNT: usize = 4; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn payment_script_hash(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn payment_min_capacity(&self) -> Uint64Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Uint64Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn unlock_script_hash(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn pub_key(&self) -> SEC1EncodedPubKeyReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[20..]) as usize; + SEC1EncodedPubKeyReader::new_unchecked(&self.as_slice()[start..end]) + } else { + SEC1EncodedPubKeyReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ParticipantReader<'r> { + type Entity = Participant; + const NAME: &'static str = "ParticipantReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ParticipantReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + Byte32Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + Uint64Reader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Byte32Reader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + SEC1EncodedPubKeyReader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ParticipantBuilder { + pub(crate) payment_script_hash: Byte32, + pub(crate) payment_min_capacity: Uint64, + pub(crate) unlock_script_hash: Byte32, + pub(crate) pub_key: SEC1EncodedPubKey, +} +impl ParticipantBuilder { + pub const FIELD_COUNT: usize = 4; + pub fn payment_script_hash(mut self, v: Byte32) -> Self { + self.payment_script_hash = v; + self + } + pub fn payment_min_capacity(mut self, v: Uint64) -> Self { + self.payment_min_capacity = v; + self + } + pub fn unlock_script_hash(mut self, v: Byte32) -> Self { + self.unlock_script_hash = v; + self + } + pub fn pub_key(mut self, v: SEC1EncodedPubKey) -> Self { + self.pub_key = v; + self + } +} +impl molecule::prelude::Builder for ParticipantBuilder { + type Entity = Participant; + const NAME: &'static str = "ParticipantBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.payment_script_hash.as_slice().len() + + self.payment_min_capacity.as_slice().len() + + self.unlock_script_hash.as_slice().len() + + self.pub_key.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.payment_script_hash.as_slice().len(); + offsets.push(total_size); + total_size += self.payment_min_capacity.as_slice().len(); + offsets.push(total_size); + total_size += self.unlock_script_hash.as_slice().len(); + offsets.push(total_size); + total_size += self.pub_key.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.payment_script_hash.as_slice())?; + writer.write_all(self.payment_min_capacity.as_slice())?; + writer.write_all(self.unlock_script_hash.as_slice())?; + writer.write_all(self.pub_key.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Participant::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ChannelParameters(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelParameters { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelParameters { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelParameters { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "party_a", self.party_a())?; + write!(f, ", {}: {}", "party_b", self.party_b())?; + write!(f, ", {}: {}", "nonce", self.nonce())?; + write!( + f, + ", {}: {}", + "challenge_duration", + self.challenge_duration() + )?; + write!(f, ", {}: {}", "app", self.app())?; + write!(f, ", {}: {}", "is_ledger_channel", self.is_ledger_channel())?; + write!( + f, + ", {}: {}", + "is_virtual_channel", + self.is_virtual_channel() + )?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for ChannelParameters { + fn default() -> Self { + let v: Vec = vec![ + 76, 1, 0, 0, 32, 0, 0, 0, 157, 0, 0, 0, 26, 1, 0, 0, 58, 1, 0, 0, 66, 1, 0, 0, 66, 1, + 0, 0, 71, 1, 0, 0, 125, 0, 0, 0, 20, 0, 0, 0, 52, 0, 0, 0, 60, 0, 0, 0, 92, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 20, 0, 0, 0, 52, 0, 0, + 0, 60, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + ChannelParameters::new_unchecked(v.into()) + } +} +impl ChannelParameters { + pub const FIELD_COUNT: usize = 7; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn party_a(&self) -> Participant { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Participant::new_unchecked(self.0.slice(start..end)) + } + pub fn party_b(&self) -> Participant { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Participant::new_unchecked(self.0.slice(start..end)) + } + pub fn nonce(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn challenge_duration(&self) -> Uint64 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + Uint64::new_unchecked(self.0.slice(start..end)) + } + pub fn app(&self) -> App { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + App::new_unchecked(self.0.slice(start..end)) + } + pub fn is_ledger_channel(&self) -> Bool { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + Bool::new_unchecked(self.0.slice(start..end)) + } + pub fn is_virtual_channel(&self) -> Bool { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + Bool::new_unchecked(self.0.slice(start..end)) + } else { + Bool::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> ChannelParametersReader<'r> { + ChannelParametersReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelParameters { + type Builder = ChannelParametersBuilder; + const NAME: &'static str = "ChannelParameters"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelParameters(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelParametersReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelParametersReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .party_a(self.party_a()) + .party_b(self.party_b()) + .nonce(self.nonce()) + .challenge_duration(self.challenge_duration()) + .app(self.app()) + .is_ledger_channel(self.is_ledger_channel()) + .is_virtual_channel(self.is_virtual_channel()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelParametersReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelParametersReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelParametersReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelParametersReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "party_a", self.party_a())?; + write!(f, ", {}: {}", "party_b", self.party_b())?; + write!(f, ", {}: {}", "nonce", self.nonce())?; + write!( + f, + ", {}: {}", + "challenge_duration", + self.challenge_duration() + )?; + write!(f, ", {}: {}", "app", self.app())?; + write!(f, ", {}: {}", "is_ledger_channel", self.is_ledger_channel())?; + write!( + f, + ", {}: {}", + "is_virtual_channel", + self.is_virtual_channel() + )?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> ChannelParametersReader<'r> { + pub const FIELD_COUNT: usize = 7; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn party_a(&self) -> ParticipantReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ParticipantReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn party_b(&self) -> ParticipantReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + ParticipantReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn nonce(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn challenge_duration(&self) -> Uint64Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + Uint64Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn app(&self) -> AppReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + AppReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn is_ledger_channel(&self) -> BoolReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + BoolReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn is_virtual_channel(&self) -> BoolReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + BoolReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BoolReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelParametersReader<'r> { + type Entity = ChannelParameters; + const NAME: &'static str = "ChannelParametersReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelParametersReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + ParticipantReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + ParticipantReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Byte32Reader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + Uint64Reader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + AppReader::verify(&slice[offsets[4]..offsets[5]], compatible)?; + BoolReader::verify(&slice[offsets[5]..offsets[6]], compatible)?; + BoolReader::verify(&slice[offsets[6]..offsets[7]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ChannelParametersBuilder { + pub(crate) party_a: Participant, + pub(crate) party_b: Participant, + pub(crate) nonce: Byte32, + pub(crate) challenge_duration: Uint64, + pub(crate) app: App, + pub(crate) is_ledger_channel: Bool, + pub(crate) is_virtual_channel: Bool, +} +impl ChannelParametersBuilder { + pub const FIELD_COUNT: usize = 7; + pub fn party_a(mut self, v: Participant) -> Self { + self.party_a = v; + self + } + pub fn party_b(mut self, v: Participant) -> Self { + self.party_b = v; + self + } + pub fn nonce(mut self, v: Byte32) -> Self { + self.nonce = v; + self + } + pub fn challenge_duration(mut self, v: Uint64) -> Self { + self.challenge_duration = v; + self + } + pub fn app(mut self, v: App) -> Self { + self.app = v; + self + } + pub fn is_ledger_channel(mut self, v: Bool) -> Self { + self.is_ledger_channel = v; + self + } + pub fn is_virtual_channel(mut self, v: Bool) -> Self { + self.is_virtual_channel = v; + self + } +} +impl molecule::prelude::Builder for ChannelParametersBuilder { + type Entity = ChannelParameters; + const NAME: &'static str = "ChannelParametersBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.party_a.as_slice().len() + + self.party_b.as_slice().len() + + self.nonce.as_slice().len() + + self.challenge_duration.as_slice().len() + + self.app.as_slice().len() + + self.is_ledger_channel.as_slice().len() + + self.is_virtual_channel.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.party_a.as_slice().len(); + offsets.push(total_size); + total_size += self.party_b.as_slice().len(); + offsets.push(total_size); + total_size += self.nonce.as_slice().len(); + offsets.push(total_size); + total_size += self.challenge_duration.as_slice().len(); + offsets.push(total_size); + total_size += self.app.as_slice().len(); + offsets.push(total_size); + total_size += self.is_ledger_channel.as_slice().len(); + offsets.push(total_size); + total_size += self.is_virtual_channel.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.party_a.as_slice())?; + writer.write_all(self.party_b.as_slice())?; + writer.write_all(self.nonce.as_slice())?; + writer.write_all(self.challenge_duration.as_slice())?; + writer.write_all(self.app.as_slice())?; + writer.write_all(self.is_ledger_channel.as_slice())?; + writer.write_all(self.is_virtual_channel.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelParameters::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ChannelConstants(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelConstants { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelConstants { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelConstants { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "params", self.params())?; + write!(f, ", {}: {}", "pfls_code_hash", self.pfls_code_hash())?; + write!(f, ", {}: {}", "pfls_hash_type", self.pfls_hash_type())?; + write!(f, ", {}: {}", "pfls_min_capacity", self.pfls_min_capacity())?; + write!(f, ", {}: {}", "pcls_code_hash", self.pcls_code_hash())?; + write!(f, ", {}: {}", "pcls_hash_type", self.pcls_hash_type())?; + write!(f, ", {}: {}", "thread_token", self.thread_token())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for ChannelConstants { + fn default() -> Self { + let v: Vec = vec![ + 218, 1, 0, 0, 32, 0, 0, 0, 108, 1, 0, 0, 140, 1, 0, 0, 141, 1, 0, 0, 149, 1, 0, 0, 181, + 1, 0, 0, 182, 1, 0, 0, 76, 1, 0, 0, 32, 0, 0, 0, 157, 0, 0, 0, 26, 1, 0, 0, 58, 1, 0, + 0, 66, 1, 0, 0, 66, 1, 0, 0, 71, 1, 0, 0, 125, 0, 0, 0, 20, 0, 0, 0, 52, 0, 0, 0, 60, + 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, + 0, 20, 0, 0, 0, 52, 0, 0, 0, 60, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + ChannelConstants::new_unchecked(v.into()) + } +} +impl ChannelConstants { + pub const FIELD_COUNT: usize = 7; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn params(&self) -> ChannelParameters { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ChannelParameters::new_unchecked(self.0.slice(start..end)) + } + pub fn pfls_code_hash(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn pfls_hash_type(&self) -> Byte { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + Byte::new_unchecked(self.0.slice(start..end)) + } + pub fn pfls_min_capacity(&self) -> Uint64 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + Uint64::new_unchecked(self.0.slice(start..end)) + } + pub fn pcls_code_hash(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn pcls_hash_type(&self) -> Byte { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + Byte::new_unchecked(self.0.slice(start..end)) + } + pub fn thread_token(&self) -> ChannelToken { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + ChannelToken::new_unchecked(self.0.slice(start..end)) + } else { + ChannelToken::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> ChannelConstantsReader<'r> { + ChannelConstantsReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelConstants { + type Builder = ChannelConstantsBuilder; + const NAME: &'static str = "ChannelConstants"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelConstants(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelConstantsReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelConstantsReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .params(self.params()) + .pfls_code_hash(self.pfls_code_hash()) + .pfls_hash_type(self.pfls_hash_type()) + .pfls_min_capacity(self.pfls_min_capacity()) + .pcls_code_hash(self.pcls_code_hash()) + .pcls_hash_type(self.pcls_hash_type()) + .thread_token(self.thread_token()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelConstantsReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelConstantsReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelConstantsReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelConstantsReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "params", self.params())?; + write!(f, ", {}: {}", "pfls_code_hash", self.pfls_code_hash())?; + write!(f, ", {}: {}", "pfls_hash_type", self.pfls_hash_type())?; + write!(f, ", {}: {}", "pfls_min_capacity", self.pfls_min_capacity())?; + write!(f, ", {}: {}", "pcls_code_hash", self.pcls_code_hash())?; + write!(f, ", {}: {}", "pcls_hash_type", self.pcls_hash_type())?; + write!(f, ", {}: {}", "thread_token", self.thread_token())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> ChannelConstantsReader<'r> { + pub const FIELD_COUNT: usize = 7; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn params(&self) -> ChannelParametersReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ChannelParametersReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn pfls_code_hash(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn pfls_hash_type(&self) -> ByteReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + ByteReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn pfls_min_capacity(&self) -> Uint64Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + Uint64Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn pcls_code_hash(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn pcls_hash_type(&self) -> ByteReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + ByteReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn thread_token(&self) -> ChannelTokenReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + ChannelTokenReader::new_unchecked(&self.as_slice()[start..end]) + } else { + ChannelTokenReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelConstantsReader<'r> { + type Entity = ChannelConstants; + const NAME: &'static str = "ChannelConstantsReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelConstantsReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + ChannelParametersReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + Byte32Reader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + ByteReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + Uint64Reader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + Byte32Reader::verify(&slice[offsets[4]..offsets[5]], compatible)?; + ByteReader::verify(&slice[offsets[5]..offsets[6]], compatible)?; + ChannelTokenReader::verify(&slice[offsets[6]..offsets[7]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ChannelConstantsBuilder { + pub(crate) params: ChannelParameters, + pub(crate) pfls_code_hash: Byte32, + pub(crate) pfls_hash_type: Byte, + pub(crate) pfls_min_capacity: Uint64, + pub(crate) pcls_code_hash: Byte32, + pub(crate) pcls_hash_type: Byte, + pub(crate) thread_token: ChannelToken, +} +impl ChannelConstantsBuilder { + pub const FIELD_COUNT: usize = 7; + pub fn params(mut self, v: ChannelParameters) -> Self { + self.params = v; + self + } + pub fn pfls_code_hash(mut self, v: Byte32) -> Self { + self.pfls_code_hash = v; + self + } + pub fn pfls_hash_type(mut self, v: Byte) -> Self { + self.pfls_hash_type = v; + self + } + pub fn pfls_min_capacity(mut self, v: Uint64) -> Self { + self.pfls_min_capacity = v; + self + } + pub fn pcls_code_hash(mut self, v: Byte32) -> Self { + self.pcls_code_hash = v; + self + } + pub fn pcls_hash_type(mut self, v: Byte) -> Self { + self.pcls_hash_type = v; + self + } + pub fn thread_token(mut self, v: ChannelToken) -> Self { + self.thread_token = v; + self + } +} +impl molecule::prelude::Builder for ChannelConstantsBuilder { + type Entity = ChannelConstants; + const NAME: &'static str = "ChannelConstantsBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.params.as_slice().len() + + self.pfls_code_hash.as_slice().len() + + self.pfls_hash_type.as_slice().len() + + self.pfls_min_capacity.as_slice().len() + + self.pcls_code_hash.as_slice().len() + + self.pcls_hash_type.as_slice().len() + + self.thread_token.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.params.as_slice().len(); + offsets.push(total_size); + total_size += self.pfls_code_hash.as_slice().len(); + offsets.push(total_size); + total_size += self.pfls_hash_type.as_slice().len(); + offsets.push(total_size); + total_size += self.pfls_min_capacity.as_slice().len(); + offsets.push(total_size); + total_size += self.pcls_code_hash.as_slice().len(); + offsets.push(total_size); + total_size += self.pcls_hash_type.as_slice().len(); + offsets.push(total_size); + total_size += self.thread_token.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.params.as_slice())?; + writer.write_all(self.pfls_code_hash.as_slice())?; + writer.write_all(self.pfls_hash_type.as_slice())?; + writer.write_all(self.pfls_min_capacity.as_slice())?; + writer.write_all(self.pcls_code_hash.as_slice())?; + writer.write_all(self.pcls_hash_type.as_slice())?; + writer.write_all(self.thread_token.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelConstants::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Fund(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Fund { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Fund { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Fund { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for Fund { + fn default() -> Self { + let v: Vec = vec![0]; + Fund::new_unchecked(v.into()) + } +} +impl Fund { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> FundReader<'r> { + FundReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Fund { + type Builder = FundBuilder; + const NAME: &'static str = "Fund"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Fund(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + FundReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + FundReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0()]) + } +} +#[derive(Clone, Copy)] +pub struct FundReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for FundReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for FundReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for FundReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> FundReader<'r> { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for FundReader<'r> { + type Entity = Fund; + const NAME: &'static str = "FundReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + FundReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct FundBuilder(pub(crate) [Byte; 1]); +impl ::core::fmt::Debug for FundBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for FundBuilder { + fn default() -> Self { + FundBuilder([Byte::default()]) + } +} +impl FundBuilder { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn set(mut self, v: [Byte; 1]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } +} +impl molecule::prelude::Builder for FundBuilder { + type Entity = Fund; + const NAME: &'static str = "FundBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Fund::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Abort(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Abort { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Abort { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Abort { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for Abort { + fn default() -> Self { + let v: Vec = vec![0]; + Abort::new_unchecked(v.into()) + } +} +impl Abort { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> AbortReader<'r> { + AbortReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Abort { + type Builder = AbortBuilder; + const NAME: &'static str = "Abort"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Abort(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + AbortReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + AbortReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0()]) + } +} +#[derive(Clone, Copy)] +pub struct AbortReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for AbortReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for AbortReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for AbortReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> AbortReader<'r> { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for AbortReader<'r> { + type Entity = Abort; + const NAME: &'static str = "AbortReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + AbortReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct AbortBuilder(pub(crate) [Byte; 1]); +impl ::core::fmt::Debug for AbortBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for AbortBuilder { + fn default() -> Self { + AbortBuilder([Byte::default()]) + } +} +impl AbortBuilder { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn set(mut self, v: [Byte; 1]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } +} +impl molecule::prelude::Builder for AbortBuilder { + type Entity = Abort; + const NAME: &'static str = "AbortBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Abort::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Dispute(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Dispute { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Dispute { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Dispute { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "sig_a", self.sig_a())?; + write!(f, ", {}: {}", "sig_b", self.sig_b())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for Dispute { + fn default() -> Self { + let v: Vec = vec![ + 20, 0, 0, 0, 12, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + Dispute::new_unchecked(v.into()) + } +} +impl Dispute { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn sig_a(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + pub fn sig_b(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } else { + Bytes::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> DisputeReader<'r> { + DisputeReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Dispute { + type Builder = DisputeBuilder; + const NAME: &'static str = "Dispute"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Dispute(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + DisputeReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + DisputeReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().sig_a(self.sig_a()).sig_b(self.sig_b()) + } +} +#[derive(Clone, Copy)] +pub struct DisputeReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for DisputeReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for DisputeReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for DisputeReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "sig_a", self.sig_a())?; + write!(f, ", {}: {}", "sig_b", self.sig_b())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> DisputeReader<'r> { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn sig_a(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn sig_b(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BytesReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for DisputeReader<'r> { + type Entity = Dispute; + const NAME: &'static str = "DisputeReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + DisputeReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + BytesReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + BytesReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct DisputeBuilder { + pub(crate) sig_a: Bytes, + pub(crate) sig_b: Bytes, +} +impl DisputeBuilder { + pub const FIELD_COUNT: usize = 2; + pub fn sig_a(mut self, v: Bytes) -> Self { + self.sig_a = v; + self + } + pub fn sig_b(mut self, v: Bytes) -> Self { + self.sig_b = v; + self + } +} +impl molecule::prelude::Builder for DisputeBuilder { + type Entity = Dispute; + const NAME: &'static str = "DisputeBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.sig_a.as_slice().len() + + self.sig_b.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.sig_a.as_slice().len(); + offsets.push(total_size); + total_size += self.sig_b.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.sig_a.as_slice())?; + writer.write_all(self.sig_b.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Dispute::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Close(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Close { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Close { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Close { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "state", self.state())?; + write!(f, ", {}: {}", "sig_a", self.sig_a())?; + write!(f, ", {}: {}", "sig_b", self.sig_b())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for Close { + fn default() -> Self { + let v: Vec = vec![ + 121, 0, 0, 0, 16, 0, 0, 0, 113, 0, 0, 0, 117, 0, 0, 0, 97, 0, 0, 0, 20, 0, 0, 0, 52, 0, + 0, 0, 84, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 12, 0, 0, 0, 28, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + Close::new_unchecked(v.into()) + } +} +impl Close { + pub const FIELD_COUNT: usize = 3; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn state(&self) -> ChannelState { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ChannelState::new_unchecked(self.0.slice(start..end)) + } + pub fn sig_a(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + pub fn sig_b(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } else { + Bytes::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> CloseReader<'r> { + CloseReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Close { + type Builder = CloseBuilder; + const NAME: &'static str = "Close"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Close(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + CloseReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + CloseReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .state(self.state()) + .sig_a(self.sig_a()) + .sig_b(self.sig_b()) + } +} +#[derive(Clone, Copy)] +pub struct CloseReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for CloseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for CloseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for CloseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "state", self.state())?; + write!(f, ", {}: {}", "sig_a", self.sig_a())?; + write!(f, ", {}: {}", "sig_b", self.sig_b())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> CloseReader<'r> { + pub const FIELD_COUNT: usize = 3; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn state(&self) -> ChannelStateReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ChannelStateReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn sig_a(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn sig_b(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BytesReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for CloseReader<'r> { + type Entity = Close; + const NAME: &'static str = "CloseReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + CloseReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + ChannelStateReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + BytesReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + BytesReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct CloseBuilder { + pub(crate) state: ChannelState, + pub(crate) sig_a: Bytes, + pub(crate) sig_b: Bytes, +} +impl CloseBuilder { + pub const FIELD_COUNT: usize = 3; + pub fn state(mut self, v: ChannelState) -> Self { + self.state = v; + self + } + pub fn sig_a(mut self, v: Bytes) -> Self { + self.sig_a = v; + self + } + pub fn sig_b(mut self, v: Bytes) -> Self { + self.sig_b = v; + self + } +} +impl molecule::prelude::Builder for CloseBuilder { + type Entity = Close; + const NAME: &'static str = "CloseBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.state.as_slice().len() + + self.sig_a.as_slice().len() + + self.sig_b.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.state.as_slice().len(); + offsets.push(total_size); + total_size += self.sig_a.as_slice().len(); + offsets.push(total_size); + total_size += self.sig_b.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.state.as_slice())?; + writer.write_all(self.sig_a.as_slice())?; + writer.write_all(self.sig_b.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Close::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ForceClose(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ForceClose { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ForceClose { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ForceClose { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for ForceClose { + fn default() -> Self { + let v: Vec = vec![0]; + ForceClose::new_unchecked(v.into()) + } +} +impl ForceClose { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> ForceCloseReader<'r> { + ForceCloseReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ForceClose { + type Builder = ForceCloseBuilder; + const NAME: &'static str = "ForceClose"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ForceClose(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ForceCloseReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ForceCloseReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0()]) + } +} +#[derive(Clone, Copy)] +pub struct ForceCloseReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ForceCloseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ForceCloseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ForceCloseReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> ForceCloseReader<'r> { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for ForceCloseReader<'r> { + type Entity = ForceClose; + const NAME: &'static str = "ForceCloseReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ForceCloseReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +pub struct ForceCloseBuilder(pub(crate) [Byte; 1]); +impl ::core::fmt::Debug for ForceCloseBuilder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for ForceCloseBuilder { + fn default() -> Self { + ForceCloseBuilder([Byte::default()]) + } +} +impl ForceCloseBuilder { + pub const TOTAL_SIZE: usize = 1; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 1; + pub fn set(mut self, v: [Byte; 1]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } +} +impl molecule::prelude::Builder for ForceCloseBuilder { + type Entity = ForceClose; + const NAME: &'static str = "ForceCloseBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ForceClose::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ChannelWitness(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelWitness { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelWitness { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelWitness { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl ::core::default::Default for ChannelWitness { + fn default() -> Self { + let v: Vec = vec![0, 0, 0, 0, 0]; + ChannelWitness::new_unchecked(v.into()) + } +} +impl ChannelWitness { + pub const ITEMS_COUNT: usize = 5; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> ChannelWitnessUnion { + let inner = self.0.slice(molecule::NUMBER_SIZE..); + match self.item_id() { + 0 => Fund::new_unchecked(inner).into(), + 1 => Abort::new_unchecked(inner).into(), + 2 => Dispute::new_unchecked(inner).into(), + 3 => Close::new_unchecked(inner).into(), + 4 => ForceClose::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } + pub fn as_reader<'r>(&'r self) -> ChannelWitnessReader<'r> { + ChannelWitnessReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelWitness { + type Builder = ChannelWitnessBuilder; + const NAME: &'static str = "ChannelWitness"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelWitness(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelWitnessReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelWitnessReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_enum()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelWitnessReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelWitnessReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelWitnessReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelWitnessReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl<'r> ChannelWitnessReader<'r> { + pub const ITEMS_COUNT: usize = 5; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> ChannelWitnessUnionReader<'r> { + let inner = &self.as_slice()[molecule::NUMBER_SIZE..]; + match self.item_id() { + 0 => FundReader::new_unchecked(inner).into(), + 1 => AbortReader::new_unchecked(inner).into(), + 2 => DisputeReader::new_unchecked(inner).into(), + 3 => CloseReader::new_unchecked(inner).into(), + 4 => ForceCloseReader::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelWitnessReader<'r> { + type Entity = ChannelWitness; + const NAME: &'static str = "ChannelWitnessReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelWitnessReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let item_id = molecule::unpack_number(slice); + let inner_slice = &slice[molecule::NUMBER_SIZE..]; + match item_id { + 0 => FundReader::verify(inner_slice, compatible), + 1 => AbortReader::verify(inner_slice, compatible), + 2 => DisputeReader::verify(inner_slice, compatible), + 3 => CloseReader::verify(inner_slice, compatible), + 4 => ForceCloseReader::verify(inner_slice, compatible), + _ => ve!(Self, UnknownItem, Self::ITEMS_COUNT, item_id), + }?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ChannelWitnessBuilder(pub(crate) ChannelWitnessUnion); +impl ChannelWitnessBuilder { + pub const ITEMS_COUNT: usize = 5; + pub fn set(mut self, v: I) -> Self + where + I: ::core::convert::Into, + { + self.0 = v.into(); + self + } +} +impl molecule::prelude::Builder for ChannelWitnessBuilder { + type Entity = ChannelWitness; + const NAME: &'static str = "ChannelWitnessBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE + self.0.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(&molecule::pack_number(self.0.item_id()))?; + writer.write_all(self.0.as_slice()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelWitness::new_unchecked(inner.into()) + } +} +#[derive(Debug, Clone)] +pub enum ChannelWitnessUnion { + Fund(Fund), + Abort(Abort), + Dispute(Dispute), + Close(Close), + ForceClose(ForceClose), +} +#[derive(Debug, Clone, Copy)] +pub enum ChannelWitnessUnionReader<'r> { + Fund(FundReader<'r>), + Abort(AbortReader<'r>), + Dispute(DisputeReader<'r>), + Close(CloseReader<'r>), + ForceClose(ForceCloseReader<'r>), +} +impl ::core::default::Default for ChannelWitnessUnion { + fn default() -> Self { + ChannelWitnessUnion::Fund(::core::default::Default::default()) + } +} +impl ::core::fmt::Display for ChannelWitnessUnion { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ChannelWitnessUnion::Fund(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Fund::NAME, item) + } + ChannelWitnessUnion::Abort(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Abort::NAME, item) + } + ChannelWitnessUnion::Dispute(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Dispute::NAME, item) + } + ChannelWitnessUnion::Close(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Close::NAME, item) + } + ChannelWitnessUnion::ForceClose(ref item) => { + write!(f, "{}::{}({})", Self::NAME, ForceClose::NAME, item) + } + } + } +} +impl<'r> ::core::fmt::Display for ChannelWitnessUnionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ChannelWitnessUnionReader::Fund(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Fund::NAME, item) + } + ChannelWitnessUnionReader::Abort(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Abort::NAME, item) + } + ChannelWitnessUnionReader::Dispute(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Dispute::NAME, item) + } + ChannelWitnessUnionReader::Close(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Close::NAME, item) + } + ChannelWitnessUnionReader::ForceClose(ref item) => { + write!(f, "{}::{}({})", Self::NAME, ForceClose::NAME, item) + } + } + } +} +impl ChannelWitnessUnion { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ChannelWitnessUnion::Fund(ref item) => write!(f, "{}", item), + ChannelWitnessUnion::Abort(ref item) => write!(f, "{}", item), + ChannelWitnessUnion::Dispute(ref item) => write!(f, "{}", item), + ChannelWitnessUnion::Close(ref item) => write!(f, "{}", item), + ChannelWitnessUnion::ForceClose(ref item) => write!(f, "{}", item), + } + } +} +impl<'r> ChannelWitnessUnionReader<'r> { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ChannelWitnessUnionReader::Fund(ref item) => write!(f, "{}", item), + ChannelWitnessUnionReader::Abort(ref item) => write!(f, "{}", item), + ChannelWitnessUnionReader::Dispute(ref item) => write!(f, "{}", item), + ChannelWitnessUnionReader::Close(ref item) => write!(f, "{}", item), + ChannelWitnessUnionReader::ForceClose(ref item) => write!(f, "{}", item), + } + } +} +impl ::core::convert::From for ChannelWitnessUnion { + fn from(item: Fund) -> Self { + ChannelWitnessUnion::Fund(item) + } +} +impl ::core::convert::From for ChannelWitnessUnion { + fn from(item: Abort) -> Self { + ChannelWitnessUnion::Abort(item) + } +} +impl ::core::convert::From for ChannelWitnessUnion { + fn from(item: Dispute) -> Self { + ChannelWitnessUnion::Dispute(item) + } +} +impl ::core::convert::From for ChannelWitnessUnion { + fn from(item: Close) -> Self { + ChannelWitnessUnion::Close(item) + } +} +impl ::core::convert::From for ChannelWitnessUnion { + fn from(item: ForceClose) -> Self { + ChannelWitnessUnion::ForceClose(item) + } +} +impl<'r> ::core::convert::From> for ChannelWitnessUnionReader<'r> { + fn from(item: FundReader<'r>) -> Self { + ChannelWitnessUnionReader::Fund(item) + } +} +impl<'r> ::core::convert::From> for ChannelWitnessUnionReader<'r> { + fn from(item: AbortReader<'r>) -> Self { + ChannelWitnessUnionReader::Abort(item) + } +} +impl<'r> ::core::convert::From> for ChannelWitnessUnionReader<'r> { + fn from(item: DisputeReader<'r>) -> Self { + ChannelWitnessUnionReader::Dispute(item) + } +} +impl<'r> ::core::convert::From> for ChannelWitnessUnionReader<'r> { + fn from(item: CloseReader<'r>) -> Self { + ChannelWitnessUnionReader::Close(item) + } +} +impl<'r> ::core::convert::From> for ChannelWitnessUnionReader<'r> { + fn from(item: ForceCloseReader<'r>) -> Self { + ChannelWitnessUnionReader::ForceClose(item) + } +} +impl ChannelWitnessUnion { + pub const NAME: &'static str = "ChannelWitnessUnion"; + pub fn as_bytes(&self) -> molecule::bytes::Bytes { + match self { + ChannelWitnessUnion::Fund(item) => item.as_bytes(), + ChannelWitnessUnion::Abort(item) => item.as_bytes(), + ChannelWitnessUnion::Dispute(item) => item.as_bytes(), + ChannelWitnessUnion::Close(item) => item.as_bytes(), + ChannelWitnessUnion::ForceClose(item) => item.as_bytes(), + } + } + pub fn as_slice(&self) -> &[u8] { + match self { + ChannelWitnessUnion::Fund(item) => item.as_slice(), + ChannelWitnessUnion::Abort(item) => item.as_slice(), + ChannelWitnessUnion::Dispute(item) => item.as_slice(), + ChannelWitnessUnion::Close(item) => item.as_slice(), + ChannelWitnessUnion::ForceClose(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + ChannelWitnessUnion::Fund(_) => 0, + ChannelWitnessUnion::Abort(_) => 1, + ChannelWitnessUnion::Dispute(_) => 2, + ChannelWitnessUnion::Close(_) => 3, + ChannelWitnessUnion::ForceClose(_) => 4, + } + } + pub fn item_name(&self) -> &str { + match self { + ChannelWitnessUnion::Fund(_) => "Fund", + ChannelWitnessUnion::Abort(_) => "Abort", + ChannelWitnessUnion::Dispute(_) => "Dispute", + ChannelWitnessUnion::Close(_) => "Close", + ChannelWitnessUnion::ForceClose(_) => "ForceClose", + } + } + pub fn as_reader<'r>(&'r self) -> ChannelWitnessUnionReader<'r> { + match self { + ChannelWitnessUnion::Fund(item) => item.as_reader().into(), + ChannelWitnessUnion::Abort(item) => item.as_reader().into(), + ChannelWitnessUnion::Dispute(item) => item.as_reader().into(), + ChannelWitnessUnion::Close(item) => item.as_reader().into(), + ChannelWitnessUnion::ForceClose(item) => item.as_reader().into(), + } + } +} +impl<'r> ChannelWitnessUnionReader<'r> { + pub const NAME: &'r str = "ChannelWitnessUnionReader"; + pub fn as_slice(&self) -> &'r [u8] { + match self { + ChannelWitnessUnionReader::Fund(item) => item.as_slice(), + ChannelWitnessUnionReader::Abort(item) => item.as_slice(), + ChannelWitnessUnionReader::Dispute(item) => item.as_slice(), + ChannelWitnessUnionReader::Close(item) => item.as_slice(), + ChannelWitnessUnionReader::ForceClose(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + ChannelWitnessUnionReader::Fund(_) => 0, + ChannelWitnessUnionReader::Abort(_) => 1, + ChannelWitnessUnionReader::Dispute(_) => 2, + ChannelWitnessUnionReader::Close(_) => 3, + ChannelWitnessUnionReader::ForceClose(_) => 4, + } + } + pub fn item_name(&self) -> &str { + match self { + ChannelWitnessUnionReader::Fund(_) => "Fund", + ChannelWitnessUnionReader::Abort(_) => "Abort", + ChannelWitnessUnionReader::Dispute(_) => "Dispute", + ChannelWitnessUnionReader::Close(_) => "Close", + ChannelWitnessUnionReader::ForceClose(_) => "ForceClose", + } + } +} +#[derive(Clone)] +pub struct ChannelState(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelState { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelState { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelState { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "channel_id", self.channel_id())?; + write!(f, ", {}: {}", "balances", self.balances())?; + write!(f, ", {}: {}", "version", self.version())?; + write!(f, ", {}: {}", "is_final", self.is_final())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for ChannelState { + fn default() -> Self { + let v: Vec = vec![ + 97, 0, 0, 0, 20, 0, 0, 0, 52, 0, 0, 0, 84, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, + 12, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + ChannelState::new_unchecked(v.into()) + } +} +impl ChannelState { + pub const FIELD_COUNT: usize = 4; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn channel_id(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn balances(&self) -> Balances { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Balances::new_unchecked(self.0.slice(start..end)) + } + pub fn version(&self) -> Uint64 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + Uint64::new_unchecked(self.0.slice(start..end)) + } + pub fn is_final(&self) -> Bool { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[20..]) as usize; + Bool::new_unchecked(self.0.slice(start..end)) + } else { + Bool::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> ChannelStateReader<'r> { + ChannelStateReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelState { + type Builder = ChannelStateBuilder; + const NAME: &'static str = "ChannelState"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelState(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelStateReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelStateReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .channel_id(self.channel_id()) + .balances(self.balances()) + .version(self.version()) + .is_final(self.is_final()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelStateReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelStateReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelStateReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelStateReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "channel_id", self.channel_id())?; + write!(f, ", {}: {}", "balances", self.balances())?; + write!(f, ", {}: {}", "version", self.version())?; + write!(f, ", {}: {}", "is_final", self.is_final())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> ChannelStateReader<'r> { + pub const FIELD_COUNT: usize = 4; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn channel_id(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn balances(&self) -> BalancesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + BalancesReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn version(&self) -> Uint64Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + Uint64Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn is_final(&self) -> BoolReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[20..]) as usize; + BoolReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BoolReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelStateReader<'r> { + type Entity = ChannelState; + const NAME: &'static str = "ChannelStateReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelStateReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + Byte32Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + BalancesReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Uint64Reader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + BoolReader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ChannelStateBuilder { + pub(crate) channel_id: Byte32, + pub(crate) balances: Balances, + pub(crate) version: Uint64, + pub(crate) is_final: Bool, +} +impl ChannelStateBuilder { + pub const FIELD_COUNT: usize = 4; + pub fn channel_id(mut self, v: Byte32) -> Self { + self.channel_id = v; + self + } + pub fn balances(mut self, v: Balances) -> Self { + self.balances = v; + self + } + pub fn version(mut self, v: Uint64) -> Self { + self.version = v; + self + } + pub fn is_final(mut self, v: Bool) -> Self { + self.is_final = v; + self + } +} +impl molecule::prelude::Builder for ChannelStateBuilder { + type Entity = ChannelState; + const NAME: &'static str = "ChannelStateBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.channel_id.as_slice().len() + + self.balances.as_slice().len() + + self.version.as_slice().len() + + self.is_final.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.channel_id.as_slice().len(); + offsets.push(total_size); + total_size += self.balances.as_slice().len(); + offsets.push(total_size); + total_size += self.version.as_slice().len(); + offsets.push(total_size); + total_size += self.is_final.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.channel_id.as_slice())?; + writer.write_all(self.balances.as_slice())?; + writer.write_all(self.version.as_slice())?; + writer.write_all(self.is_final.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelState::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ChannelStatus(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelStatus { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelStatus { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelStatus { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "state", self.state())?; + write!(f, ", {}: {}", "funded", self.funded())?; + write!(f, ", {}: {}", "disputed", self.disputed())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for ChannelStatus { + fn default() -> Self { + let v: Vec = vec![ + 123, 0, 0, 0, 16, 0, 0, 0, 113, 0, 0, 0, 118, 0, 0, 0, 97, 0, 0, 0, 20, 0, 0, 0, 52, 0, + 0, 0, 84, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 12, 0, 0, 0, 28, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + ChannelStatus::new_unchecked(v.into()) + } +} +impl ChannelStatus { + pub const FIELD_COUNT: usize = 3; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn state(&self) -> ChannelState { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ChannelState::new_unchecked(self.0.slice(start..end)) + } + pub fn funded(&self) -> Bool { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Bool::new_unchecked(self.0.slice(start..end)) + } + pub fn disputed(&self) -> Bool { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + Bool::new_unchecked(self.0.slice(start..end)) + } else { + Bool::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> ChannelStatusReader<'r> { + ChannelStatusReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelStatus { + type Builder = ChannelStatusBuilder; + const NAME: &'static str = "ChannelStatus"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelStatus(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelStatusReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelStatusReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .state(self.state()) + .funded(self.funded()) + .disputed(self.disputed()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelStatusReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelStatusReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelStatusReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelStatusReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "state", self.state())?; + write!(f, ", {}: {}", "funded", self.funded())?; + write!(f, ", {}: {}", "disputed", self.disputed())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> ChannelStatusReader<'r> { + pub const FIELD_COUNT: usize = 3; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn state(&self) -> ChannelStateReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ChannelStateReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn funded(&self) -> BoolReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + BoolReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn disputed(&self) -> BoolReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + BoolReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BoolReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelStatusReader<'r> { + type Entity = ChannelStatus; + const NAME: &'static str = "ChannelStatusReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelStatusReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + ChannelStateReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + BoolReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + BoolReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ChannelStatusBuilder { + pub(crate) state: ChannelState, + pub(crate) funded: Bool, + pub(crate) disputed: Bool, +} +impl ChannelStatusBuilder { + pub const FIELD_COUNT: usize = 3; + pub fn state(mut self, v: ChannelState) -> Self { + self.state = v; + self + } + pub fn funded(mut self, v: Bool) -> Self { + self.funded = v; + self + } + pub fn disputed(mut self, v: Bool) -> Self { + self.disputed = v; + self + } +} +impl molecule::prelude::Builder for ChannelStatusBuilder { + type Entity = ChannelStatus; + const NAME: &'static str = "ChannelStatusBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.state.as_slice().len() + + self.funded.as_slice().len() + + self.disputed.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.state.as_slice().len(); + offsets.push(total_size); + total_size += self.funded.as_slice().len(); + offsets.push(total_size); + total_size += self.disputed.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.state.as_slice())?; + writer.write_all(self.funded.as_slice())?; + writer.write_all(self.disputed.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelStatus::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ChannelToken(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelToken { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelToken { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelToken { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "out_point", self.out_point())?; + write!(f, " }}") + } +} +impl ::core::default::Default for ChannelToken { + fn default() -> Self { + let v: Vec = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + ]; + ChannelToken::new_unchecked(v.into()) + } +} +impl ChannelToken { + pub const TOTAL_SIZE: usize = 36; + pub const FIELD_SIZES: [usize; 1] = [36]; + pub const FIELD_COUNT: usize = 1; + pub fn out_point(&self) -> OutPoint { + OutPoint::new_unchecked(self.0.slice(0..36)) + } + pub fn as_reader<'r>(&'r self) -> ChannelTokenReader<'r> { + ChannelTokenReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelToken { + type Builder = ChannelTokenBuilder; + const NAME: &'static str = "ChannelToken"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelToken(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelTokenReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelTokenReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().out_point(self.out_point()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelTokenReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelTokenReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelTokenReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelTokenReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "out_point", self.out_point())?; + write!(f, " }}") + } +} +impl<'r> ChannelTokenReader<'r> { + pub const TOTAL_SIZE: usize = 36; + pub const FIELD_SIZES: [usize; 1] = [36]; + pub const FIELD_COUNT: usize = 1; + pub fn out_point(&self) -> OutPointReader<'r> { + OutPointReader::new_unchecked(&self.as_slice()[0..36]) + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelTokenReader<'r> { + type Entity = ChannelToken; + const NAME: &'static str = "ChannelTokenReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelTokenReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ChannelTokenBuilder { + pub(crate) out_point: OutPoint, +} +impl ChannelTokenBuilder { + pub const TOTAL_SIZE: usize = 36; + pub const FIELD_SIZES: [usize; 1] = [36]; + pub const FIELD_COUNT: usize = 1; + pub fn out_point(mut self, v: OutPoint) -> Self { + self.out_point = v; + self + } +} +impl molecule::prelude::Builder for ChannelTokenBuilder { + type Entity = ChannelToken; + const NAME: &'static str = "ChannelTokenBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.out_point.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelToken::new_unchecked(inner.into()) + } +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/sig.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/sig.rs new file mode 100644 index 0000000..3a7e905 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/src/sig.rs @@ -0,0 +1,11 @@ +use k256::{ecdsa::{VerifyingKey, Signature, signature::{hazmat::PrehashVerifier}}, elliptic_curve::sec1::EncodedPoint, Secp256k1}; + +use crate::error::Error; + +pub fn verify_signature(msg_hash: &[u8; 32], sig: &[u8], key: &[u8]) -> Result<(), Error> { + let signature = Signature::from_der(sig)?; + let e = EncodedPoint::::from_bytes(key).expect("unable to decode public key"); + let verifying_key = VerifyingKey::from_encoded_point(&e)?; + verifying_key.verify_prehash(msg_hash, &signature)?; + Ok(()) +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-common/types.mol b/payment-channel-ckb/devnet/contracts/contracts/perun-common/types.mol new file mode 100644 index 0000000..5fa3a5f --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-common/types.mol @@ -0,0 +1,140 @@ +import blockchain; + +/* Perun Types */ +array SEC1EncodedPubKey [byte; 33]; + +array CKByteDistribution [Uint64; 2]; + +array SUDTDistribution [Uint128; 2]; + +vector SUDTAllocation ; + +table SUDTAsset { + type_script: Script, + // The max_capacity of an SUDTAsset should always be at least the capacity needed for the SUDT type script + outputs_data + // + max(party_a.payment_min_capacity, party_b.payment_min_capacity) + // Make sure verify this in the Funding Agreement, as the contract can not verify this upon channel start! + max_capacity: Uint64, +} + +table SUDTBalances { + asset: SUDTAsset, + distribution: SUDTDistribution, +} + +table Balances { + ckbytes: CKByteDistribution, + sudts: SUDTAllocation, +} + +array True [byte; 1]; +array False [byte; 1]; + +union Bool { + True, + False, +} + +array A [byte; 1]; +array B [byte; 1]; + + +option App (Bytes); + +// Terminology: +// - script_hash: By script_hash we mean the results of the syscalls load_cell_lock_hash / load_cell_type_hash +// and the sdk function calc_script_hash. This is the hash of the script struct (code_hash, hash_type and args). +// - code_hash: By code_hash we mean the member of a script that hold the hash of the executed code (depending on the hash_type). +// See: https://docs.nervos.org/docs/reference/script/ + + + +table Participant { + // payment_script_hash specifies the script-hash used + // to lock payments to this participant (upon channel close) + payment_script_hash: Byte32, + // payment_min_capacity specifies the minimum capacity of the payment lock script. + payment_min_capacity: Uint64, + + // unlock_script_hash specifies the script-hash that needs to be present in the inputs + // to a transaction to authorize the transaction to interact with the channel as + // this channel participant. + unlock_script_hash: Byte32, + + pub_key: SEC1EncodedPubKey, +} +table ChannelParameters { + party_a: Participant, + party_b: Participant, + nonce: Byte32, + challenge_duration: Uint64, + // The default should be NoApp! + app: App, + // This should always be set to true for, as we currently only support ledger channels. + is_ledger_channel: Bool, + // This should always be set to false for, as we currently do not support virtual channels. + is_virtual_channel: Bool, +} + +// Important: Upon channel creation, every participant must verify the integrity of the channel. +// This includes verifying that the correct ChannelConstants are present. +// If e.g. the payment_min_capacity (inside the participants of the channel parameters) were to be significantly larger than the minimum +// capacity of the payment lock script, a party could steal funds from the channel participants with balances smaller than the +// payment_min_capacity upon channel closing. +table ChannelConstants { + params: ChannelParameters, + // pfls__code_hash specifies the code hash of the lock_script that guards funds for this channel. + // Specifically, this should be the perun-funds-lockscript. + pfls_code_hash: Byte32, + pfls_hash_type: byte, + pfls_min_capacity: Uint64, + + // pcls_hash specifies the lock_script used for this channel. + // Specifically, this should be the perun-channel-lockscript. + pcls_code_hash: Byte32, + pcls_hash_type: byte, + + thread_token: ChannelToken, +} + +array Fund [byte; 1]; + +array Abort [byte; 1]; + +table Dispute { + sig_a: Bytes, + sig_b: Bytes, +} +table Close { + state: ChannelState, + sig_a: Bytes, + sig_b: Bytes, +} +array ForceClose [byte; 1]; + + +union ChannelWitness { + Fund, + Abort, + Dispute, + Close, + ForceClose, +} + +table ChannelState { + // + channel_id: Byte32, + balances: Balances, + version: Uint64, + is_final: Bool, +} + +table ChannelStatus { + state: ChannelState, + funded: Bool, + disputed: Bool, +} + +struct ChannelToken { + out_point: OutPoint, +} \ No newline at end of file diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/Cargo.toml b/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/Cargo.toml new file mode 100644 index 0000000..6e66cd6 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "perun-funds-lockscript" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ckb-std = "0.10.0" +perun-common = { path = "../perun-common", default-features = false, features = ["contract"] } diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/entry.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/entry.rs new file mode 100644 index 0000000..1d21352 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/entry.rs @@ -0,0 +1,47 @@ +// Import from `core` instead of from `std` since we are in no-std mode +use core::result::Result; + +// Import heap related library from `alloc` +// https://doc.rust-lang.org/alloc/index.html + +use perun_common::error::Error; + +// Import CKB syscalls and structures +// https://docs.rs/ckb-std/ +use ckb_std::{ + ckb_constants::Source, + ckb_types::{bytes::Bytes, packed::Byte32, prelude::*}, + high_level::{load_cell_type_hash, load_script, load_transaction}, +}; + +// The Perun Funds Lock Script can be unlocked by including an input cell with the pcts script hash +// that is specified in the args of the pfls. +pub fn main() -> Result<(), Error> { + let script = load_script()?; + let args: Bytes = script.args().unpack(); + + if args.is_empty() { + return Err(Error::NoArgs); + } + + let pcts_script_hash = Byte32::from_slice(&args)?; + + return verify_pcts_in_inputs(&pcts_script_hash.unpack()); +} + +pub fn verify_pcts_in_inputs(pcts_script_hash: &[u8; 32]) -> Result<(), Error> { + let num_inputs = load_transaction()?.raw().inputs().len(); + for i in 0..num_inputs { + match load_cell_type_hash(i, Source::Input)? { + Some(cell_type_script_hash) => { + if cell_type_script_hash[..] == pcts_script_hash[..] { + return Ok(()); + } else { + continue; + } + } + None => continue, + }; + } + Err(Error::PCTSNotFound) +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/main.rs b/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/main.rs new file mode 100644 index 0000000..9306fc4 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/perun-funds-lockscript/src/main.rs @@ -0,0 +1,32 @@ +//! Generated by capsule +//! +//! `main.rs` is used to define rust lang items and modules. +//! See `entry.rs` for the `main` function. +//! See `error.rs` for the `Error` type. + +#![no_std] +#![no_main] +#![feature(asm_sym)] +#![feature(lang_items)] +#![feature(alloc_error_handler)] +#![feature(panic_info_message)] + +// define modules +mod entry; + +use ckb_std::default_alloc; +use core::arch::asm; + +ckb_std::entry!(program_entry); +default_alloc!(); + +/// program entry +/// +/// Both `argc` and `argv` can be omitted. +fn program_entry(_argc: u64, _argv: *const *const u8) -> i8 { + // Call main function and return error code + match entry::main() { + Ok(_) => 0, + Err(err) => err as i8, + } +} diff --git a/payment-channel-ckb/devnet/contracts/contracts/sample-udt/Cargo.toml b/payment-channel-ckb/devnet/contracts/contracts/sample-udt/Cargo.toml new file mode 100644 index 0000000..1d27e95 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/sample-udt/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sample-udt" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ckb-std = "0.10.0" +perun-common = { path = "../perun-common", default-features = false, features = ["contract"] } diff --git a/payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/entry.rs b/payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/entry.rs new file mode 100644 index 0000000..4e0c757 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/entry.rs @@ -0,0 +1,101 @@ +// Import from `core` instead of from `std` since we are in no-std mode +use core::result::Result; + +// Import CKB syscalls and structures +// https://docs.rs/ckb-std/ +use ckb_std::{ + ckb_constants::Source, + ckb_types::{bytes::Bytes, prelude::*}, + high_level::{load_cell_lock_hash, load_script, load_cell_data}, + syscalls::SysError, +}; +use perun_common::error::Error; + + +pub fn main() -> Result<(), Error> { + let script = load_script()?; + let args: Bytes = script.args().unpack(); + + // return success if owner mode is true + if check_owner_mode(&args)? { + return Ok(()); + } + + let inputs_amount = collect_inputs_amount()?; + let outputs_amount = collect_outputs_amount()?; + + if inputs_amount < outputs_amount { + return Err(Error::DecreasingAmount); + } + + Ok(()) +} + +pub fn check_owner_mode(args: &Bytes) -> Result { + // With owner lock script extracted, we will look through each input in the + // current transaction to see if any unlocked cell uses owner lock. + for i in 0.. { + // check input's lock_hash with script args + let lock_hash = match load_cell_lock_hash( + i, + Source::Input, + ) { + Ok(lock_hash) => lock_hash, + Err(SysError::IndexOutOfBound) => return Ok(false), + Err(err) => return Err(err.into()), + }; + // invalid length of loaded data + if args[..] == lock_hash[..] { + return Ok(true); + } + } + Ok(false) +} + +const UDT_LEN: usize = 16; + +pub fn collect_inputs_amount() -> Result { + // let's loop through all input cells containing current UDTs, + // and gather the sum of all input tokens. + let mut inputs_amount: u128 = 0; + let mut buf = [0u8; UDT_LEN]; + + // u128 is 16 bytes + for i in 0.. { + let data = match load_cell_data(i, Source::GroupInput) { + Ok(data) => data, + Err(SysError::IndexOutOfBound) => break, + Err(err) => return Err(err.into()), + }; + + if data.len() != UDT_LEN { + return Err(Error::Encoding); + } + buf.copy_from_slice(&data); + inputs_amount += u128::from_le_bytes(buf); + } + Ok(inputs_amount) +} + +fn collect_outputs_amount() -> Result { + // With the sum of all input UDT tokens gathered, let's now iterate through + // output cells to grab the sum of all output UDT tokens. + let mut outputs_amount: u128 = 0; + + // u128 is 16 bytes + let mut buf = [0u8; UDT_LEN]; + for i in 0.. { + let data = match load_cell_data(i, Source::GroupOutput) { + Ok(data) => data, + Err(SysError::IndexOutOfBound) => break, + Err(err) => return Err(err.into()), + }; + + if data.len() != UDT_LEN { + return Err(Error::Encoding); + } + buf.copy_from_slice(&data); + outputs_amount += u128::from_le_bytes(buf); + } + Ok(outputs_amount) +} \ No newline at end of file diff --git a/payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/main.rs b/payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/main.rs new file mode 100644 index 0000000..9306fc4 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/contracts/sample-udt/src/main.rs @@ -0,0 +1,32 @@ +//! Generated by capsule +//! +//! `main.rs` is used to define rust lang items and modules. +//! See `entry.rs` for the `main` function. +//! See `error.rs` for the `Error` type. + +#![no_std] +#![no_main] +#![feature(asm_sym)] +#![feature(lang_items)] +#![feature(alloc_error_handler)] +#![feature(panic_info_message)] + +// define modules +mod entry; + +use ckb_std::default_alloc; +use core::arch::asm; + +ckb_std::entry!(program_entry); +default_alloc!(); + +/// program entry +/// +/// Both `argc` and `argv` can be omitted. +fn program_entry(_argc: u64, _argv: *const *const u8) -> i8 { + // Call main function and return error code + match entry::main() { + Ok(_) => 0, + Err(err) => err as i8, + } +} diff --git a/payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml b/payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml new file mode 100644 index 0000000..899072d --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml @@ -0,0 +1,41 @@ +[[cells]] +name = "pcts" +enable_type_id = false +location = { file = "build/release/perun-channel-typescript" } + +[[cells]] +name = "pcls" +enable_type_id = false +location = { file = "build/release/perun-channel-lockscript" } + +[[cells]] +name = "pfls" +enable_type_id = false +location = { file = "build/release/perun-funds-lockscript" } + +[[cells]] +name = "sudt" +enable_type_id = false +location = { file = "build/release/sample-udt" } + +# +# # reference to on-chain cells +# [[cells]] +# name = "genesis_cell" +# enable_type_id = false +# location = { tx_hash = "0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c", index = 0 } + +# # Dep group cells +# [[dep_groups]] +# name = "my_dep_group" +# cells = [ +# "my_cell", +# "genesis_cell" +# ] + +# # Replace with your own lock if you want to unlock deployed cells. +# # For example the secp256k1 lock +[lock] +code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +args = "0x4a3c88737f8d4d26031ad9a6d6448ba75f1533e2" +hash_type = "type" diff --git a/payment-channel-ckb/devnet/contracts/deployment/release/deployment.toml b/payment-channel-ckb/devnet/contracts/deployment/release/deployment.toml new file mode 100644 index 0000000..65968f5 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/deployment/release/deployment.toml @@ -0,0 +1,37 @@ +[[cells]] +name = "pcts" +enable_type_id = false +location = { file = "build/release/perun-channel-typescript" } + +[[cells]] +name = "pcls" +enable_type_id = false +location = { file = "build/release/perun-channel-lockscript" } + +[[cells]] +name = "pfls" +enable_type_id = false +location = { file = "build/release/perun-funds-lockscript" } + +# +# # reference to on-chain cells +# [[cells]] +# name = "genesis_cell" +# enable_type_id = false +# location = { tx_hash = "0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c", index = 0 } + +# # Dep group cells +# [[dep_groups]] +# name = "my_dep_group" +# cells = [ +# "my_cell", +# "genesis_cell" +# ] + +# # Replace with your own lock if you want to unlock deployed cells. +# # For example the secp256k1 lock +# [lock] +# code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +# args = "0x1edcdab5ec7e0f748c60815fce513ee1fe4d63ee" +# hash_type = "type" + diff --git a/payment-channel-ckb/devnet/contracts/migrations/.gitkeep b/payment-channel-ckb/devnet/contracts/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/payment-channel-ckb/devnet/contracts/tests/Cargo.lock b/payment-channel-ckb/devnet/contracts/tests/Cargo.lock new file mode 100644 index 0000000..d7d027c --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/Cargo.lock @@ -0,0 +1,1593 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.9", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake2b-ref" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95916998c798756098a4eb1b3f2cd510659705a9817bf203d61abd30fbec3e7b" + +[[package]] +name = "blake2b-rs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89a8565807f21b913288968e391819e7f9b2f0f46c7b89549c051cccf3a2771" +dependencies = [ + "cc", + "cty", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "buddy-alloc" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3240a4cb09cf0da6a51641bd40ce90e96ea6065e3a1adc46434029254bcc2d09" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ckb-always-success-script" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b3b72a38c9920a29990df12002c4d069a147c8782f0c211f8a01b2df8f42bfd" + +[[package]] +name = "ckb-chain-spec" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78df45446aaa86b06a77b8b145cffa79950e7ede293cebcd114a62e74c29dbf" +dependencies = [ + "ckb-constant", + "ckb-crypto", + "ckb-dao-utils", + "ckb-error", + "ckb-hash", + "ckb-jsonrpc-types", + "ckb-pow", + "ckb-rational", + "ckb-resource", + "ckb-traits", + "ckb-types", + "ckb-util", + "serde", + "toml", +] + +[[package]] +name = "ckb-channel" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "920f26cc48cadcaf6f7bcc3960fde9f9f355633b6361da8ef31e1e1c00fc8858" +dependencies = [ + "crossbeam-channel", +] + +[[package]] +name = "ckb-constant" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302566408e5b296663ac5e8245bf71824ca2c7c2ef19a57fcc15939dd66527e9" + +[[package]] +name = "ckb-crypto" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac31177b0a8bf3acd563c042775e40494e437b2bbbae96ac2473eec3a4da95d" +dependencies = [ + "ckb-fixed-hash", + "faster-hex", + "lazy_static", + "rand 0.7.3", + "secp256k1", + "thiserror", +] + +[[package]] +name = "ckb-dao" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b70944b9013ead64287b87ac19608a3ca5ab19a9f29b7a76f637ad7831510e88" +dependencies = [ + "byteorder", + "ckb-chain-spec", + "ckb-dao-utils", + "ckb-traits", + "ckb-types", +] + +[[package]] +name = "ckb-dao-utils" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1929c9627923fe1d22151361d74f5a5aa0dda77016d020307a54486eae11cb3c" +dependencies = [ + "byteorder", + "ckb-error", + "ckb-types", +] + +[[package]] +name = "ckb-error" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446a519d8a847d97f1c8ece739dc1748751a9a2179249c96c45cced0825a7aa5" +dependencies = [ + "anyhow", + "ckb-occupied-capacity", + "derive_more", + "thiserror", +] + +[[package]] +name = "ckb-fixed-hash" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00cbbc455b23748b32e06d16628a03e30d56ffa057f17093fdf5b42d4fb6c879" +dependencies = [ + "ckb-fixed-hash-core", + "ckb-fixed-hash-macros", +] + +[[package]] +name = "ckb-fixed-hash-core" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e644a4e026625b4be5a04cdf6c02043080e79feaf77d9cdbb2f0e6553f751" +dependencies = [ + "faster-hex", + "serde", + "thiserror", +] + +[[package]] +name = "ckb-fixed-hash-macros" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cfc980ef88c217825172eb46df269f47890f5e78a38214416f13b3bd17a4b4" +dependencies = [ + "ckb-fixed-hash-core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ckb-hash" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d9b683e89ae4ffdd5aaf4172eab00b6bbe7ea24e2abf77d3eb850ba36e8983" +dependencies = [ + "blake2b-ref", + "blake2b-rs", +] + +[[package]] +name = "ckb-jsonrpc-types" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac087657eaf964e729f40b3c929d3dac74a2cd8bb38d5e588756e2495711f810" +dependencies = [ + "ckb-types", + "faster-hex", + "serde", + "serde_json", +] + +[[package]] +name = "ckb-logger" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "911c4695ddf82f78da8f514b359092bbe231f58c2669c93b1cfc9a2030b125bb" +dependencies = [ + "log", +] + +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ccb671c5921be8a84686e6212ca184cb1d7c51cadcdbfcbd1cc3f042f5dfb8" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ckb-occupied-capacity" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2a1dd0d4ba5dafba1e30d437c1148b20f42edb76b6794323e05bda626754eb" +dependencies = [ + "ckb-occupied-capacity-core", + "ckb-occupied-capacity-macros", +] + +[[package]] +name = "ckb-occupied-capacity-core" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ebba3d564098a84c83f4740e1dce48a5e2da759becdb47e3c7965f0808e6e92" +dependencies = [ + "serde", +] + +[[package]] +name = "ckb-occupied-capacity-macros" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6321bba85cdf9724029d8c906851dd4a90906869b42f9100b16645a1261d4c" +dependencies = [ + "ckb-occupied-capacity-core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ckb-pow" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9167b427f42874e68e20e6946d5211709979ff1d86c0061a71c2f6a6aa17659" +dependencies = [ + "byteorder", + "ckb-hash", + "ckb-types", + "eaglesong", + "log", + "serde", +] + +[[package]] +name = "ckb-rational" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2519249f8d47fa758d3fb3cf3049327c69ce0f2acd79d61427482c8661d3dbd" +dependencies = [ + "numext-fixed-uint", + "serde", +] + +[[package]] +name = "ckb-resource" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3abddc968d7f1e70584ab04180c347380a44acbe0b60e26cc96208ec8885279" +dependencies = [ + "ckb-system-scripts", + "ckb-types", + "includedir", + "includedir_codegen", + "phf", + "serde", + "walkdir", +] + +[[package]] +name = "ckb-script" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b4754a2f0ccea5ea1934822bd18a3a66c46344d8c3872cb20ffdcf0851fab9" +dependencies = [ + "byteorder", + "ckb-chain-spec", + "ckb-error", + "ckb-hash", + "ckb-logger", + "ckb-traits", + "ckb-types", + "ckb-vm", + "faster-hex", + "serde", +] + +[[package]] +name = "ckb-standalone-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22d7cbbdab96e6b809a102cf88bfec28795a0a3c06bfdea4abe4de89777801cd" +dependencies = [ + "cfg-if", + "molecule", +] + +[[package]] +name = "ckb-std" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a6ad40455c446ad6fbb303dae24827fc309f43558f59d1f1b863a9de3e9f81" +dependencies = [ + "buddy-alloc", + "cc", + "ckb-standalone-types", + "cstr_core", +] + +[[package]] +name = "ckb-system-scripts" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa5c59063142de7a68cfad4449c6b3863563856219a2925dfb8c5f019ec2aa47" +dependencies = [ + "blake2b-rs", + "faster-hex", + "includedir", + "includedir_codegen", + "phf", +] + +[[package]] +name = "ckb-systemtime" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243197680f69d6bb6cb1caf16199ce4a8162a258c757d5af8f727af0d8aabe9e" + +[[package]] +name = "ckb-testtool" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15fed7e8aeb21e981246bc39e0bd49067f7734851798bef996389a3b02bf9b4e" +dependencies = [ + "ckb-always-success-script", + "ckb-chain-spec", + "ckb-crypto", + "ckb-error", + "ckb-hash", + "ckb-jsonrpc-types", + "ckb-resource", + "ckb-script", + "ckb-traits", + "ckb-types", + "ckb-verification", + "lazy_static", + "rand 0.7.3", +] + +[[package]] +name = "ckb-traits" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9d5827f20a396dfb785398db484fe50de93d76c02e1e32287832604a9dda91" +dependencies = [ + "ckb-types", +] + +[[package]] +name = "ckb-types" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c22b3b1ca8f88a8f48e2f73321c0605281c9c6f1e1c4d651c6138265c22291e" +dependencies = [ + "bit-vec", + "bytes", + "ckb-channel", + "ckb-error", + "ckb-fixed-hash", + "ckb-hash", + "ckb-merkle-mountain-range", + "ckb-occupied-capacity", + "ckb-rational", + "derive_more", + "merkle-cbt", + "molecule", + "numext-fixed-uint", + "once_cell", +] + +[[package]] +name = "ckb-util" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d165c6958601dfbfa4cd00c9263ecfb013b4ccb6d9e1d3187bfa62801abc7d" +dependencies = [ + "linked-hash-map", + "once_cell", + "parking_lot", + "regex", +] + +[[package]] +name = "ckb-verification" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc1745cf02f6d628ac04cf58145b853a359ad4d74fdb418207e99773185ad11" +dependencies = [ + "ckb-chain-spec", + "ckb-dao", + "ckb-dao-utils", + "ckb-error", + "ckb-pow", + "ckb-script", + "ckb-systemtime", + "ckb-traits", + "ckb-types", + "ckb-verification-traits", + "derive_more", + "lru", +] + +[[package]] +name = "ckb-verification-traits" +version = "0.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88de577410c2e72ccd18e00cb63fc0000d41be50604a895946a1566a02272730" +dependencies = [ + "bitflags", + "ckb-error", +] + +[[package]] +name = "ckb-vm" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1223acc8054ce96f91c5d99d4942898d0bdadd618c3b14f1acd3e67212991d8e" +dependencies = [ + "byteorder", + "bytes", + "cc", + "ckb-vm-definitions", + "derive_more", + "goblin 0.2.3", + "goblin 0.4.0", + "rand 0.7.3", + "scroll", + "serde", +] + +[[package]] +name = "ckb-vm-definitions" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4af800ae2b6c54b70efa398dab015a09a52eeac2dd1ac3ad32c9bbe224974225" + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cstr_core" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd98742e4fdca832d40cab219dc2e3048de17d873248f83f17df47c1bea70956" +dependencies = [ + "cty", + "memchr", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "eaglesong" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d978bd5d343e8ab9b5c0fc8d93ff9c602fdc96616ffff9c05ac7a155419b824" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest", + "ff", + "generic-array", + "group", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "faster-hex" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e2ce894d53b295cf97b05685aa077950ff3e8541af83217fc720a6437169f8" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "goblin" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "goblin" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532a09cd3df2c6bbfc795fb0434bff8f22255d1d07328180e918a2e6ce122d4d" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapsize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +dependencies = [ + "winapi", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "includedir" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afd126bd778c00c43a9dc76d1609a0894bf4222088088b2217ccc0ce9e816db7" +dependencies = [ + "flate2", + "phf", +] + +[[package]] +name = "includedir_codegen" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ac1500c9780957c9808c4ec3b94002f35aab01483833f5a8bce7dfb243e3148" +dependencies = [ + "flate2", + "phf_codegen", + "walkdir", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2", + "sha3", +] + +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +dependencies = [ + "serde", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lru" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "merkle-cbt" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171d2f700835121c3b04ccf0880882987a050fd5c7ae88148abf537d33dd3a56" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "molecule" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc8276c02a006bddad7d1c28c1a88f30421e1b5f0ba0ca96ceb8077c7d20c01" +dependencies = [ + "bytes", + "cfg-if", + "faster-hex", +] + +[[package]] +name = "numext-constructor" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "621fe0f044729f810c6815cdd77e8f5e0cd803ce4f6a38380ebfc1322af98661" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "numext-fixed-uint" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c68c76f96d589d1009a666c5072f37f3114d682696505f2cf445f27766c7d70" +dependencies = [ + "numext-fixed-uint-core", + "numext-fixed-uint-hack", +] + +[[package]] +name = "numext-fixed-uint-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aab1d6457b97b49482f22a92f0f58a2f39bdd7f3b2f977eae67e8bc206aa980" +dependencies = [ + "heapsize", + "numext-constructor", + "rand 0.7.3", + "serde", + "thiserror", +] + +[[package]] +name = "numext-fixed-uint-hack" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200f8d55c36ec1b6a8cf810115be85d4814f045e0097dfd50033ba25adb4c9e" +dependencies = [ + "numext-fixed-uint-core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "perun-common" +version = "0.1.0" +dependencies = [ + "blake2b-rs", + "ckb-occupied-capacity", + "ckb-std", + "ckb-types", + "k256", + "molecule", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared", + "rand 0.7.3", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.9", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scroll" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaaae8f38bb311444cfb7f1979af0bc9240d95795f75f9ceddf6a59b79ceffa0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + +[[package]] +name = "serde" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tests" +version = "0.1.0" +dependencies = [ + "ckb-occupied-capacity", + "ckb-standalone-types", + "ckb-std", + "ckb-testtool", + "hex", + "k256", + "molecule", + "perun-common", + "rand 0.8.5", + "rand_core 0.6.4", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/payment-channel-ckb/devnet/contracts/tests/Cargo.toml b/payment-channel-ckb/devnet/contracts/tests/Cargo.toml new file mode 100644 index 0000000..7d3dbcb --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "tests" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ckb-testtool = "0.9" +hex = "0.4.3" +rand = "0.8.5" +perun-common = { path = "../contracts/perun-common", default-features = false, features = ["testing"] } +molecule = "0.7.3" +ckb-types = { package = "ckb-standalone-types", version = "0.1.2" } +k256 = { version = "0.11.6", default-features = false, features = ["ecdsa", "arithmetic"]} +rand_core = { version = "0.6", features = ["getrandom"] } +ckb-std = "0.10.0" +ckb-occupied-capacity = "0.108.0" diff --git a/payment-channel-ckb/devnet/contracts/tests/src/lib.rs b/payment-channel-ckb/devnet/contracts/tests/src/lib.rs new file mode 100644 index 0000000..c58a205 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/lib.rs @@ -0,0 +1,63 @@ +use ckb_testtool::ckb_types::bytes::Bytes; +use std::env; +use std::fs; +use std::path::PathBuf; +use std::str::FromStr; + +#[cfg(test)] +mod perun; +#[cfg(test)] +mod tests; + +const TEST_ENV_VAR: &str = "CAPSULE_TEST_ENV"; + +pub enum TestEnv { + Debug, + Release, +} + +impl FromStr for TestEnv { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "debug" => Ok(TestEnv::Debug), + "release" => Ok(TestEnv::Release), + _ => Err("no match"), + } + } +} + +pub struct Loader(PathBuf); + +impl Default for Loader { + fn default() -> Self { + let test_env = match env::var(TEST_ENV_VAR) { + Ok(val) => val.parse().expect("test env"), + Err(_) => TestEnv::Debug, + }; + Self::with_test_env(test_env) + } +} + +impl Loader { + fn with_test_env(env: TestEnv) -> Self { + let load_prefix = match env { + TestEnv::Debug => "debug", + TestEnv::Release => "release", + }; + let dir = env::current_dir().unwrap(); + let mut base_path = PathBuf::new(); + base_path.push(dir); + base_path.push(".."); + base_path.push("build"); + base_path.push(load_prefix); + Loader(base_path) + } + + pub fn load_binary(&self, name: &str) -> Bytes { + let mut path = self.0.clone(); + path.push(name); + fs::read(path).expect("binary").into() + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/account.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/account.rs new file mode 100644 index 0000000..6f06ec9 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/account.rs @@ -0,0 +1,41 @@ +use k256::{ecdsa::SigningKey, PublicKey}; +use rand_core::OsRng; +use std::fmt::Debug; + +pub trait Account: Debug + Clone { + fn public_key(&self) -> PublicKey; + fn name(&self) -> String; +} + +#[derive(Clone, Debug)] +pub struct TestAccount { + pub sk: SigningKey, + pub name: String, +} + +impl TestAccount { + pub fn new(sk: SigningKey, name: String) -> Self { + Self { sk, name } + } + + pub fn new_with_random_key(name: String) -> Self { + Self { + sk: SigningKey::random(&mut OsRng), + name, + } + } + + pub fn id(&self) -> &str { + &self.name + } +} + +impl Account for TestAccount { + fn public_key(&self) -> PublicKey { + PublicKey::from(self.sk.verifying_key()) + } + + fn name(&self) -> String { + self.name.clone() + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/action.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/action.rs new file mode 100644 index 0000000..71ea179 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/action.rs @@ -0,0 +1,22 @@ +/// Action is a generic channel action, that occurred in the channel. It is +/// parameterized by the type of the channel state. +pub enum Action +where + S: Applyable, +{ + Open(S), + Fund(S), + Abort(S), + Send(S), + Close(S), + ForceClose(S), +} + +/// Applyable allows to apply an action containing the same state type to its +/// current state. +pub trait Applyable +where + Self: Clone, +{ + fn apply(self, action: &Action) -> Self; +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/channel.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/channel.rs new file mode 100644 index 0000000..266d0da --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/channel.rs @@ -0,0 +1,374 @@ +use ckb_testtool::{ + ckb_types::{ + packed::{Header, OutPoint, RawHeader, Script}, + prelude::{Builder, Entity, Pack, Unpack}, + }, + context::Context, +}; +use k256::ecdsa::VerifyingKey; +use perun_common::{ + ctrue, + perun_types::{ChannelConstants, ChannelStatus, ChannelState}, +}; + +use crate::perun::{ + self, + test::{keys, Client}, +}; +use crate::perun::{harness, test}; +use std::cmp::PartialEq; +use std::collections::HashMap; +use std::fmt::Debug; + +use super::{test::cell::FundingCell, Account}; + +enum ActionValidity { + Valid, + Invalid, +} + +/// Channel is a Perun test channel. It handles the state of said channel +/// together with the participants, the current time and surrounding chain +/// context. +pub struct Channel<'a, S> +where + S: perun::Applyable + Debug + PartialEq, +{ + /// The active party. Actions called on the channel will be issued by this + /// party henceforth. + active_part: test::Client, + /// The id of the channel. + id: test::ChannelId, + /// The cell which represents this channel on-chain. + channel_cell: Option, + /// The current state of this channel. + channel_state: ChannelStatus, + /// The cells locking funds for this channel. + funding_cells: Vec, + /// The used Perun Channel Type Script. + pcts: Script, + /// All available parties. + parts: HashMap, + /// The surrounding chain context. + ctx: &'a mut Context, + /// The intial test harness environment supplying all Perun specific + /// contracts and functionality for deployment etc. + env: &'a harness::Env, + /// The current channel time. + current_time: u64, + /// The validity of the next action. + validity: ActionValidity, + /// The history of actions performed on this channel. + history: Vec>, + /// The currently tracked channel state as produced by the unit under test. + current_state: S, +} + +/// call_action! is a macro that calls the given action on the currently active +/// participant. It also sets the validity of the next action to `Valid`. +macro_rules! call_action { + ($self:ident, $action:ident $(, $x:expr)*$(,)*) => ( + { + println!("calling action {} on {}", stringify!($action), $self.active_part.name()); + let res = match $self.validity { + ActionValidity::Valid => $self.active_part.$action($self.ctx, $self.env, $($x),*), + ActionValidity::Invalid => { + let res = $self.active_part.$action($self.ctx, $self.env, $($x),*); + match res { + Ok(_) => Err(perun::Error::new("action should have failed")), + Err(_) => Ok(Default::default()), + } + } + }; + $self.validity = ActionValidity::Valid; + res + } +) +} + +impl<'a, S> Channel<'a, S> +where + S: Default + perun::Applyable + Debug + PartialEq, +{ + pub fn new( + context: &'a mut Context, + env: &'a perun::harness::Env, + parts: &[perun::TestAccount], + ) -> Self { + let m_parts: HashMap<_, _> = parts + .iter() + .enumerate() + .map(|(i, p)| { + ( + p.name().clone(), + perun::test::Client::new(i as u8, p.name(), p.sk.clone()), + ) + }) + .collect(); + let active = m_parts.get(&parts[0].name()).expect("part not found"); + + Channel { + id: test::ChannelId::new(), + current_time: 0, + ctx: context, + env, + pcts: Script::default(), + channel_cell: None, + channel_state: ChannelStatus::default(), + funding_cells: Vec::new(), + active_part: active.clone(), + parts: m_parts.clone(), + validity: ActionValidity::Valid, + history: Vec::new(), + current_state: S::default(), + } + } + + /// with sets the currently active participant to the given `part`. + pub fn with(&mut self, part: &str) -> &mut Self { + self.active_part = self.parts.get(part).expect("part not found").clone(); + self + } + + /// delay the environment by the given `duration`, this makes the next + /// transaction receive a block_header with a timestamp that is `duration` + /// in the future. + pub fn delay(&mut self, duration: u64) { + self.current_time += duration; + } + + /// open a channel using the currently active participant set by `with(..)` + /// with the value given in `funding_agreement`. + pub fn open(&mut self, funding_agreement: &test::FundingAgreement) -> Result<(), perun::Error> { + let (id, or) = call_action!(self, open, funding_agreement)?; + self.id = id; + self.channel_cell = Some(or.channel_cell.clone()); + // Make sure the channel cell is linked to a header with a timestamp. + self.push_header_with_cell(or.channel_cell); + let mut fs = self.funding_cells.clone(); + fs.extend(or.funds_cells.iter().cloned()); + self.funding_cells = fs.to_vec(); + self.pcts = or.pcts; + self.channel_state = or.state; + Ok(()) + } + + fn push_header_with_cell(&mut self, cell: OutPoint) { + let header = Header::new_builder() + .raw( + RawHeader::new_builder() + .timestamp(self.current_time.pack()) + .build(), + ) + .build() + .into_view(); + self.ctx.insert_header(header.clone()); + // We will always use 0 as the `tx_index`. + self.ctx.link_cell_with_block(cell, header.hash(), 0); + } + + /// fund a channel using the currently active participant set by `with(..)` + /// with the value given in `funding_agreement`. + pub fn fund(&mut self, funding_agreement: &test::FundingAgreement) -> Result<(), perun::Error> { + // TODO: Lift this check into the type-system to make this more readable and stick to DRY. + let res = match &self.channel_cell { + Some(channel_cell) => { + call_action!( + self, + fund, + self.id, + funding_agreement, + channel_cell.clone(), + self.channel_state.clone(), + self.pcts.clone() + ) + } + None => panic!("no channel cell, invalid test setup"), + }?; + // TODO: DRY please. + self.channel_state = res.state; + self.channel_cell = Some(res.channel_cell.clone()); + self.push_header_with_cell(res.channel_cell); + let mut fs = self.funding_cells.clone(); + fs.extend(res.funds_cells.iter().cloned()); + self.funding_cells = fs.to_vec(); + Ok(()) + } + + /// send a payment using the currently active participant set by `with(..)` + /// to the given `to` participant. + pub fn send(&mut self, to: &P, amount: u64) -> Result<(), perun::Error> { + let to = self.parts.get(&to.name()).expect("part not found"); + self.active_part.send(self.ctx, self.env) + } + + /// dispute a channel using the currently active participant set by + /// `with(..)`. + pub fn dispute(&mut self) -> Result<(), perun::Error> { + self.channel_state = self.channel_state.clone().as_builder().disputed(ctrue!()).build(); + let sigs = self.sigs_for_channel_state()?; + let res = match &self.channel_cell { + Some(channel_cell) => { + call_action!( + self, + dispute, + self.id, + channel_cell.clone(), + self.channel_state.clone(), + self.pcts.clone(), + sigs, + ) + } + None => panic!("no channel cell, invalid test setup"), + }?; + self.channel_cell = Some(res.channel_cell.clone()); + self.push_header_with_cell(res.channel_cell); + Ok(()) + } + + /// abort a channel using the currently active participant set by + /// `with(..)`. + pub fn abort(&mut self) -> Result<(), perun::Error> { + match &self.channel_cell { + Some(channel_cell) => { + call_action!( + self, + abort, + self.id, + self.channel_state.clone(), + channel_cell.clone(), + self.funding_cells.clone() + ) + } + None => panic!("no channel cell, invalid test setup"), + }?; + Ok(()) + } + + /// finalize finalizes the channel state in use. It has to be called for + /// before successful close actions. It bumps the version of the channel state. + pub fn finalize(&mut self) -> &mut Self { + let status = self.channel_state.clone(); + let old_version: u64 = status.state().version().unpack(); + let state = status.state().as_builder().is_final(ctrue!()).version((old_version + 1).pack()).build(); + self.channel_state = status.as_builder().state(state).build(); + self + } + + pub fn update(&mut self, update: impl Fn(&ChannelState) -> Result) -> &mut Self { + let new_state = update(&self.channel_state.state()).expect("update failed"); + self.channel_state = self.channel_state + .clone() + .as_builder() + .state(new_state) + .build(); + self + } + + /// close a channel using the currently active participant set by + /// `with(..)`. + pub fn close(&mut self) -> Result<(), perun::Error> { + let sigs = self.sigs_for_channel_state()?; + match self.channel_cell.clone() { + Some(channel_cell) => call_action!( + self, + close, + self.id, + channel_cell, + self.funding_cells.clone(), + self.channel_state.clone(), + sigs + ), + None => panic!("no channel cell, invalid test setup"), + }?; + Ok(()) + } + + fn sigs_for_channel_state(&self) -> Result<[Vec; 2], perun::Error> { + // We have to unpack the ChannelConstants like this. Otherwise the molecule header is still + // part of the slice. On-chain we have no problem due to unpacking the arguments, but this + // does not seem possible in this scope. + let bytes = self.pcts.args().raw_data(); + // We want to have the correct order of clients in an array to construct signatures. For + // consistency we use the ChannelConstants which are also used to construct the channel and + // look up the participants according to their public key identifier. + let s = ChannelConstants::from_slice(&bytes)?; + let resolve_client = |verifying_key_raw: Vec| -> Result { + let verifying_key = VerifyingKey::from_sec1_bytes(verifying_key_raw.as_slice())?; + let pubkey = keys::verifying_key_to_byte_array(&verifying_key); + self.parts + .values() + .cloned() + .find(|c| c.pubkey() == pubkey) + .ok_or("unknown participant in channel parameters".into()) + }; + let clients: Result, _> = s + .params() + .mk_party_pubkeys() + .iter() + .cloned() + .map(resolve_client) + .collect(); + let sigs: Result, _> = clients? + .iter() + .map(|p| p.sign(self.channel_state.state())) + .collect(); + let sig_arr: [Vec; 2] = sigs?.try_into()?; + Ok(sig_arr) + } + + /// force_close a channel using the currently active participant set by + /// `with(..)`. + pub fn force_close(&mut self) -> Result<(), perun::Error> { + let h = Header::new_builder() + .raw( + RawHeader::new_builder() + .timestamp(self.current_time.pack()) + .build(), + ) + .build() + .into_view(); + // Push a header with the current time which can be used in force_close + // as for time validation purposes. + self.ctx.insert_header(h.clone()); + match self.channel_cell.clone() { + Some(channel_cell) => call_action!( + self, + force_close, + self.id, + channel_cell, + self.funding_cells.clone(), + self.channel_state.clone(), + ), + None => panic!("no channel cell, invalid test setup"), + }?; + Ok(()) + } + + /// valid sets the validity of the next action to valid. (default) + pub fn valid(&mut self) -> &mut Self { + self.validity = ActionValidity::Valid; + self + } + + /// invalid sets the validity of the next action to invalid. It resets to + /// valid after the next action. + pub fn invalid(&mut self) -> &mut Self { + self.validity = ActionValidity::Invalid; + self + } + + /// assert asserts that the channel is in a valid state according to all + /// actions that have been performed on it. This also includes the + /// surrounding context for this channel. + /// + /// If a channel was closed, it will also assert that all participants + /// were properly paid. + pub fn assert(&self) { + let expected_state: S = self + .history + .iter() + .fold(Default::default(), |acc, act| acc.apply(act)); + assert_eq!(expected_state, self.current_state) + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/error.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/error.rs new file mode 100644 index 0000000..6af554f --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/error.rs @@ -0,0 +1,65 @@ +use molecule::error::VerificationError; +use std::{error, fmt}; + +use ckb_testtool::ckb_error; + +#[derive(Debug)] +pub struct Error { + details: String, +} + +impl Error { + pub fn new(msg: &str) -> Error { + Error { + details: msg.to_string(), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.details) + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + &self.details + } +} + +impl From<&str> for Error { + fn from(err: &str) -> Error { + Error::new(err) + } +} + +impl From for Error { + fn from(err: ckb_occupied_capacity::Error) -> Error { + Error::new(&err.to_string()) + } +} + +impl From for Error { + fn from(err: ckb_error::Error) -> Error { + Error::new(&err.to_string()) + } +} + +impl From for Error { + fn from(err: k256::ecdsa::Error) -> Error { + Error::new(&err.to_string()) + } +} + +impl From for Error { + fn from(err: VerificationError) -> Error { + Error::new(&err.to_string()) + } +} + +impl From>> for Error { + fn from(vs: Vec>) -> Error { + Error::new(&format!("converting from nested vectors: {:?}", vs)) + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/harness.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/harness.rs new file mode 100644 index 0000000..4e288fc --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/harness.rs @@ -0,0 +1,285 @@ +use crate::perun; +use crate::Loader; +use ckb_occupied_capacity::{Capacity, IntoCapacity}; +use ckb_testtool::{ + builtin::ALWAYS_SUCCESS, + ckb_types::{bytes::Bytes, packed::*, prelude::*}, + context::Context, +}; +use perun_common::cfalse; +use perun_common::perun_types::ChannelStateBuilder; +use perun_common::perun_types::ChannelStatusBuilder; +use perun_common::perun_types::{self, ChannelStatus, ChannelToken}; + +use super::test::ChannelId; +use super::test::FundingAgreement; +use super::test::FundingAgreementEntry; + +// Env contains all chain information required for running Perun +// tests. +pub struct Env { + // Perun contracts. + pub pcls_out_point: OutPoint, + pub pcts_out_point: OutPoint, + pub pfls_out_point: OutPoint, + // Auxiliary contracts. + pub always_success_out_point: OutPoint, + pub sample_udt_out_point: OutPoint, + + // Perun scripts. + pcls_script: Script, + pcts_script: Script, + pfls_script: Script, + pub pcls_script_dep: CellDep, + pub pcts_script_dep: CellDep, + pub pfls_script_dep: CellDep, + // Auxiliary scripts. + pub always_success_script: Script, + pub always_success_script_dep: CellDep, + pub sample_udt_script: Script, + pub sample_udt_script_dep: CellDep, + // Maximum amount of cycles used when verifying TXs. + pub max_cycles: u64, + pub min_capacity_no_script: Capacity, + pub min_capacity_pfls: Capacity, + pub sample_udt_max_cap: Capacity, + pub challenge_duration: u64, +} + +impl Env { + // prepare_env prepares the given context to be used for running Perun + // tests. + pub fn new( + context: &mut Context, + max_cycles: u64, + challenge_duration: u64, + ) -> Result { + // Perun contracts. + let pcls: Bytes = Loader::default().load_binary("perun-channel-lockscript"); + let pcts: Bytes = Loader::default().load_binary("perun-channel-typescript"); + let pfls: Bytes = Loader::default().load_binary("perun-funds-lockscript"); + let sample_udt: Bytes = Loader::default().load_binary("sample-udt"); + // Deploying the contracts returns the cell they are deployed in. + let pcls_out_point = context.deploy_cell(pcls); + let pcts_out_point = context.deploy_cell(pcts); + let pfls_out_point = context.deploy_cell(pfls); + let sample_udt_out_point = context.deploy_cell(sample_udt); + // Auxiliary contracts. + let always_success_out_point = context.deploy_cell(ALWAYS_SUCCESS.clone()); + + // Prepare scripts. + // Perun scripts. + let pcls_script = context + .build_script(&pcls_out_point, Default::default()) + .ok_or("perun-channel-lockscript")?; + let pcts_script = context + .build_script( + &pcts_out_point, + perun_types::ChannelConstants::default().as_bytes(), + ) + .ok_or("perun-channel-typescript")?; + let pfls_script = context + .build_script(&pfls_out_point, Default::default()) + .ok_or("perun-funds-lockscript")?; + let sample_udt_script = context + .build_script(&sample_udt_out_point, Default::default()) + .ok_or("sample-udt")?; + let pcls_script_dep = CellDep::new_builder() + .out_point(pcls_out_point.clone()) + .build(); + let pcts_script_dep = CellDep::new_builder() + .out_point(pcts_out_point.clone()) + .build(); + let pfls_script_dep = CellDep::new_builder() + .out_point(pfls_out_point.clone()) + .build(); + let sample_udt_script_dep = CellDep::new_builder() + .out_point(sample_udt_out_point.clone()) + .build(); + let sample_udt_max_cap = sample_udt_script.occupied_capacity()?.safe_mul(Capacity::shannons(10))?; + // Auxiliary scripts. + let always_success_script = context + .build_script(&always_success_out_point, Bytes::from(vec![0])) + .expect("always_success"); + let always_success_script_dep = CellDep::new_builder() + .out_point(always_success_out_point.clone()) + .build(); + + // Calculate minimum amount of capacity required for a cell using the always success script. + let tmp_output = CellOutput::new_builder() + .capacity(0u64.pack()) + .lock(always_success_script.clone()) + .build(); + let min_capacity_no_script = tmp_output.occupied_capacity(0u64.into_capacity())?; + + // Calculate minimum amount of capacity required for a cell using the PFLS script. + let tmp_output = CellOutput::new_builder() + .capacity(0u64.pack()) + .lock(pfls_script.clone()) + .build(); + let pfls_args_capacity = pcts_script.calc_script_hash().as_bytes().len() as u64; + let min_capacity_pfls = tmp_output.occupied_capacity(pfls_args_capacity.into_capacity())?; + println!("pfls code hash: {}", pfls_script.code_hash()); + println!("asset code hash: {}", sample_udt_script.code_hash()); + println!("pcts code hash: {}", pcts_script.code_hash()); + println!("pcls code hash: {}", pcls_script.code_hash()); + println!("always_success code hash: {}", always_success_script.code_hash()); + Ok(Env { + pcls_out_point, + pcts_out_point, + pfls_out_point, + always_success_out_point, + sample_udt_out_point, + pcls_script, + pcts_script, + pfls_script, + pcls_script_dep, + pcts_script_dep, + pfls_script_dep, + always_success_script, + always_success_script_dep, + sample_udt_script, + sample_udt_script_dep, + max_cycles, + min_capacity_no_script, + min_capacity_pfls, + sample_udt_max_cap, + challenge_duration, + }) + } + + pub fn build_pcls(&self, context: &mut Context, args: Bytes) -> Script { + let pcls_out_point = &self.pcls_out_point; + context + .build_script(pcls_out_point, args) + .expect("perun-channel-lockscript") + } + + pub fn build_pcts(&self, context: &mut Context, args: Bytes) -> Script { + let pcts_out_point = &self.pcts_out_point; + context + .build_script(pcts_out_point, args) + .expect("perun-channel-typescript") + } + + pub fn build_pfls(&self, context: &mut Context, args: Bytes) -> Script { + let pfls_out_point = &self.pfls_out_point; + context + .build_script(pfls_out_point, args) + .expect("perun-funds-lockscript") + } + + pub fn build_lock_script(&self, context: &mut Context, args: Bytes) -> Script { + let always_success_out_point = &self.always_success_out_point; + context + .build_script(always_success_out_point, args) + .expect("always_success") + } + + pub fn min_capacity_for_channel(&self, cs: ChannelStatus) -> Result { + let tmp_output = CellOutput::new_builder() + .capacity(0u64.pack()) + .lock(self.pcls_script.clone()) + .type_(Some(self.pcts_script.clone()).pack()) + .build(); + let cs_capacity = Capacity::bytes(cs.as_bytes().len())?; + let min_capacity = tmp_output.occupied_capacity(cs_capacity)?; + Ok(min_capacity) + } + + pub fn create_channel_token(&self, context: &mut Context) -> (ChannelToken, OutPoint) { + let channel_token_outpoint = context.create_cell( + CellOutput::new_builder() + .capacity(self.min_capacity_no_script.pack()) + .lock(self.always_success_script.clone()) + .build(), + Bytes::default(), + ); + let packed_outpoint = OutPointBuilder::default() + .tx_hash(channel_token_outpoint.tx_hash()) + .index(channel_token_outpoint.index()) + .build(); + ( + perun_types::ChannelTokenBuilder::default() + .out_point(packed_outpoint.clone()) + .build(), + packed_outpoint, + ) + } + + /// create_funds_from_agreement creates a new cell with the funds for the given party index locked + /// by the always_success_script parameterized on the party index. + pub fn create_funds_from_agreement( + &self, + context: &mut Context, + party_index: u8, + funding_agreement: &FundingAgreement, + ) -> Result, perun::Error> { + let mut funds = self.create_ckbytes_funds_for_index(context, party_index, funding_agreement.expected_ckbytes_funding_for(party_index)?)?; + funds.append(self.create_sudts_funds_for_index(context, party_index, funding_agreement.expected_sudts_funding_for(party_index)?)?.as_mut()); + return Ok(funds); + } + + pub fn create_ckbytes_funds_for_index( + &self, + context: &mut Context, + party_index: u8, + required_funds: u64, + ) -> Result, perun::Error> { + // Create cell containing the required funds for this party. + let my_output = CellOutput::new_builder() + .capacity(required_funds.pack()) + // Lock cell using the correct party index. + .lock(self.build_lock_script(context, Bytes::from(vec![party_index]))) + .build(); + let cell = context.create_cell(my_output.clone(), Bytes::default()); + Ok(vec![(cell, required_funds.into_capacity())]) + } + + pub fn create_sudts_funds_for_index(&self, context: &mut Context, party_index: u8, required_funds: Vec<(Script, Capacity, u128)>) -> Result, perun::Error> { + let mut outs: Vec<(OutPoint, Capacity)> = Vec::new(); + for (sudt_script, capacity, amount) in required_funds { + let my_output = CellOutput::new_builder() + .capacity(capacity.pack()) + // Lock cell using the correct party index. + .lock(self.build_lock_script(context, Bytes::from(vec![party_index]))) + .type_(Some(sudt_script).pack()) + .build(); + let cell = context.create_cell(my_output.clone(), Bytes::from(amount.to_le_bytes().to_vec())); + outs.push((cell, capacity)); + } + Ok(outs) + } + + pub fn create_min_cell_for_index(&self, context: &mut Context, party_index: u8) -> OutPoint { + self.create_ckbytes_funds_for_index(context, party_index, self.min_capacity_no_script.as_u64()) + .unwrap() + .get(0).unwrap().clone().0 + } + + pub fn build_initial_channel_state( + &self, + channel_id: ChannelId, + client_index: u8, + funding_agreement: &FundingAgreement, + ) -> Result { + let all_indices = funding_agreement + .content() + .iter() + .map(|FundingAgreementEntry { index, .. }| *index) + .collect::>(); + let channel_balances = funding_agreement.mk_balances(all_indices)?; + let channel_state = ChannelStateBuilder::default() + .channel_id(channel_id.to_byte32()) + .balances(channel_balances) + .version(Default::default()) + .is_final(cfalse!()) + .build(); + let channel_status = ChannelStatusBuilder::default() + .state(channel_state) + .funded(cfalse!()) + .disputed(cfalse!()) + .build(); + Ok(channel_status) + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/mod.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/mod.rs new file mode 100644 index 0000000..cbf1768 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/mod.rs @@ -0,0 +1,22 @@ +#[cfg(test)] +pub mod harness; + +mod error; +pub use error::*; + +pub mod channel; + +pub mod mutators; + +pub mod test; + +mod action; +pub use action::*; + +mod state; +pub use state::*; + +pub mod random; + +mod account; +pub use account::*; diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/mutators.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/mutators.rs new file mode 100644 index 0000000..24abb8c --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/mutators.rs @@ -0,0 +1,69 @@ +use crate::perun; +use ckb_testtool::ckb_types::prelude::{Unpack, Pack}; +use molecule::prelude::{Entity, Builder}; +use perun_common::perun_types::{ChannelState, CKByteDistribution, SUDTDistribution}; + +pub enum Direction { + AtoB, + BtoA, +} + +/// id returns a mutator that does not change the channel state. +pub fn id() -> impl Fn(&ChannelState) -> Result { + |s| Ok(s.clone()) +} + +/// bump_version returns a mutator that bumps the version number of the channel state. +pub fn bump_version() -> impl Fn(&ChannelState) -> Result { + |s| Ok(s.clone().as_builder().version((Unpack::::unpack(&s.version()) + 1u64).pack()).build()) +} + +/// pay_ckbytes returns a mutator that transfers the given amount of CKBytes from one party to the other according to the +/// specified direction. It also bumps the version number of the channel state. +pub fn pay_ckbytes(direction: Direction, amount: u64) -> impl Fn(&ChannelState) -> Result { + let (sender_index, receiver_index) = get_indices(direction); + move |s| { + let s_bumped = bump_version()(s)?; + let mut distribution = s_bumped.balances().ckbytes().to_array(); + if distribution[sender_index] < amount { + return Err(perun::Error::new("insufficient funds")); + } + distribution[sender_index] -= amount; + distribution[receiver_index] += amount; + let balances = s_bumped.balances().clone().as_builder().ckbytes(CKByteDistribution::from_array(distribution)).build(); + Ok(s_bumped.clone().as_builder().balances(balances).build()) + } +} + +/// pay_sudt returns a mutator that transfers the given amount of the specified SUDT index from one party to the other according to the +/// specified direction. It also bumps the version number of the channel state. +pub fn pay_sudt(direction:Direction, amount: u128, asset_index: usize)-> impl Fn(&ChannelState) -> Result { + let (sender_index, receiver_index) = get_indices(direction); + move |s| { + let s_bumped = bump_version()(s)?; + let sudts = s_bumped.balances().sudts().clone(); + if asset_index >= sudts.len() { + return Err(perun::Error::new("asset index out of bounds")); + } + let sudt = sudts.get(asset_index).unwrap(); + let mut distribution = sudt.distribution().to_array(); + if distribution[sender_index] < amount { + return Err(perun::Error::new("insufficient funds")); + } + distribution[sender_index] -= amount; + distribution[receiver_index] += amount; + let packed_sudt = sudt.clone().as_builder().distribution(SUDTDistribution::from_array(distribution)).build(); + let mut new_sudts = sudts.clone().as_builder(); + new_sudts.replace(asset_index, packed_sudt).unwrap(); + let balances = s_bumped.balances().clone().as_builder().sudts(new_sudts.build()).build(); + Ok(s_bumped.clone().as_builder().balances(balances).build()) + } +} + +/// get_indices returns (sender_index, receiver_index) +fn get_indices(direction: Direction) -> (usize, usize) { + match direction { + Direction::AtoB => (0, 1), + Direction::BtoA => (1, 0), + } +} \ No newline at end of file diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/random.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/random.rs new file mode 100644 index 0000000..3351e08 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/random.rs @@ -0,0 +1,13 @@ +use rand::Rng; + +use super::TestAccount; + +pub fn nonce() -> [u8; 32] { + let mut rng = rand::thread_rng(); + let nonce: [u8; 32] = rng.gen(); + nonce +} + +pub fn account(name: &str) -> TestAccount { + TestAccount::new_with_random_key(name.to_string()) +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/state.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/state.rs new file mode 100644 index 0000000..a06a364 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/state.rs @@ -0,0 +1,17 @@ +use crate::perun::{Action, Applyable}; + +#[derive(Debug, Clone, Default, PartialEq)] +pub struct State {} + +impl Applyable for State { + fn apply(self, action: &Action) -> Self { + match action { + Action::Open(_) => self, + Action::Fund(_) => self, + Action::Abort(_) => self, + Action::Send(_) => self, + Action::Close(_) => self, + Action::ForceClose(_) => self, + } + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/cell.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/cell.rs new file mode 100644 index 0000000..668d262 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/cell.rs @@ -0,0 +1,74 @@ +use ckb_testtool::{ckb_types::{packed::{OutPoint, CellOutput}, prelude::{Unpack, Pack}}}; +use ckb_types::bytes; +use molecule::prelude::{Entity, Builder}; + +use super::{Asset, AssetRegister}; + + +#[derive(Debug, Clone)] + +pub enum FundingCell { + FundingCellCKBytes(FundingCellCKBytes), + FundingCellSUDT(FundingCellSUDT), +} + +#[derive(Debug, Clone)] +pub struct FundingCellCKBytes { + // Index of the party whose initial funds are contained in this cell. + pub index: u8, + // The amount of funding for the party given by index. + pub cap: u64, + // The outpoint of the cell containing the funds. + pub out_point: OutPoint, +} + +#[derive(Debug, Clone)] +pub struct FundingCellSUDT { + // Index of the party whose initial funds are contained in this cell. + pub index: u8, + // The amount of funding for the party given by index. + pub cap: u64, + // The outpoint of the cell containing the funds. + pub out_point: OutPoint, + pub asset: Asset, + pub asset_amount: u128, +} + +impl Default for FundingCell { + fn default() -> Self { + FundingCell::FundingCellCKBytes(FundingCellCKBytes { + index: 0, + cap: 0, + out_point: OutPoint::default(), + }) + } +} + +pub fn mk_funding_cell(party_index: u8, out_point: OutPoint, cell_output: &CellOutput, data: bytes::Bytes, register: &AssetRegister) -> FundingCell { + if cell_output.type_().is_some(){ + let asset = register.guess_asset_from_script(&cell_output.type_().to_opt().unwrap()).unwrap(); + FundingCell::FundingCellSUDT(FundingCellSUDT { + index: party_index, + cap: cell_output.capacity().unpack(), + out_point, + asset: asset.clone(), + asset_amount: u128::from_le_bytes(data.to_vec().as_slice().try_into().unwrap()), + }) + } else { + FundingCell::FundingCellCKBytes(FundingCellCKBytes { + index: party_index, + cap: cell_output.capacity().unpack(), + out_point, + }) + } + +} + +impl FundingCell { + pub fn outpoint(&self) -> OutPoint { + match self { + FundingCell::FundingCellCKBytes(f) => f.out_point.clone(), + FundingCell::FundingCellSUDT(f) => f.out_point.clone(), + } + } +} \ No newline at end of file diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/channel_id.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/channel_id.rs new file mode 100644 index 0000000..3b0f445 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/channel_id.rs @@ -0,0 +1,38 @@ +use ckb_testtool::ckb_types::{ + packed::{Byte, Byte32, Byte32Builder}, + prelude::Builder, +}; +use rand::Rng; + +#[derive(Debug, Clone, Copy)] +pub struct ChannelId([u8; 32]); + +impl ChannelId { + pub fn new() -> Self { + ChannelId(Default::default()) + } + + pub fn new_random() -> Self { + ChannelId(rand::thread_rng().gen()) + } + + pub fn to_byte32(&self) -> Byte32 { + let mut byte32: [Byte; 32] = [0u8.into(); 32]; + let x = self.0; + let y = x.iter().map(|x| (*x).into()).collect::>(); + byte32.copy_from_slice(&y); + Byte32Builder::default().set(byte32).build() + } +} + +impl From<[u8; 32]> for ChannelId { + fn from(bytes: [u8; 32]) -> Self { + ChannelId(bytes) + } +} + +impl Default for ChannelId { + fn default() -> Self { + ChannelId([0u8; 32]) + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/client.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/client.rs new file mode 100644 index 0000000..cdc8aec --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/client.rs @@ -0,0 +1,259 @@ +use ckb_testtool::ckb_traits::CellDataProvider; + +use ckb_testtool::ckb_types::core::ScriptHashType; +use ckb_testtool::ckb_types::packed::{OutPoint, Script}; +use ckb_testtool::ckb_types::prelude::*; +use ckb_testtool::context::Context; + +use k256::ecdsa::signature::hazmat::PrehashSigner; +use perun_common::*; + +use perun_common::helpers::blake2b256; +use perun_common::perun_types::{ChannelState, ChannelStatus}; + +use crate::perun; +use crate::perun::harness; +use crate::perun::random; +use crate::perun::test; +use crate::perun::test::transaction::{AbortArgs, OpenResult}; +use crate::perun::test::{keys, transaction}; + +use k256::ecdsa::{Signature, SigningKey}; + +use super::cell::FundingCell; +use super::ChannelId; + +#[derive(Clone, Debug)] +pub struct Client { + index: u8, + signing_key: SigningKey, + name: String, +} + +impl Client { + pub fn new(idx: u8, name: String, sk: SigningKey) -> Client { + Client { + index: idx, + name, + signing_key: sk, + } + } + + // pubkey returns the public key of the client as a SEC1 encoded byte + // array. + pub fn pubkey(&self) -> [u8; 33] { + keys::verifying_key_to_byte_array(&self.signing_key.verifying_key()) + } + + pub fn name(&self) -> String { + self.name.clone() + } + + pub fn open( + &self, + ctx: &mut Context, + env: &harness::Env, + funding_agreement: &test::FundingAgreement, + ) -> Result<(ChannelId, OpenResult), perun::Error> { + // Prepare environment so that this party has the required funds. + let inputs = + env.create_funds_from_agreement(ctx, self.index, funding_agreement)?; + // Create the channel token. + let (channel_token, channel_token_outpoint) = env.create_channel_token(ctx); + + let pcls = env.build_pcls(ctx, Default::default()); + let pcls_code_hash = pcls.code_hash(); + let pfls_code_hash = ctx + .get_cell_data_hash(&env.pfls_out_point) + .expect("pfls hash"); + let always_success_hash = ctx + .get_cell_data_hash(&env.always_success_out_point) + .expect("always success hash"); + + let parties = funding_agreement.mk_participants(ctx, env, env.min_capacity_no_script); + + let chan_params = perun_types::ChannelParametersBuilder::default() + .party_a(parties[0].clone()) + .party_b(parties[1].clone()) + .nonce(random::nonce().pack()) + .challenge_duration(env.challenge_duration.pack()) + .app(Default::default()) + .is_ledger_channel(ctrue!()) + .is_virtual_channel(cfalse!()) + .build(); + let cid_raw = blake2b256(chan_params.as_slice()); + let cid = ChannelId::from(cid_raw); + let chan_const = perun_types::ChannelConstantsBuilder::default() + .params(chan_params) + .pfls_code_hash(pfls_code_hash.clone()) + .pfls_hash_type(ScriptHashType::Data1.into()) + .pfls_min_capacity(env.min_capacity_pfls.pack()) + .pcls_code_hash(pcls_code_hash.clone()) + .pcls_hash_type(ScriptHashType::Data1.into()) + .thread_token(channel_token.clone()) + .build(); + + let pcts = env.build_pcts(ctx, chan_const.as_bytes()); + let pfls = env.build_pfls(ctx, pcts.calc_script_hash().as_bytes()); + + let args = transaction::OpenArgs { + cid, + funding_agreement: funding_agreement.clone(), + channel_token_outpoint: channel_token_outpoint.clone(), + inputs: inputs, + party_index: self.index, + pcls_script: pcls, + pcts_script: pcts, + pfls_script: pfls, + }; + let or = transaction::mk_open(ctx, env, args)?; + + let cycles = ctx.verify_tx(&or.tx, env.max_cycles)?; + println!("consumed cycles: {}", cycles); + Ok((cid, or)) + } + + pub fn fund( + &self, + ctx: &mut Context, + env: &harness::Env, + _cid: test::ChannelId, + funding_agreement: &test::FundingAgreement, + channel_cell: OutPoint, + channel_state: ChannelStatus, + pcts: Script, + ) -> Result { + // Prepare environment so that this party has the required funds. + let inputs = + env.create_funds_from_agreement(ctx, self.index, funding_agreement)?; + let fr = transaction::mk_fund( + ctx, + env, + transaction::FundArgs { + channel_cell, + funding_agreement: funding_agreement.clone(), + party_index: self.index, + state: channel_state, + inputs, + pcts, + }, + )?; + let cycles = ctx.verify_tx(&fr.tx, env.max_cycles)?; + println!("consumed cycles: {}", cycles); + Ok(fr) + } + + pub fn send(&self, ctx: &mut Context, env: &harness::Env) -> Result<(), perun::Error> { + Ok(()) + } + + pub fn sign(&self, state: ChannelState) -> Result, perun::Error> { + let s: Signature = self + .signing_key + .sign_prehash(&blake2b256(state.as_slice()))?; + Ok(Vec::from(s.to_der().as_bytes())) + } + + pub fn dispute( + &self, + ctx: &mut Context, + env: &harness::Env, + _cid: test::ChannelId, + channel_cell: OutPoint, + channel_state: ChannelStatus, + pcts: Script, + sigs: [Vec; 2], + ) -> Result { + let dr = transaction::mk_dispute( + ctx, + env, + transaction::DisputeArgs { + channel_cell, + state: channel_state, + party_index: self.index, + pcts_script: pcts, + sigs, + }, + )?; + let cycles = ctx.verify_tx(&dr.tx, env.max_cycles)?; + println!("consumed cycles: {}", cycles); + Ok(dr) + } + + pub fn abort( + &self, + ctx: &mut Context, + env: &harness::Env, + _cid: test::ChannelId, + state: ChannelStatus, + channel_cell: OutPoint, + funds: Vec, + ) -> Result { + let ar = transaction::mk_abort( + ctx, + env, + AbortArgs { + channel_cell, + funds, + state, + party_index: self.index, + }, + )?; + let cycles = ctx.verify_tx(&ar.tx, env.max_cycles)?; + println!("consumed cycles: {}", cycles); + Ok(ar) + } + + pub fn close( + &self, + ctx: &mut Context, + env: &harness::Env, + _cid: test::ChannelId, + channel_cell: OutPoint, + funds_cells: Vec, + state: ChannelStatus, + sigs: [Vec; 2], + ) -> Result { + let cr = transaction::mk_close( + ctx, + env, + transaction::CloseArgs { + channel_cell, + funds_cells, + party_index: self.index, + state, + sigs, + }, + )?; + let cycles = ctx.verify_tx(&cr.tx, env.max_cycles)?; + println!("consumed cycles: {}", cycles); + Ok(cr) + } + + pub fn force_close( + &self, + ctx: &mut Context, + env: &harness::Env, + _cid: test::ChannelId, + channel_cell: OutPoint, + funds_cells: Vec, + state: ChannelStatus, + ) -> Result { + // We will pass all available headers to the force close transaction. + let hs = ctx.headers.keys().cloned().collect(); + let fcr = transaction::mk_force_close( + ctx, + env, + transaction::ForceCloseArgs { + headers: hs, + channel_cell, + party_index: self.index, + funds_cells, + state, + }, + )?; + let cycles = ctx.verify_tx(&fcr.tx, env.max_cycles)?; + println!("consumed cycles: {}", cycles); + Ok(fcr) + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/funding_agreement.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/funding_agreement.rs new file mode 100644 index 0000000..5723b99 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/funding_agreement.rs @@ -0,0 +1,282 @@ +use ckb_occupied_capacity::Capacity; +use ckb_testtool::ckb_types::packed::{Byte as PackedByte, Script}; +use ckb_testtool::ckb_types::prelude::*; +use ckb_testtool::context::Context; +use ckb_types::bytes::Bytes; +use k256::elliptic_curve::sec1::ToEncodedPoint; +use k256::PublicKey; +use perun_common::perun_types::{ + self, Balances, CKByteDistribution, ParticipantBuilder, + SEC1EncodedPubKeyBuilder, SUDTAllocation, SUDTAsset, SUDTBalances, SUDTDistribution, +}; + +use crate::perun; + +#[derive(Debug, Clone)] +pub struct FundingAgreement { + entries: Vec, + register: AssetRegister, +} + +impl FundingAgreement { + pub fn register(&self) -> &AssetRegister { + &self.register + } + + pub fn has_udts(&self) -> bool { + self.register.len() > 0 + } + + pub fn new_with_capacities(caps: Vec<(P, u64)>) -> Self { + FundingAgreement { + entries: caps + .iter() + .enumerate() + .map(|(i, (acc, c))| FundingAgreementEntry { + ckbytes: *c, + sudts: Vec::new(), + index: i as u8, + pub_key: acc.public_key(), + }) + .collect(), + register: AssetRegister::new(), + } + } + + pub fn new_with_capacities_and_sudt( + caps: Vec<(P, u64)>, + asset: &Script, + max_cap: u64, + asset_amt: Vec<(P, u128)>, + ) -> Self { + let mut r = AssetRegister::new(); + let a = r.register_asset( + SUDTAsset::new_builder() + .type_script(asset.clone()) + .max_capacity(max_cap.pack()) + .build(), + ); + FundingAgreement { + entries: caps + .iter() + .enumerate() + .map(|(i, (acc, c))| FundingAgreementEntry { + ckbytes: *c, + sudts: vec![(a, asset_amt.get(i).unwrap().1)], + index: i as u8, + pub_key: acc.public_key(), + }) + .collect(), + register: r, + } + } + + pub fn content(&self) -> &Vec { + &self.entries + } + + pub fn mk_participants( + &self, + ctx: &mut Context, + env: &perun::harness::Env, + payment_min_capacity: Capacity, + ) -> Vec { + self.entries + .iter() + .map(|entry| { + let sec1_encoded_bytes: Vec<_> = entry + .pub_key + .to_encoded_point(true) + .as_bytes() + .iter() + .map(|b| PackedByte::new(*b)) + .collect(); + let sec1_pub_key = SEC1EncodedPubKeyBuilder::default() + .set(sec1_encoded_bytes.try_into().unwrap()) + .build(); + let unlock_script = ctx + .build_script( + &env.always_success_out_point, + // NOTE: To be able to make sure we can distinguish between the payout of + // the participants, we will pass their corresponding index as an argument. + // This will have no effect on the execution of the always_success_script, + // because it does not bother checking its arguments, but will allow us to + // assert the correct indices once a channel is concluded. + Bytes::from(vec![entry.index]), + ) + .expect("script"); + let unlock_script_hash = unlock_script.calc_script_hash(); + ParticipantBuilder::default() + // The payment script hash used to lock the funds after a channel close for + // this party. + .payment_script_hash(unlock_script_hash.clone()) + // The minimum capacity required for the payment cell to be valid. + .payment_min_capacity(payment_min_capacity.pack()) + // The unlock script hash used to identify this party. Normally this would be + // the lock args for a secp256k1 script or similar. Since we use the always + // success script, we will use the hash of said script parameterized by the + // party index. + .unlock_script_hash(unlock_script_hash.clone()) + .pub_key(sec1_pub_key) + .build() + }) + .collect() + } + + /// mk_balances creates a Balances object from the funding agreement where the given indices + /// already funded their part. + pub fn mk_balances(&self, indices: Vec) -> Result { + let mut ckbytes = [0u64; 2]; + let sudts = self.register.get_sudtassets(); + let mut sudt_dist: Vec<[u128; 2]> = Vec::new(); + for _ in 0..sudts.len() { + sudt_dist.push([0u128, 0]); + } + for fae in self.entries.iter() { + if indices.iter().find(|&&i| i == fae.index).is_none() { + continue; + } + + ckbytes[fae.index as usize] = fae.ckbytes; + for (asset, amount) in fae.sudts.iter() { + sudt_dist[asset.0 as usize][fae.index as usize] = *amount; + } + } + let mut sudt_alloc: Vec = Vec::new(); + for (i, asset) in sudts.iter().enumerate() { + sudt_alloc.push( + SUDTBalances::new_builder() + .asset(asset.clone()) + .distribution( + SUDTDistribution::new_builder() + .nth0(sudt_dist[i][0].pack()) + .nth1(sudt_dist[i][1].pack()) + .build(), + ) + .build(), + ); + } + + println!("mkbalances ckbytes: {:?}", ckbytes); + + Ok(Balances::new_builder() + .ckbytes( + CKByteDistribution::new_builder() + .nth0(ckbytes[0].pack()) + .nth1(ckbytes[1].pack()) + .build(), + ) + .sudts(SUDTAllocation::new_builder().set(sudt_alloc).build()) + .build()) + } + + pub fn expected_ckbytes_funding_for(&self, index: u8) -> Result { + let entry = self + .entries + .iter() + .find(|entry| entry.index == index) + .ok_or("unknown index")?; + Ok(entry.ckbytes) + } + + pub fn sudt_max_cap_sum(&self) -> u64 { + self.register.get_sudtassets().iter().fold(0u64, |old, asset| { + old + Capacity::shannons(asset.max_capacity().unpack()).as_u64() + }) + } + + pub fn expected_sudts_funding_for( + &self, + index: u8, + ) -> Result, perun::Error> { + let entry = self + .entries + .iter() + .find(|entry| entry.index == index) + .ok_or("unknown index")?; + entry + .sudts + .iter() + .map(|(asset, amount)| { + let sudt_asset = self.register.get_sudtasset(asset).ok_or("unknown asset")?; + let sudt_script = sudt_asset.type_script(); + let sudt_capacity = Capacity::shannons(sudt_asset.max_capacity().unpack()); + Ok((sudt_script, sudt_capacity, *amount)) + }) + .collect::, perun::Error>>() + } +} + +#[derive(Debug, Clone)] +pub struct FundingAgreementEntry { + pub ckbytes: u64, + pub sudts: Vec<(Asset, u128)>, + pub index: u8, + pub pub_key: PublicKey, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct Asset(pub u32); + +impl Asset { + pub fn new() -> Self { + Asset(0) + } +} + +impl Default for Asset { + fn default() -> Self { + Asset(0) + } +} + +#[derive(Debug, Clone)] +pub struct AssetRegister { + assets: Vec<(Asset, SUDTAsset)>, +} + +impl AssetRegister { + fn new() -> Self { + AssetRegister { + assets: Vec::new(), + } + } + + pub fn len(&self) -> usize { + self.assets.len() + } + + pub fn register_asset(&mut self, sudt_asset: SUDTAsset) -> Asset { + let asset = Asset(self.assets.len() as u32); + self.assets.push((asset, sudt_asset)); + return asset; + } + pub fn get_sudtasset(&self, asset: &Asset) -> Option<&SUDTAsset> { + match self.assets.get(asset.0 as usize) { + Some((_, sudt_asset)) => Some(sudt_asset), + None => None, + } + } + + pub fn get_asset(&self, sudt_asset: SUDTAsset) -> Option<&Asset> { + match self.assets.iter().find(|(_, a)| a.as_slice()[..] == sudt_asset.as_slice()[..]) { + Some((asset, _)) => Some(asset), + None => None, + } + } + + pub fn guess_asset_from_script(&self, script: &Script) -> Option<&Asset> { + match self + .assets + .iter() + .find(|(_, sudt_asset)| sudt_asset.type_script().as_slice()[..] == script.as_slice()[..]) + { + Some((asset, _)) => Some(asset), + None => None, + } + } + + pub fn get_sudtassets(&self) -> Vec { + self.assets.iter().map(|(_, a)| a.clone()).collect() + } +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/keys.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/keys.rs new file mode 100644 index 0000000..00c507d --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/keys.rs @@ -0,0 +1,11 @@ +use k256::{ecdsa::VerifyingKey, elliptic_curve::sec1::ToEncodedPoint}; + +pub fn verifying_key_to_byte_array(vk: &VerifyingKey) -> [u8; 33] { + vk.to_encoded_point(true) + .as_bytes() + .iter() + .map(|x| *x) + .collect::>() + .try_into() + .expect("public-key length 33") +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/mod.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/mod.rs new file mode 100644 index 0000000..effc4c1 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/mod.rs @@ -0,0 +1,15 @@ +#[cfg(test)] +mod client; +pub use client::*; + +mod funding_agreement; +pub use funding_agreement::*; + +mod channel_id; +pub use channel_id::*; + +pub mod keys; + +pub mod transaction; + +pub mod cell; diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/abort.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/abort.rs new file mode 100644 index 0000000..c454be0 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/abort.rs @@ -0,0 +1,85 @@ +use ckb_testtool::{ + ckb_types::{ + bytes::Bytes, + core::{TransactionBuilder, TransactionView}, + packed::{CellInput, OutPoint}, + prelude::{Builder, Entity, Pack}, + }, + context::Context, +}; +use perun_common::{perun_types::ChannelStatus, redeemer}; + +use crate::perun::{self, harness, test::{cell::FundingCell, transaction::common::add_cap_to_a}}; + +use super::common::{channel_witness, create_cells}; + +#[derive(Debug, Clone)] +pub struct AbortArgs { + pub channel_cell: OutPoint, + pub funds: Vec, + pub state: ChannelStatus, + pub party_index: u8, +} + +#[derive(Debug, Clone)] +pub struct AbortResult { + pub tx: TransactionView, +} + +impl Default for AbortResult { + fn default() -> Self { + AbortResult { + tx: TransactionBuilder::default().build(), + } + } +} + +pub fn mk_abort( + ctx: &mut Context, + env: &harness::Env, + args: AbortArgs, +) -> Result { + let payment_input = env.create_min_cell_for_index(ctx, args.party_index); + let abort_action = redeemer!(Abort); + let witness_args = channel_witness!(abort_action); + let mut inputs = vec![ + CellInput::new_builder() + .previous_output(args.channel_cell) + .build(), + CellInput::new_builder() + .previous_output(payment_input) + .build(), + ]; + inputs.extend(args.funds.iter().cloned().map(|op| { + CellInput::new_builder() + .previous_output(op.outpoint()) + .build() + })); + + let headers: Vec<_> = ctx.headers.keys().cloned().collect(); + // TODO: We are expecting the output amounts to be greater than the minimum amount necessary to + // accomodate the space required for each output cell. + let f = |idx| env.build_lock_script(ctx, Bytes::from(vec![idx])); + let channel_cap = env.min_capacity_for_channel(args.state.clone())?; + let balances = add_cap_to_a(&args.state.state().balances(), channel_cap); + let outputs = balances.mk_outputs(f, vec![0]); + let outputs_data: Vec<_> = outputs.iter().map(|o| o.1.clone()).collect(); + + let cell_deps = vec![ + env.pcls_script_dep.clone(), + env.pcts_script_dep.clone(), + env.always_success_script_dep.clone(), + ]; + + let rtx = TransactionBuilder::default() + .inputs(inputs) + .outputs(outputs.iter().cloned().map(|o| o.0)) + .outputs_data(outputs_data.pack()) + .cell_deps(cell_deps) + .header_deps(headers) + .witness(witness_args.as_bytes().pack()) + .build(); + let tx = ctx.complete_tx(rtx); + create_cells(ctx, tx.hash(), outputs); + Ok(AbortResult { tx }) +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/close.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/close.rs new file mode 100644 index 0000000..e40f6f7 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/close.rs @@ -0,0 +1,96 @@ +use ckb_testtool::{ + ckb_types::packed::{CellInput, OutPoint}, + ckb_types::{ + bytes::Bytes, + core::{TransactionBuilder, TransactionView}, + prelude::{Builder, Entity, Pack}, + }, + context::Context, +}; +use perun_common::{close, perun_types::ChannelStatus, redeemer}; + +use crate::perun::{ + self, harness, + test::{cell::FundingCell, transaction::common::channel_witness}, +}; + +use super::common::{create_cells, add_cap_to_a}; + +#[derive(Debug, Clone)] +pub struct CloseArgs { + /// The channel cell which tracks the channel on-chain. + pub channel_cell: OutPoint, + /// All funding cells used to initially fund the channel. + pub funds_cells: Vec, + /// The channel state which shall be used for closing. + pub state: ChannelStatus, + /// The DER encoded signatures for the channel state in proper order of parties. + pub sigs: [Vec; 2], + pub party_index: u8, +} + +#[derive(Debug, Clone)] +pub struct CloseResult { + pub tx: TransactionView, +} + +impl Default for CloseResult { + fn default() -> Self { + CloseResult { + tx: TransactionBuilder::default().build(), + } + } +} + +pub fn mk_close( + ctx: &mut Context, + env: &harness::Env, + args: CloseArgs, +) -> Result { + let payment_input = env.create_min_cell_for_index(ctx, args.party_index); + let mut inputs = vec![ + CellInput::new_builder() + .previous_output(args.channel_cell) + .build(), + CellInput::new_builder() + .previous_output(payment_input) + .build(), + ]; + inputs.extend(args.funds_cells.iter().cloned().map(|f| { + CellInput::new_builder() + .previous_output(f.outpoint()) + .build() + })); + + let cell_deps = vec![ + env.pcls_script_dep.clone(), + env.pcts_script_dep.clone(), + env.pfls_script_dep.clone(), + env.always_success_script_dep.clone(), + ]; + let channel_cap = env.min_capacity_for_channel(args.state.clone())?; + let balances = add_cap_to_a(&args.state.state().balances(), channel_cap); + let f = |idx| env.build_lock_script(ctx, Bytes::from(vec![idx])); + let outputs = balances.mk_outputs(f, vec![0, 1]); + let outputs_data: Vec<_> = outputs.iter().map(|o| o.1.clone()).collect(); + + let close_action = redeemer!(close!( + args.state.state(), + args.sigs[0].pack(), + args.sigs[1].pack() + )); + let witness_args = channel_witness!(close_action); + + let headers: Vec<_> = ctx.headers.keys().cloned().collect(); + let rtx = TransactionBuilder::default() + .inputs(inputs) + .outputs(outputs.iter().map(|o| o.0.clone())) + .outputs_data(outputs_data.pack()) + .witness(witness_args.as_bytes().pack()) + .cell_deps(cell_deps) + .header_deps(headers) + .build(); + let tx = ctx.complete_tx(rtx); + create_cells(ctx, tx.hash(), outputs); + Ok(CloseResult { tx }) +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/common.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/common.rs new file mode 100644 index 0000000..3814aad --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/common.rs @@ -0,0 +1,41 @@ +use ckb_occupied_capacity::Capacity; +use ckb_testtool::{ + bytes, + ckb_types::{packed::{Byte32, CellOutput, OutPoint}, prelude::{Unpack, Pack}}, + context::Context, +}; +use molecule::prelude::{Entity, Builder}; +use perun_common::perun_types::Balances; + +use crate::perun; + +/// Build witness args containing the given action. +macro_rules! channel_witness { + ($action:expr) => { + ckb_testtool::ckb_types::packed::WitnessArgsBuilder::default() + .input_type(Some($action.as_bytes()).pack()) + .build() + }; +} +pub(crate) use channel_witness; + +pub fn create_funding_from( + available_capacity: Capacity, + wanted_capacity: Capacity, +) -> Result { + Ok(available_capacity.safe_sub(wanted_capacity)?) +} + +pub fn create_cells(ctx: &mut Context, hash: Byte32, outputs: Vec<(CellOutput, bytes::Bytes)>) { + for (i, (output, data)) in outputs.into_iter().enumerate() { + let out_point = OutPoint::new(hash.clone(), i as u32); + ctx.create_cell_with_out_point(out_point, output, data); + } +} + +pub fn add_cap_to_a(balances: &Balances, cap: Capacity) -> Balances { + let bal_a: u64 = balances.ckbytes().nth0().unpack(); + balances.clone().as_builder().ckbytes( + balances.ckbytes().as_builder().nth0( + (cap.as_u64() + bal_a).pack()).build()).build() +} \ No newline at end of file diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/dispute.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/dispute.rs new file mode 100644 index 0000000..aa8a5e4 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/dispute.rs @@ -0,0 +1,94 @@ +use ckb_testtool::{ + ckb_types::packed::{CellInput, CellOutput, OutPoint}, + ckb_types::{ + core::{TransactionBuilder, TransactionView}, + packed::Script, + prelude::{Builder, Entity, Pack}, + }, + context::Context, +}; +use perun_common::{dispute, perun_types::ChannelStatus, redeemer}; + +use crate::perun::{self, harness, test::transaction::common::channel_witness}; + +use super::common::create_cells; + +#[derive(Debug, Clone)] +pub struct DisputeArgs { + /// The channel cell which tracks the channel on-chain. + pub channel_cell: OutPoint, + /// The channel state which shall be used for closing. + pub state: ChannelStatus, + /// The DER encoded signatures for the channel state in proper order of parties. + pub sigs: [Vec; 2], + /// The Perun channel type script used for the current channel. + pub pcts_script: Script, + pub party_index: u8, +} + +#[derive(Debug, Clone)] +pub struct DisputeResult { + pub tx: TransactionView, + pub channel_cell: OutPoint, +} + +impl Default for DisputeResult { + fn default() -> Self { + DisputeResult { + tx: TransactionBuilder::default().build(), + channel_cell: OutPoint::default(), + } + } +} + +pub fn mk_dispute( + ctx: &mut Context, + env: &harness::Env, + args: DisputeArgs, +) -> Result { + let payment_input = env.create_min_cell_for_index(ctx, args.party_index); + let inputs = vec![ + CellInput::new_builder() + .previous_output(args.channel_cell) + .build(), + CellInput::new_builder() + .previous_output(payment_input) + .build(), + ]; + + let cell_deps = vec![ + env.pcls_script_dep.clone(), + env.pcts_script_dep.clone(), + env.pfls_script_dep.clone(), + env.always_success_script_dep.clone(), + ]; + + let pcls_script = env.build_pcls(ctx, Default::default()); + let capacity_for_cs = env.min_capacity_for_channel(args.state.clone())?; + let channel_cell = CellOutput::new_builder() + .capacity(capacity_for_cs.pack()) + .lock(pcls_script.clone()) + .type_(Some(args.pcts_script.clone()).pack()) + .build(); + let outputs = vec![(channel_cell.clone(), args.state.as_bytes())]; + let outputs_data: Vec<_> = outputs.iter().map(|e| e.1.clone()).collect(); + + let dispute_action = redeemer!(dispute!(args.sigs[0].pack(), args.sigs[1].pack())); + let witness_args = channel_witness!(dispute_action); + + let headers: Vec<_> = ctx.headers.keys().cloned().collect(); + let rtx = TransactionBuilder::default() + .inputs(inputs) + .outputs(outputs.iter().map(|e| e.0.clone())) + .outputs_data(outputs_data.pack()) + .header_deps(headers) + .witness(witness_args.as_bytes().pack()) + .cell_deps(cell_deps) + .build(); + let tx = ctx.complete_tx(rtx); + create_cells(ctx, tx.hash(), outputs); + Ok(DisputeResult { + channel_cell: OutPoint::new(tx.hash(), 0), + tx, + }) +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/force_close.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/force_close.rs new file mode 100644 index 0000000..a767ab5 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/force_close.rs @@ -0,0 +1,94 @@ +use ckb_testtool::{ + ckb_types::packed::{CellInput, OutPoint}, + ckb_types::{ + bytes::Bytes, + core::{TransactionBuilder, TransactionView}, + packed::Byte32, + prelude::{Builder, Entity, Pack}, + }, + context::Context, +}; +use perun_common::{perun_types::ChannelStatus, redeemer}; + +use crate::perun::{ + self, harness, + test::{cell::FundingCell, transaction::common::channel_witness}, +}; + +use super::common::{create_cells, add_cap_to_a}; + +#[derive(Debug, Clone)] +pub struct ForceCloseArgs { + /// The channel cell which tracks the channel on-chain. + pub channel_cell: OutPoint, + /// The latest headers for the chain containing some timestamps. + pub headers: Vec, + /// All funding cells used to initially fund the channel. + pub funds_cells: Vec, + /// The channel state which shall be used for closing. + pub state: ChannelStatus, + pub party_index: u8, +} + +#[derive(Debug, Clone)] +pub struct ForceCloseResult { + pub tx: TransactionView, +} + +impl Default for ForceCloseResult { + fn default() -> Self { + ForceCloseResult { + tx: TransactionBuilder::default().build(), + } + } +} + +pub fn mk_force_close( + ctx: &mut Context, + env: &harness::Env, + args: ForceCloseArgs, +) -> Result { + let payment_input = env.create_min_cell_for_index(ctx, args.party_index); + let mut inputs = vec![ + CellInput::new_builder() + .previous_output(args.channel_cell) + .build(), + CellInput::new_builder() + .previous_output(payment_input) + .build(), + ]; + inputs.extend(args.funds_cells.iter().cloned().map(|f| { + CellInput::new_builder() + .previous_output(f.outpoint()) + .build() + })); + + let cell_deps = vec![ + env.pcls_script_dep.clone(), + env.pcts_script_dep.clone(), + env.pfls_script_dep.clone(), + env.always_success_script_dep.clone(), + ]; + + // Rust... + let channel_cap = env.min_capacity_for_channel(args.state.clone())?; + let balances = add_cap_to_a(&args.state.state().balances(), channel_cap); + let f = |idx| env.build_lock_script(ctx, Bytes::from(vec![idx])); + let outputs = balances.mk_outputs(f, vec![0, 1]); + let outputs_data: Vec<_> = outputs.iter().map(|o| o.1.clone()).collect(); + + let force_close_action = redeemer!(ForceClose); + let witness_args = channel_witness!(force_close_action); + + let rtx = TransactionBuilder::default() + .inputs(inputs) + .outputs(outputs.iter().map(|o| o.0.clone())) + .outputs_data(outputs_data.pack()) + .header_deps(args.headers) + .witness(witness_args.as_bytes().pack()) + .cell_deps(cell_deps) + .build(); + let tx = ctx.complete_tx(rtx); + create_cells(ctx, tx.hash(), outputs); + Ok(ForceCloseResult { tx }) +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/fund.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/fund.rs new file mode 100644 index 0000000..15bd968 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/fund.rs @@ -0,0 +1,123 @@ +use ckb_occupied_capacity::{Capacity, IntoCapacity}; +use ckb_testtool::{ + ckb_types::{ + bytes::Bytes, + core::{TransactionBuilder, TransactionView}, + packed::{CellInput, CellOutput, OutPoint, Script}, + prelude::{Builder, Entity, Pack}, + }, + context::Context, +}; +use perun_common::{fund, perun_types::ChannelStatus, redeemer}; + +use crate::perun::{ + self, harness, + test::{cell::{FundingCell, mk_funding_cell}, FundingAgreement}, +}; + +use super::common::{channel_witness, create_cells, create_funding_from}; + +#[derive(Debug, Clone)] +pub struct FundArgs { + pub channel_cell: OutPoint, + pub funding_agreement: FundingAgreement, + pub party_index: u8, + pub inputs: Vec<(OutPoint, Capacity)>, + pub pcts: Script, + pub state: ChannelStatus, +} + +#[derive(Debug, Clone)] +pub struct FundResult { + pub tx: TransactionView, + pub channel_cell: OutPoint, + pub funds_cells: Vec, + pub state: ChannelStatus, +} + +impl Default for FundResult { + fn default() -> Self { + FundResult { + tx: TransactionBuilder::default().build(), + channel_cell: OutPoint::default(), + funds_cells: vec![], + state: ChannelStatus::default(), + } + } +} + +pub fn mk_fund( + ctx: &mut Context, + env: &harness::Env, + args: FundArgs, +) -> Result { + let fund_action = redeemer!(fund!()); + let witness_args = channel_witness!(fund_action); + let wanted = args + .funding_agreement + .expected_ckbytes_funding_for(args.party_index)?; + let pfls = env.build_pfls(ctx, args.pcts.calc_script_hash().as_bytes()); + // TODO: Make sure enough funds available all cells! + + // Note: we do not really need to shrink the balances to only contain the party's balances, as balances.mk_outputs will do so anyway. + let balances = args.funding_agreement.mk_balances(vec![args.party_index])?; + let pfls = |_| pfls.clone(); + let mut outputs = balances.mk_outputs(pfls, vec![1]); + let num_fund_ouputs = outputs.len(); + + let my_available_funds = Capacity::shannons(args.inputs.iter().map(|(_, c)| c.as_u64()).sum()); + let exchange_cell = create_funding_from(my_available_funds, (wanted + args.funding_agreement.sudt_max_cap_sum()).into_capacity())?; + let mut inputs = vec![ + CellInput::new_builder() + .previous_output(args.channel_cell) + .build(), + ]; + for (outpoint, _) in args.inputs.iter() { + inputs.push(CellInput::new_builder().previous_output(outpoint.clone()).build()); + } + // NOTE: mk_fund currently expects the be called for the last party funding the channel. + // Otherwise the call to `mk_funded` returns a wrong channel state. + let updated_cs = args.state.mk_funded(); + let capacity_for_new_cs = env.min_capacity_for_channel(updated_cs.clone())?; + let pcls = env.build_pcls(ctx, Default::default()); + let new_channel_cell = CellOutput::new_builder() + .capacity(capacity_for_new_cs.pack()) + .lock(pcls.clone()) + .type_(Some(args.pcts.clone()).pack()) + .build(); + outputs.append(&mut vec![ + (new_channel_cell.clone(), updated_cs.as_bytes()), + ( + CellOutput::new_builder() + .capacity(exchange_cell.pack()) + .lock(env.build_lock_script(ctx, Bytes::from(vec![args.party_index]))) + .build(), + Bytes::new(), + ), + ]); + let outputs_data: Vec<_> = outputs.iter().map(|o| o.1.clone()).collect(); + let cell_deps = vec![ + env.always_success_script_dep.clone(), + env.pcts_script_dep.clone(), + env.pcls_script_dep.clone(), + env.sample_udt_script_dep.clone(), // TODO: Make this generic + ]; + let headers: Vec<_> = ctx.headers.keys().cloned().collect(); + let rtx = TransactionBuilder::default() + .inputs(inputs) + .witness(witness_args.as_bytes().pack()) + .outputs(outputs.clone().into_iter().map(|o| o.0.clone())) + .outputs_data(outputs_data.pack()) + .cell_deps(cell_deps) + .header_deps(headers) + .build(); + let tx = ctx.complete_tx(rtx); + create_cells(ctx, tx.hash(), outputs.clone()); + Ok(FundResult { + channel_cell: OutPoint::new(tx.hash(), num_fund_ouputs as u32), + funds_cells: outputs[..num_fund_ouputs].iter().enumerate().map(|(i, (co, bytes))| + mk_funding_cell(args.party_index, OutPoint::new(tx.hash(), i as u32), co, bytes.clone(), args.funding_agreement.register())).collect(), + state: updated_cs, + tx, + }) +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/mod.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/mod.rs new file mode 100644 index 0000000..b1d6673 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/mod.rs @@ -0,0 +1,19 @@ +mod open; +pub use open::*; + +mod fund; +pub use fund::*; + +mod abort; +pub use abort::*; + +mod close; +pub use close::*; + +mod force_close; +pub use force_close::*; + +mod dispute; +pub use dispute::*; + +mod common; diff --git a/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/open.rs b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/open.rs new file mode 100644 index 0000000..808cd8e --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/perun/test/transaction/open.rs @@ -0,0 +1,129 @@ +use std::vec; + +use ckb_occupied_capacity::{Capacity, IntoCapacity}; +use ckb_testtool::{ + ckb_types::{ + bytes::Bytes, + core::{TransactionBuilder, TransactionView}, + packed::{CellInput, CellOutput, OutPoint, Script}, + prelude::{Builder, Entity, Pack}, + }, + context::Context, +}; +use perun_common::perun_types::ChannelStatus; + +use crate::perun::{ + self, harness, + test::{cell::{FundingCell, mk_funding_cell}, ChannelId, FundingAgreement}, +}; + +use super::common::{create_cells, create_funding_from}; + +#[derive(Clone)] +pub struct OpenArgs { + pub cid: ChannelId, + pub funding_agreement: FundingAgreement, + pub channel_token_outpoint: OutPoint, + pub inputs: Vec<(OutPoint, Capacity)>, + pub party_index: u8, + pub pcls_script: Script, + pub pcts_script: Script, + pub pfls_script: Script, +} + +pub struct OpenResult { + pub tx: TransactionView, + pub channel_cell: OutPoint, + pub funds_cells: Vec, + pub pcts: Script, + pub state: ChannelStatus, +} + +impl Default for OpenResult { + fn default() -> Self { + OpenResult { + tx: TransactionBuilder::default().build(), + channel_cell: OutPoint::default(), + funds_cells: Vec::new(), + pcts: Script::default(), + state: ChannelStatus::default(), + } + } +} + +pub fn mk_open( + ctx: &mut Context, + env: &harness::Env, + args: OpenArgs, +) -> Result { + let mut inputs = vec![ + CellInput::new_builder() + .previous_output(args.channel_token_outpoint) + .build(), + ]; + for (outpoint, _) in args.inputs.iter() { + inputs.push( + CellInput::new_builder() + .previous_output(outpoint.clone()) + .build(), + ); + } + let initial_cs = + env.build_initial_channel_state(args.cid, args.party_index, &args.funding_agreement)?; + let capacity_for_cs = env.min_capacity_for_channel(initial_cs.clone())?; + let channel_cell = CellOutput::new_builder() + .capacity(capacity_for_cs.pack()) + .lock(args.pcls_script.clone()) + .type_(Some(args.pcts_script.clone()).pack()) + .build(); + let wanted = args + .funding_agreement + .expected_ckbytes_funding_for(args.party_index)?; + + let pfls = |_| args.pfls_script.clone(); + + let balances = args.funding_agreement.mk_balances(vec![args.party_index])?; + let mut outputs = balances.mk_outputs(pfls, vec![0]); + let num_of_funds = outputs.len(); + // TODO: Make sure enough funds available all cells! + let my_available_funds = Capacity::shannons(args.inputs.iter().map(|(_, c)| c.as_u64()).sum()); + let exchange_cell_cap = create_funding_from(my_available_funds, (wanted + args.funding_agreement.sudt_max_cap_sum()).into_capacity())?; + // NOTE: The ORDER here is important. We need to reference the outpoints later on by using the + // correct index in the output array of the transaction we build. + outputs.append( + vec![ + (channel_cell.clone(), initial_cs.as_bytes()), + ( + CellOutput::new_builder() + .capacity(exchange_cell_cap.pack()) + .lock(env.build_lock_script(ctx, Bytes::from(vec![args.party_index]))) + .build(), + Bytes::new(), + ), + ].as_mut() + ); + + let outputs_data: Vec<_> = outputs.iter().map(|o| o.1.clone()).collect(); + let cell_deps = vec![ + env.always_success_script_dep.clone(), + env.pcts_script_dep.clone(), + env.sample_udt_script_dep.clone(), // TODO: Make this generic! + ]; + let rtx = TransactionBuilder::default() + .inputs(inputs) + .outputs(outputs.iter().map(|o| o.0.clone())) + .outputs_data(outputs_data.pack()) + .cell_deps(cell_deps) + .build(); + let tx = ctx.complete_tx(rtx); + create_cells(ctx, tx.hash(), outputs.clone()); + Ok(OpenResult { + // See NOTE above for magic indices. + channel_cell: OutPoint::new(tx.hash(), num_of_funds as u32), + funds_cells: outputs[..num_of_funds].iter().enumerate().map(|(i, (co, bytes))| + mk_funding_cell(args.party_index, OutPoint::new(tx.hash(), i as u32), co, bytes.clone(), args.funding_agreement.register())).collect(), + tx, + pcts: args.pcts_script, + state: initial_cs, + }) +} diff --git a/payment-channel-ckb/devnet/contracts/tests/src/tests.rs b/payment-channel-ckb/devnet/contracts/tests/src/tests.rs new file mode 100644 index 0000000..f21be32 --- /dev/null +++ b/payment-channel-ckb/devnet/contracts/tests/src/tests.rs @@ -0,0 +1,486 @@ +use crate::perun::mutators::*; +use crate::perun::random; + +use super::*; +use ckb_occupied_capacity::Capacity; +use ckb_testtool::ckb_types::{bytes::Bytes, packed::*, prelude::*}; +use ckb_testtool::context::Context; +use perun; +use perun::test; +use perun_common::helpers::blake2b256; +use perun_common::perun_types::{Balances, Bool, ChannelState, SEC1EncodedPubKey, CKByteDistribution}; +use perun_common::sig::verify_signature; + +const MAX_CYCLES: u64 = 10 * 10_000_000; +const CHALLENGE_DURATION_MS: u64 = 10 * 1000; + +#[test] +fn test_signature() { + // This tests the interoperability between the on-chain signature verification + // and the key generation & signing in the perun-ckb-backend's wallet. + + // This signature was generated by the wallet in the perun-ckb-backend + let sig_string = "3045022100a4f8768be2e5afdcbcfee600eb963caf1957d32edca49390e6f5a4933c2f6dcd02207fd9d2b5928266e9aeee039285508da1dbdbeec67cb995fd8735e1795bf53e5f"; + let sig = hex::decode(sig_string).expect("decoding signature"); + let sig_bytes: Bytes = sig.into(); + + // This public key was generated by the wallet in the perun-ckb-backend + let pubkey_string = "02d1ab4e7cbfb2262de6f3f816d9b044970162a6a2ae0e6b0ff9b082e315c5e152"; + let pubkey = hex::decode(pubkey_string).expect("decoding pubkey"); + let pubkey_bytes: [Byte; 33] = pubkey + .iter() + .map(|x| (*x).into()) + .collect::>() + .try_into() + .unwrap(); + SEC1EncodedPubKey::new_builder().set(pubkey_bytes).build(); + + let balances_array: [Uint64; 2] = [10u64.pack(), 11u64.pack()]; + let balances = Balances::new_builder().ckbytes(CKByteDistribution::new_builder().set(balances_array).build()).build(); + let channel_state = ChannelState::new_builder() + .channel_id(Byte32::zero()) + .balances(balances) + .is_final(Bool::from_bool(true)) + .version(10u64.pack()) + .build(); + let msg = channel_state.as_slice(); + let msg_hash = blake2b256(msg); + + verify_signature(&msg_hash, &sig_bytes, pubkey.as_slice()).expect("valid signature"); +} + +// TODO: Add mutator to channel state that can be passed to dispute, and close. +#[test] +fn channel_test_bench() -> Result<(), perun::Error> { + let res = [ + test_funding_abort, + test_successful_funding_with_udt, + test_successful_funding_without_udt, + test_early_force_close, + test_close, + test_force_close, + test_multiple_disputes, + test_multiple_disputes_same_version, + test_multi_asset_payment, + test_multi_asset_abort, + test_multi_asset_abort_zero_sudt_balance, + test_multi_asset_force_close, + ] + .iter() + .map(|test| { + let mut context = Context::default(); + let pe = perun::harness::Env::new(&mut context, MAX_CYCLES, CHALLENGE_DURATION_MS) + .expect("preparing environment"); + test(&mut context, &pe) + }) + .collect::>(); + res.into_iter().collect() +} + +fn create_channel_test( + context: &mut Context, + env: &perun::harness::Env, + parts: &[perun::TestAccount], + test: impl Fn(&mut perun::channel::Channel) -> Result<(), perun::Error>, +) -> Result<(), perun::Error> { + let mut chan = perun::channel::Channel::new(context, env, parts); + test(&mut chan) +} + +fn test_funding_abort( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding_timeout = 10; + let funding = [ + Capacity::bytes(1000)?.as_u64(), + Capacity::bytes(1000)?.as_u64(), + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.delay(funding_timeout); + + chan.with(alice).abort().expect("aborting channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_successful_funding_without_udt( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.assert(); + Ok(()) + }) +} + + +fn test_successful_funding_with_udt( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let asset_funding = [ + 20u128, + 30u128, + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities_and_sudt( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + &env.sample_udt_script, + env.sample_udt_max_cap.as_u64(), + parts.iter().cloned().zip(asset_funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_close(context: &mut Context, env: &perun::harness::Env) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.with(alice) + .finalize() + .close() + .expect("closing channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_force_close(context: &mut Context, env: &perun::harness::Env) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.with(bob).dispute().expect("invalid channel dispute"); + + chan.delay(env.challenge_duration); + + chan.with(bob).force_close().expect("force closing channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_early_force_close(context: &mut Context, env: &perun::harness::Env) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.with(bob).dispute().expect("invalid channel dispute"); + + chan.with(bob).invalid().force_close().expect("force closing channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_multiple_disputes_same_version( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.with(alice) + .valid() + .dispute() + .expect("disputing channel"); + + chan.with(bob) + .invalid() + .dispute() + .expect("disputing channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_multiple_disputes( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.with(alice) + .valid() + .dispute() + .expect("disputing channel"); + + chan.with(bob) + .valid() + .update(bump_version()) + .dispute() + .expect("disputing channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_multi_asset_payment( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let asset_funding = [ + 20u128, + 30u128, + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities_and_sudt( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + &env.sample_udt_script, + env.sample_udt_max_cap.as_u64(), + parts.iter().cloned().zip(asset_funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.update(pay_ckbytes(Direction::AtoB, 50)); + chan.update(pay_sudt(Direction::BtoA, 10, 0)); + + chan.with(alice).finalize().close().expect("closing channel"); + + chan.assert(); + Ok(()) + }) +} + +pub fn test_multi_asset_abort( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(0)?.as_u64(), + Capacity::bytes(0)?.as_u64(), + ]; + let asset_funding = [ + 30u128, + 20u128, + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities_and_sudt( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + &env.sample_udt_script, + env.sample_udt_max_cap.as_u64(), + parts.iter().cloned().zip(asset_funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(alice).abort().expect("aborting channel"); + + chan.assert(); + Ok(()) + }) +} + +pub fn test_multi_asset_abort_zero_sudt_balance( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(0)?.as_u64(), + Capacity::bytes(0)?.as_u64(), + ]; + let asset_funding = [ + 0u128, + 0u128, + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities_and_sudt( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + &env.sample_udt_script, + env.sample_udt_max_cap.as_u64(), + parts.iter().cloned().zip(asset_funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(alice).abort().expect("aborting channel"); + + chan.assert(); + Ok(()) + }) +} + +fn test_multi_asset_force_close( + context: &mut Context, + env: &perun::harness::Env, +) -> Result<(), perun::Error> { + let (alice, bob) = ("alice", "bob"); + let parts = [random::account(alice), random::account(bob)]; + let funding = [ + Capacity::bytes(100)?.as_u64(), + Capacity::bytes(100)?.as_u64(), + ]; + let asset_funding = [ + 20u128, + 30u128, + ]; + let funding_agreement = test::FundingAgreement::new_with_capacities_and_sudt( + parts.iter().cloned().zip(funding.iter().cloned()).collect(), + &env.sample_udt_script, + env.sample_udt_max_cap.as_u64(), + parts.iter().cloned().zip(asset_funding.iter().cloned()).collect(), + ); + create_channel_test(context, env, &parts, |chan| { + chan.with(alice) + .open(&funding_agreement) + .expect("opening channel"); + + chan.with(bob) + .fund(&funding_agreement) + .expect("funding channel"); + + chan.update(pay_ckbytes(Direction::AtoB, 50)); + chan.update(pay_sudt(Direction::BtoA, 10, 0)); + + chan.with(bob).dispute().expect("disputing channel"); + + chan.delay(env.challenge_duration); + + chan.with(bob).force_close().expect("force closing channel"); + + chan.assert(); + Ok(()) + }) +} diff --git a/payment-channel-ckb/devnet/deploy_contracts.sh b/payment-channel-ckb/devnet/deploy_contracts.sh new file mode 100755 index 0000000..b93ca2f --- /dev/null +++ b/payment-channel-ckb/devnet/deploy_contracts.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -eu +[ -n "${DEBUG:-}" ] && set -x || true + +ACCOUNTS_DIR="accounts" +PERUN_CONTRACTS_DIR="contracts" +SYSTEM_SCRIPTS_DIR="system_scripts" +DEVNET_DIR="$PWD" + +genesis=$(cat $ACCOUNTS_DIR/genesis-2.txt | awk '/testnet/ { count++; if (count == 2) print $2}') + +cd $PERUN_CONTRACTS_DIR + +if [ -d "migrations/dev" ]; then + rm -rf "migrations/dev" +fi + +expect << EOF +spawn capsule deploy --address $genesis --api "http://127.0.0.1:8114" --fee 1 +expect "Confirm deployment? (Yes/No)" +send "Yes\r" +expect "Password:" +send "\r" +expect eof +EOF + +# Fetch default contracts: +cd $DEVNET_DIR + +if [ -d "$SYSTEM_SCRIPTS_DIR" ]; then + rm -rf "$SYSTEM_SCRIPTS_DIR" +fi + +mkdir -p "$SYSTEM_SCRIPTS_DIR" +## jq will interpret the code_hash and tx_hash as numbers, so we need to wrap them in quotes. +## The index must also be a string value, but yaml does not support hex values as a top level block argument +## so we have to do that in a second pass... +ckb-cli util genesis-scripts --output-format json \ + | sed 's/code_hash: \(.*\)/code_hash: \"\1\"/; s/tx_hash: \(.*\)/tx_hash: \"\1\"/' \ + | sed 's/"index": \([0-9]\+\),/echo "\\"index\\": $(python -c "print(\\\"\\\\\\"{}\\\\\\"\\\".format(hex(\1)))"),";/e' \ + | jq . > "$SYSTEM_SCRIPTS_DIR/default_scripts.json" + +cd $DEVNET_DIR + +SUDT_TX_HASH=$(cat ./contracts/migrations/dev/*.json | jq .cell_recipes[3].tx_hash) +SUDT_TX_INDEX=$(cat ./contracts/migrations/dev/*.json | jq .cell_recipes[3].index) +SUDT_DATA_HASH=$(cat ./contracts/migrations/dev/*.json | jq .cell_recipes[3].data_hash) + +# TODO: This only works as long as the tx index is 0-9. +jq ".items.sudt.script_id.code_hash = $SUDT_DATA_HASH | .items.sudt.cell_dep.out_point.tx_hash = $SUDT_TX_HASH | .items.sudt.cell_dep.out_point.index = \"0x$SUDT_TX_INDEX\"" ./sudt-celldep-template.json > $SYSTEM_SCRIPTS_DIR/sudt-celldep.json diff --git a/payment-channel-ckb/devnet/devnet-session.yaml b/payment-channel-ckb/devnet/devnet-session.yaml new file mode 100644 index 0000000..c266d19 --- /dev/null +++ b/payment-channel-ckb/devnet/devnet-session.yaml @@ -0,0 +1,26 @@ +session_name: devnet +before_script: ./setup-devnet.sh +windows: + - layout: tiled + panes: + - shell_command: + - ckb run + - shell_command: + - sleep 3.0 + - ckb miner + - shell_command: + - sleep 3.0 + - ./print_accounts.sh + - shell_command: + - sleep 6.0 + - expect fund_accounts.expect && ckb-cli + - panes: + - shell_command: + - sleep 10.0 + - ./deploy_contracts.sh + - echo "Waiting 15 seconds before funding SUDTs" + - sleep 15.0 + - ./sudt_helper.sh fund + - echo "Waiting 10 seconds before listing SUDT account balances" + - sleep 10.0 + - ./sudt_helper.sh balances diff --git a/payment-channel-ckb/devnet/fund_accounts.expect b/payment-channel-ckb/devnet/fund_accounts.expect new file mode 100644 index 0000000..2389c17 --- /dev/null +++ b/payment-channel-ckb/devnet/fund_accounts.expect @@ -0,0 +1,7 @@ +#!/usr/bin/expect -f + +spawn ./fund_accounts.sh + +expect "Password:" +send "\r" +expect eof diff --git a/payment-channel-ckb/devnet/fund_accounts.sh b/payment-channel-ckb/devnet/fund_accounts.sh new file mode 100755 index 0000000..e404831 --- /dev/null +++ b/payment-channel-ckb/devnet/fund_accounts.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +genesis=$(cat accounts/genesis-1.txt | awk '/testnet/ && !found {print $2; found=1}') +alice=$(cat accounts/alice.txt | awk '/testnet/ && !found {print $2; found=1}') +bob=$(cat accounts/bob.txt | awk '/testnet/ && !found {print $2; found=1}') + +genesis_tx_hash=$(ckb-cli wallet get-live-cells --address $genesis | awk '/tx_hash/ {print $2}') +genesis_tx_index=$(ckb-cli wallet get-live-cells --address $genesis | awk '/output_index/ && !found {print $2; found=1}') +genesis_tx_amount=$(ckb-cli wallet get-live-cells --address $genesis | awk '/capacity/ {print $3}') +FUNDINGTX="fundingtx.json" +FUNDING_AMOUNT=1000 +CHANGE_AMOUNT=$(python -c "print(\"{:.8f}\".format($genesis_tx_amount - 2.0 * 10.0 * $FUNDING_AMOUNT - 1.0))") + +add_output() { + ckb-cli tx add-output --tx-file $FUNDINGTX --to-sighash-address $1 --capacity $2 +} + +ckb-cli tx init --tx-file $FUNDINGTX + +for ((i=1; i <= 10; i++)); do + add_output $alice $FUNDING_AMOUNT +done + +for ((i=1; i <= 10; i++)); do + add_output $bob $FUNDING_AMOUNT +done + +ckb-cli tx add-output --tx-file $FUNDINGTX --to-sighash-address $genesis --capacity $CHANGE_AMOUNT +ckb-cli tx add-input --tx-file $FUNDINGTX --tx-hash $genesis_tx_hash --index $genesis_tx_index +ckb-cli tx sign-inputs --add-signatures --tx-file $FUNDINGTX --from-account $genesis +ckb-cli tx send --tx-file $FUNDINGTX +ckb-cli tx info --tx-file $FUNDINGTX +rm $FUNDINGTX diff --git a/payment-channel-ckb/devnet/print_accounts.sh b/payment-channel-ckb/devnet/print_accounts.sh new file mode 100755 index 0000000..74919c8 --- /dev/null +++ b/payment-channel-ckb/devnet/print_accounts.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +for entry in ./accounts/*; do + echo $entry + account_id=$(cat $entry | awk '/lock_arg:/ { count++; print $2}') + cat $entry + echo $account_id + echo -e '\n' | ckb-cli account export --lock-arg $account_id --extended-privkey-path ${entry%.*}.pk + echo "------------------" +done + +echo "Extract SUDT owner lock-hash into own file" +cat ./accounts/genesis-2.txt | awk '/lock_hash:/ { print $2 }' > ./accounts/sudt-owner-lock-hash.txt diff --git a/payment-channel-ckb/devnet/setup-devnet.sh b/payment-channel-ckb/devnet/setup-devnet.sh new file mode 100755 index 0000000..7625586 --- /dev/null +++ b/payment-channel-ckb/devnet/setup-devnet.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +set -eu +[ -n "${DEBUG:-}" ] && set -x || true + +# This script sets up the devnet for CKB. +# Part of the setup are a miner, two accounts Alice and Bob, as well as the +# registration of two accounts governing the genesis cells. + +ACCOUNTS_DIR="accounts" +PERUN_CONTRACTS_DIR="contracts" + +if [ -d $ACCOUNTS_DIR ]; then + rm -rf $ACCOUNTS_DIR/* +fi +mkdir -p $ACCOUNTS_DIR + +if [ -d "data" ]; then + rm -rf "data" +fi + +if [ -d "specs" ]; then + rm -rf "specs" +fi + +if [ -f "ckb-miner.toml" ]; then + rm "ckb-miner.toml" +fi + +if [ -f "ckb.toml" ]; then + rm "ckb.toml" +fi + +if [ -f "default.db-options" ]; then + rm "default.db-options" +fi + +# Build all required contracts for Perun. +DEVNET=$(pwd) +cd $PERUN_CONTRACTS_DIR +capsule build --release +# If debug contracts are wanted: +# capsule build +cd $DEVNET + +# Genesis cell #1 +GenCellOnePK="0xd00c06bfd800d27397002dca6fb0993d5ba6399b4238b2f29ee9deb97593d2bc" +GenCellOneLockArg="0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" +GenCellOneAddress="ckt1qyqvsv5240xeh85wvnau2eky8pwrhh4jr8ts8vyj37" +# Genesis cell #2 +GenCellTwoPK="0x63d86723e08f0f813a36ce6aa123bb2289d90680ae1e99d4de8cdb334553f24d" +GenCellTwoLockArg="0x470dcdc5e44064909650113a274b3b36aecb6dc7" +GenCellTwoAddress="ckt1qyqywrwdchjyqeysjegpzw38fvandtktdhrs0zaxl4" + +create_account() { + echo -e '\n\n' | ckb-cli account new > $ACCOUNTS_DIR/$1.txt +} + +# Create accounts for genesis cells. +touch privateKeyGenesisCells.txt +echo $GenCellOnePK > privateKeyGenesisCells.txt +echo -e '\n\n' | ckb-cli account import --privkey-path privateKeyGenesisCells.txt || true +ckb-cli account list | grep -B 5 -A 4 "$GenCellOneAddress" > $ACCOUNTS_DIR/genesis-1.txt +echo $GenCellTwoPK > privateKeyGenesisCells.txt +echo -e '\n\n' | ckb-cli account import --privkey-path privateKeyGenesisCells.txt || true +ckb-cli account list | grep -B 5 -A 4 "$GenCellTwoAddress" > $ACCOUNTS_DIR/genesis-2.txt +rm privateKeyGenesisCells.txt + +echo -e '\n\n' | ckb-cli account new > $ACCOUNTS_DIR/miner.txt +MINER_LOCK_ARG=$(cat $ACCOUNTS_DIR/miner.txt | awk '/lock_arg/ {print $2}') + +create_account "alice" +create_account "bob" + +ckb init --chain dev --ba-arg $MINER_LOCK_ARG --ba-message "0x" --force + +# Make the scripts owned by the miner. +sed -i "s/args =.*$/args = \"$MINER_LOCK_ARG\"/" $PERUN_CONTRACTS_DIR/deployment/dev/deployment.toml +# Use the debug versions of the contracts. +# sed -i "s/release/debug/" $PERUN_CONTRACTS_DIR/deployment/dev/deployment.toml + +# Adjust miner config to process blocks faster. +sed -i 's/value = 5000/value = 1000/' ckb-miner.toml + +# Reduce epoch length to 10 blocks. +sed -i 's/genesis_epoch_length = 1000/genesis_epoch_length = 10/' specs/dev.toml +sed -i '/\[params\]/a\ +max_block_bytes = 100_000_000' specs/dev.toml + +# Enable the indexer. +sed -i '/"Debug"]/ s/"Debug"]/"Debug", "Indexer"]/' ckb.toml +sed -i '/filter = "info"/ s/filter = "info"/filter = "debug"/' ckb.toml +sed -i 's/max_tx_verify_cycles = 70_000_000/max_tx_verify_cycles = 100_000_000/' ckb.toml +# Increase max_request_body_size to allow for debug contracts (large in size) +# to be deployed. +sed -i 's/max_request_body_size =.*$/max_request_body_size = 104857600/' ckb.toml diff --git a/payment-channel-ckb/devnet/sudt-celldep-template.json b/payment-channel-ckb/devnet/sudt-celldep-template.json new file mode 100644 index 0000000..610cf14 --- /dev/null +++ b/payment-channel-ckb/devnet/sudt-celldep-template.json @@ -0,0 +1,17 @@ +{ + "items": { + "sudt": { + "script_id": { + "hash_type": "data1", + "code_hash": "0x" + }, + "cell_dep": { + "out_point": { + "tx_hash": "0x", + "index": "0x0" + }, + "dep_type": "code" + } + } + } +} diff --git a/payment-channel-ckb/devnet/sudt_helper.sh b/payment-channel-ckb/devnet/sudt_helper.sh new file mode 100755 index 0000000..9bffe39 --- /dev/null +++ b/payment-channel-ckb/devnet/sudt_helper.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +ACCOUNTS_DIR="accounts" +SYSTEM_SCRIPTS_DIR="system_scripts" + +# If any of the listed files is missing, exit with an error. +check_files() { + for file in "$@"; do + if [ ! -f "$file" ]; then + echo "File $file not found. Please run $PWD/print_accounts.sh first and" + echo "make sure $PWD/deploy_contracts.sh has been run successfully." + exit 1 + fi + done +} + +check_files "$ACCOUNTS_DIR/alice.txt" "$ACCOUNTS_DIR/bob.txt" "$ACCOUNTS_DIR/genesis-2.txt" "$SYSTEM_SCRIPTS_DIR/sudt-celldep.json" + +ALICE=$(cat $ACCOUNTS_DIR/alice.txt | awk '/testnet/ { count++; if (count == 1) print $2}') +BOB=$(cat $ACCOUNTS_DIR/bob.txt | awk '/testnet/ { count++; if (count == 1) print $2}') +genesis=$(cat $ACCOUNTS_DIR/genesis-2.txt | awk '/testnet/ { count++; if (count == 2) print $2}') +GENESIS=$(cat $ACCOUNTS_DIR/genesis-2.txt | awk '/testnet/ { count++; if (count == 1) print $2}') + +fund_accounts() { + echo "Funding accounts for Alice and Bob with SUDT tokens" + SUDT_AMOUNT=100000000 + + expect << EOF + spawn ckb-cli sudt issue --owner $GENESIS --udt-to $ALICE:$SUDT_AMOUNT $BOB:$SUDT_AMOUNT --cell-deps $SYSTEM_SCRIPTS_DIR/sudt-celldep.json + expect "owner Password:" + send "\r" + expect eof +EOF +} + +list_accounts_balances() { + echo "Listing SUDT account balances for Alice and Bob" + echo "ALICE: ========================================" + ckb-cli sudt get-amount --owner $GENESIS --cell-deps $SYSTEM_SCRIPTS_DIR/sudt-celldep.json --address $ALICE + echo "BOB: ========================================" + ckb-cli sudt get-amount --owner $GENESIS --cell-deps $SYSTEM_SCRIPTS_DIR/sudt-celldep.json --address $BOB + echo "=============================================" +} + +if [ $# -eq 0 ]; then + echo "No arguments provided. Please provide one of the following:" + echo " balances: list SUDT account balances for Alice and Bob" + echo " fund: fund Alice and Bob with SUDT tokens" + exit 1 +fi + +for arg in "$@"; do + case $arg in + balances) + list_accounts_balances + ;; + fund) + fund_accounts + ;; + *) + echo "Unknown argument: $arg" + echo "Usage: $0 [balances|fund]" + exit 1 + ;; + esac +done diff --git a/payment-channel-ckb/go.mod b/payment-channel-ckb/go.mod new file mode 100644 index 0000000..b0077ba --- /dev/null +++ b/payment-channel-ckb/go.mod @@ -0,0 +1,45 @@ +module perun.network/perun-ckb-demo + +go 1.17 + +require ( + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 + github.com/nervosnetwork/ckb-sdk-go/v2 v2.2.0 + github.com/stretchr/testify v1.8.4 + perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e + perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166 + polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37 +) + +require ( + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Pilatuz/bigz v1.2.1 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/ethereum/go-ethereum v1.13.10 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/stretchr/objx v0.5.1 // indirect + github.com/tklauser/go-sysconf v0.3.13 // indirect + github.com/tklauser/numcpus v0.7.0 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/tools v0.17.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/nervosnetwork/ckb-sdk-go/v2 v2.2.0 => github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80 diff --git a/payment-channel-ckb/go.sum b/payment-channel-ckb/go.sum new file mode 100644 index 0000000..976b7c6 --- /dev/null +++ b/payment-channel-ckb/go.sum @@ -0,0 +1,1322 @@ +cloud.google.com/go v0.0.0-20170206221025-ce650573d812/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0/go.mod h1:ceIuwmxDWptoW3eCqSXlnPsZFKh4X+R38dWPv7GS9Vs= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0/go.mod h1:s1tW/At+xHqjNFvWU4G0c0Qv33KOhvbGNj0RCTQDV8s= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= +github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= +github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Pilatuz/bigz v1.2.1 h1:S/R9NGdunq2lIz7KvHu6DmX8bdh41uMqijWeJDz0U5Y= +github.com/Pilatuz/bigz v1.2.1/go.mod h1:FZmplFUEZe3pUr647EQMQgYhV+n9h8+HGTsYK4X6xws= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= +github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes= +github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20210923152817-c3b6e2f0c527/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= +github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/config v1.18.45/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2/go.mod h1:TQZBt/WaQy+zTHoW++rnl8JBrmZ0VO6EUbVua1+foCA= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= +github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= +github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= +github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI= +github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +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/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cloudflare/cloudflare-go v0.79.0/go.mod h1:gkHQf9xEubaQPEuerBuoinR9P8bf8a05Lq0X6WKy1Oc= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= +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= +github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= +github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +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/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.9.14/go.mod h1:oP8FC5+TbICUyftkTWs+8JryntjIJLJvWvApK3z2AYw= +github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= +github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= +github.com/ethereum/go-ethereum v1.13.10/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +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/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= +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= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc= +github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= +github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= +github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A= +github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/safehtml v0.0.2/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +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.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +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= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +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= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= +github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80 h1:45S239s+5oGVJHakd+BjfZmstG7wHnA8Tkeq43R9eFA= +github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80/go.mod h1:nPpBML8fuaM1NgkKCwv2gSHiCv+xKH43fu8LA9LOQUg= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +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.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= +github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +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/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= +github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= +github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +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/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= +github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= +github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= +github.com/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +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-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +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.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/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-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +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= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/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= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/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-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/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-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/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-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/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/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +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-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= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +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.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/xerrors v0.0.0-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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.0/go.mod h1:JWIHJ7U20drSQb/aDpTetJzfC1KlAPldJLpkSy88dvQ= +google.golang.org/api v0.0.0-20170206182103-3d017632ea10/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +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= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +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/grpc v0.0.0-20170208002647-2a6bf6142e96/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +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/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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +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= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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 v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +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= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e h1:4SOKO0WZtcsQUwP5nKVUrLUohgUPIhMa8wto5iNCA/k= +perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e/go.mod h1:BGBZC3npkX457u87pjDd0NEIXr1a4dsH4H/YpLdGGe8= +perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166 h1:Y/3rPrDpspxiMDkh43sV7lkmbSDTM+m37e66kDEidR0= +perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166/go.mod h1:Ebp1GCFpmlSlxuP+fSO9yk/qAllF+6GhRCe7b2533zs= +polycry.pt/poly-go v0.0.0-20220222131629-aa4bdbaab60b/go.mod h1:XUBrNtqgEhN3EEOP/5gh7IBd3xVHKidCjXDZfl9+kMU= +polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37 h1:iA5GzEa/hHfVlQpimEjPV09NATwHXxSjWNB0VVodtew= +polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37/go.mod h1:XUBrNtqgEhN3EEOP/5gh7IBd3xVHKidCjXDZfl9+kMU= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/payment-channel-ckb/main.go b/payment-channel-ckb/main.go new file mode 100644 index 0000000..447e61d --- /dev/null +++ b/payment-channel-ckb/main.go @@ -0,0 +1,258 @@ +package main + +import ( + "errors" + "fmt" + "io/ioutil" + "log" + "os" + + "github.com/nervosnetwork/ckb-sdk-go/v2/types" + "perun.network/go-perun/channel" + "perun.network/go-perun/channel/persistence/keyvalue" + "perun.network/go-perun/wire" + "perun.network/perun-ckb-backend/channel/asset" + "perun.network/perun-ckb-backend/wallet" + "perun.network/perun-ckb-demo/client" + "perun.network/perun-ckb-demo/deployment" + "polycry.pt/poly-go/sortedkv/memorydb" +) + +const ( + rpcNodeURL = "http://localhost:8114" + Network = types.NetworkTest +) + +func SetLogFile(path string) { + logFile, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + log.SetOutput(logFile) +} + +func main() { + SetLogFile("demo.log") + sudtOwnerLockArg, err := parseSUDTOwnerLockArg("./devnet/accounts/sudt-owner-lock-hash.txt") + if err != nil { + log.Fatalf("error getting SUDT owner lock arg: %v", err) + } + d, _, err := deployment.GetDeployment("./devnet/contracts/migrations/dev/", "./devnet/system_scripts", sudtOwnerLockArg) + if err != nil { + log.Fatalf("error getting deployment: %v", err) + } + /* + maxSudtCapacity := transaction.CalculateCellCapacity(types.CellOutput{ + Capacity: 0, + Lock: &d.DefaultLockScript, + Type: sudtInfo.Script, + }) + */ + w := wallet.NewEphemeralWallet() + + keyAlice, err := deployment.GetKey("./devnet/accounts/alice.pk") + if err != nil { + log.Fatalf("error getting alice's private key: %v", err) + } + keyBob, err := deployment.GetKey("./devnet/accounts/bob.pk") + if err != nil { + log.Fatalf("error getting bob's private key: %v", err) + } + aliceAccount := wallet.NewAccountFromPrivateKey(keyAlice) + bobAccount := wallet.NewAccountFromPrivateKey(keyBob) + + err = w.AddAccount(aliceAccount) + if err != nil { + log.Fatalf("error adding alice's account: %v", err) + } + err = w.AddAccount(bobAccount) + if err != nil { + log.Fatalf("error adding bob's account: %v", err) + } + + // Setup clients. + log.Println("Setting up clients.") + bus := wire.NewLocalBus() // Message bus used for off-chain communication. + prAlice := keyvalue.NewPersistRestorer(memorydb.NewDatabase()) + prBob := keyvalue.NewPersistRestorer(memorydb.NewDatabase()) + alice, err := client.NewPaymentClient( + "Alice", + Network, + d, + bus, + rpcNodeURL, + aliceAccount, + *keyAlice, + w, + prAlice, + ) + if err != nil { + log.Fatalf("error creating alice's client: %v", err) + } + bob, err := client.NewPaymentClient( + "Bob", + Network, + d, + bus, + rpcNodeURL, + bobAccount, + *keyBob, + w, + prBob, + ) + if err != nil { + log.Fatalf("error creating bob's client: %v", err) + } + + //print balances before transaction + + fmt.Println("Balances of Alice and Bob before transaction") + str := "'s account balance" + fmt.Println(alice.Name, str, alice.GetBalances()) + fmt.Println(bob.Name, str, bob.GetBalances()) + + ckbAsset := asset.Asset{ + IsCKBytes: true, + SUDT: nil, + } + + /* + sudtAsset := asset.Asset{ + IsCKBytes: false, + SUDT: &asset.SUDT{ + TypeScript: *sudtInfo.Script, + MaxCapacity: maxSudtCapacity, + }, + } + */ + + fmt.Println("Opening channel and depositing funds") + chAlice := alice.OpenChannel(bob.WireAddress(), map[channel.Asset]float64{ + &asset.Asset{ + IsCKBytes: true, + SUDT: nil, + }: 100.0, + }) + strAlice := "Alice" + strBob := "Bob" + fmt.Println(alice.Name, str, alice.GetBalances()) + fmt.Println(bob.Name, str, bob.GetBalances()) + + fmt.Println("Alice sent proposal") + chBob := bob.AcceptedChannel() + fmt.Println("Bob accepted proposal") + fmt.Println("Sending payments....") + + chAlice.SendPayment(map[channel.Asset]float64{ + &ckbAsset: 10.0, + }) + fmt.Println("Alice sent Bob a payment") + printAllocationBalances(chAlice, ckbAsset, strAlice) + printAllocationBalances(chBob, ckbAsset, strBob) + + chBob.SendPayment(map[channel.Asset]float64{ + &ckbAsset: 10.0, + }) + fmt.Println("Bob sent Alice a payment") + printAllocationBalances(chAlice, ckbAsset, strAlice) + printAllocationBalances(chBob, ckbAsset, strBob) + + chAlice.SendPayment(map[channel.Asset]float64{ + &ckbAsset: 10.0, + }) + fmt.Println("Alice sent Bob a payment") + printAllocationBalances(chAlice, ckbAsset, strAlice) + printAllocationBalances(chBob, ckbAsset, strBob) + + fmt.Println("Payments completed") + printAllocationBalances(chAlice, ckbAsset, strAlice) + printAllocationBalances(chBob, ckbAsset, strBob) + + fmt.Println("Skip Settling Channel and force client shutdown") + //chAlice.Settle() + + fmt.Println(alice.Name, str, alice.GetBalances()) + fmt.Println(bob.Name, str, bob.GetBalances()) + + //cleanup + alice.Shutdown() + bob.Shutdown() + fmt.Println("Clients shutdown, exiting method") + + fmt.Println("Creating clients again to see if channels can be restored") + alice2, err := client.NewPaymentClient( + "Alice", + Network, + d, + bus, + rpcNodeURL, + aliceAccount, + *keyAlice, + w, + prAlice, + ) + if err != nil { + log.Fatalf("error creating alice's client: %v", err) + } + bob2, err := client.NewPaymentClient( + "Bob", + Network, + d, + bus, + rpcNodeURL, + bobAccount, + *keyBob, + w, + prBob, + ) + if err != nil { + log.Fatalf("error creating bob's client: %v", err) + } + + chansAlice := alice2.Restore() + chansBob := bob2.Restore() + fmt.Println("Alice and Bob's channels successfully restored") + + // Print balances after transactions. + fmt.Println(alice.Name, str, alice.GetBalances()) + fmt.Println(bob.Name, str, bob.GetBalances()) + + fmt.Println("Alice sending payment to Bob") + chansAlice[0].SendPayment(map[channel.Asset]float64{ + &ckbAsset: 10.0, + }) + fmt.Println("Bob sending payment to Alice") + chansBob[0].SendPayment(map[channel.Asset]float64{ + &ckbAsset: 10.0, + }) + + chansAlice[0].Settle() + fmt.Println("Balances after settling channel") + fmt.Println(alice.Name, str, alice.GetBalances()) + fmt.Println(bob.Name, str, bob.GetBalances()) + +} + +func printAllocationBalances(ch *client.PaymentChannel, asset asset.Asset, name string) { + chAlloc := ch.State().Allocation + //_assets := chAlloc.Assets + fmt.Println("Assets held by" + name) + /* + for _, a := range _assets { + fmt.Println(a) + } + */ + fmt.Println(name + "'s allocation in channel: " + chAlloc.Balance(1, &asset).String()) +} + +func parseSUDTOwnerLockArg(pathToSUDTOwnerLockArg string) (string, error) { + b, err := ioutil.ReadFile(pathToSUDTOwnerLockArg) + if err != nil { + return "", fmt.Errorf("reading sudt owner lock arg from file: %w", err) + } + sudtOwnerLockArg := string(b) + if sudtOwnerLockArg == "" { + return "", errors.New("sudt owner lock arg not found in file") + } + return sudtOwnerLockArg, nil +} From 19d47e6be76dc9f4989a505ecfc7cd74a13a047f Mon Sep 17 00:00:00 2001 From: ravi0131 Date: Tue, 14 May 2024 19:14:45 +0200 Subject: [PATCH 2/5] wire discovery added --- payment-channel-ckb/client/client.go | 51 ++-- payment-channel-ckb/go.mod | 75 ++++- payment-channel-ckb/go.sum | 438 ++++++++++++++++++++++++++- payment-channel-ckb/main.go | 49 ++- 4 files changed, 575 insertions(+), 38 deletions(-) diff --git a/payment-channel-ckb/client/client.go b/payment-channel-ckb/client/client.go index 90d62d8..7564e30 100644 --- a/payment-channel-ckb/client/client.go +++ b/payment-channel-ckb/client/client.go @@ -9,6 +9,7 @@ import ( "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/nervosnetwork/ckb-sdk-go/v2/rpc" "github.com/nervosnetwork/ckb-sdk-go/v2/types" + "github.com/perun-network/perun-libp2p-wire/p2p" "perun.network/go-perun/channel" gpchannel "perun.network/go-perun/channel" "perun.network/go-perun/channel/persistence" @@ -16,7 +17,6 @@ import ( gpwallet "perun.network/go-perun/wallet" "perun.network/go-perun/watcher/local" "perun.network/go-perun/wire" - "perun.network/go-perun/wire/net/simple" "perun.network/perun-ckb-backend/backend" "perun.network/perun-ckb-backend/channel/adjudicator" "perun.network/perun-ckb-backend/channel/asset" @@ -36,21 +36,23 @@ type PaymentClient struct { wAddr wire.Address Network types.Network PerunClient *client.Client - - channels chan *PaymentChannel - rpcClient rpc.Client + net *p2p.Net + channels chan *PaymentChannel + rpcClient rpc.Client } func NewPaymentClient( name string, network types.Network, deployment backend.Deployment, - bus wire.Bus, rpcUrl string, account *wallet.Account, key secp256k1.PrivateKey, wallet *wallet.EphemeralWallet, persistRestorer persistence.PersistRestorer, + wAddr wire.Address, + net *p2p.Net, + ) (*PaymentClient, error) { backendRPCClient, err := rpc.Dial(rpcUrl) if err != nil { @@ -68,8 +70,19 @@ func NewPaymentClient( if err != nil { return nil, err } - wAddr := simple.NewAddress(account.Address().String()) - perunClient, err := client.New(wAddr, bus, f, a, wallet, watcher) + /* + wireAcc := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano()))) + net, err := p2p.NewP2PBus(wireAcc) + if err != nil { + panic(errors.Wrap(err, "creating p2p net")) + } + bus := net.Bus + listener := net.Listener + + //wAddr := simple.NewAddress(account.Address().String()) + wAddr := wireAcc.Address() + */ + perunClient, err := client.New(wAddr, net.Bus, f, a, wallet, watcher) if err != nil { return nil, err } @@ -89,6 +102,7 @@ func NewPaymentClient( PerunClient: perunClient, channels: make(chan *PaymentChannel, 1), rpcClient: balanceRPC, + net: net, } //go p.PollBalances() @@ -105,6 +119,11 @@ func (p *PaymentClient) WireAddress() wire.Address { return p.wAddr } +func (p *PaymentClient) PeerID() string { + walletAddr := p.wAddr.(*p2p.Address) + return walletAddr.ID.String() +} + func (p *PaymentClient) GetSudtBalance() *big.Int { p.balanceMutex.Lock() defer p.balanceMutex.Unlock() @@ -126,12 +145,13 @@ func (p *PaymentClient) GetBalances() string { } // OpenChannel opens a new channel with the specified peer and funding. -func (p *PaymentClient) OpenChannel(peer wire.Address, amounts map[gpchannel.Asset]float64) *PaymentChannel { +func (p *PaymentClient) OpenChannel(peer wire.Address, peerID string, amounts map[gpchannel.Asset]float64) *PaymentChannel { // We define the channel participants. The proposer always has index 0. Here // we use the on-chain addresses as off-chain addresses, but we could also // use different ones. log.Println("OpenChannel called") participants := []wire.Address{p.WireAddress(), peer} + p.net.Dialer.Register(peer, peerID) assets := make([]gpchannel.Asset, len(amounts)) i := 0 @@ -214,22 +234,11 @@ func (p *PaymentClient) Shutdown() { p.PerunClient.Close() } -func (c *PaymentClient) Restore() []*PaymentChannel { +func (c *PaymentClient) Restore(peer wire.Address, peerID string) []*PaymentChannel { var restoredChannels []*client.Channel - + //c.net.Dialer.Register(peer, peerID) //TODO: Remove this hack. Find why asset is not found upon restoring c.PerunClient.OnNewChannel(func(ch *client.Channel) { - /* - state := ch.State().Clone() - ckbyte := asset.Asset{ - IsCKBytes: true, - SUDT: nil, - } - //create a new allocation where asset type is defined - alloc := gpchannel.NewAllocation(2, ckbyte) - ckbBalances := state.Allocation.Balances[0] - alloc.SetAssetBalances(ckbyte, ckbBalances) - */ restoredChannels = append(restoredChannels, ch) }) diff --git a/payment-channel-ckb/go.mod b/payment-channel-ckb/go.mod index b0077ba..0907bf1 100644 --- a/payment-channel-ckb/go.mod +++ b/payment-channel-ckb/go.mod @@ -5,7 +5,8 @@ go 1.17 require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/nervosnetwork/ckb-sdk-go/v2 v2.2.0 - github.com/stretchr/testify v1.8.4 + github.com/perun-network/perun-libp2p-wire v0.0.0-20240514121025-635388735967 + github.com/stretchr/testify v1.9.0 perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166 polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37 @@ -14,24 +15,92 @@ require ( require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Pilatuz/bigz v1.2.1 // indirect + github.com/btcsuite/btcd v0.20.1-beta // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/ethereum/go-ethereum v1.13.10 // indirect + github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 // indirect github.com/go-ole/go-ole v1.3.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gopacket v1.1.17 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/holiman/uint256 v1.2.4 // indirect + github.com/huin/goupnp v1.3.0 // indirect + github.com/ipfs/go-cid v0.0.7 // indirect + github.com/ipfs/go-ipfs-util v0.0.2 // indirect + github.com/ipfs/go-log v1.0.4 // indirect + github.com/ipfs/go-log/v2 v2.1.1 // 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 + github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d // indirect + github.com/libp2p/go-addr-util v0.0.2 // indirect + github.com/libp2p/go-buffer-pool v0.0.2 // indirect + github.com/libp2p/go-conn-security-multistream v0.2.0 // indirect + github.com/libp2p/go-eventbus v0.2.1 // indirect + github.com/libp2p/go-flow-metrics v0.0.3 // indirect + github.com/libp2p/go-libp2p v0.13.0 // indirect + github.com/libp2p/go-libp2p-autonat v0.4.0 // indirect + github.com/libp2p/go-libp2p-blankhost v0.2.0 // indirect + github.com/libp2p/go-libp2p-circuit v0.4.0 // indirect + github.com/libp2p/go-libp2p-core v0.8.5 // indirect + github.com/libp2p/go-libp2p-discovery v0.5.0 // indirect + github.com/libp2p/go-libp2p-loggables v0.1.0 // indirect + github.com/libp2p/go-libp2p-mplex v0.4.1 // indirect + github.com/libp2p/go-libp2p-nat v0.0.6 // indirect + github.com/libp2p/go-libp2p-noise v0.1.1 // indirect + github.com/libp2p/go-libp2p-peerstore v0.2.6 // indirect + github.com/libp2p/go-libp2p-pnet v0.2.0 // indirect + github.com/libp2p/go-libp2p-swarm v0.4.0 // indirect + github.com/libp2p/go-libp2p-tls v0.1.3 // indirect + github.com/libp2p/go-libp2p-transport-upgrader v0.4.0 // indirect + github.com/libp2p/go-libp2p-yamux v0.5.1 // indirect + github.com/libp2p/go-mplex v0.3.0 // indirect + github.com/libp2p/go-msgio v0.0.6 // indirect + github.com/libp2p/go-nat v0.0.5 // indirect + github.com/libp2p/go-netroute v0.1.3 // indirect + github.com/libp2p/go-openssl v0.0.7 // indirect + github.com/libp2p/go-reuseport v0.0.2 // indirect + github.com/libp2p/go-reuseport-transport v0.0.4 // indirect + github.com/libp2p/go-sockaddr v0.0.2 // indirect + github.com/libp2p/go-stream-muxer-multistream v0.3.0 // indirect + github.com/libp2p/go-tcp-transport v0.2.1 // indirect + github.com/libp2p/go-ws-transport v0.4.0 // indirect + github.com/libp2p/go-yamux/v2 v2.0.0 // indirect github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/minio/sha256-simd v0.1.1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.0.3 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.3.3 // indirect + github.com/multiformats/go-multiaddr-dns v0.2.0 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multiaddr-net v0.2.0 // indirect + github.com/multiformats/go-multibase v0.0.3 // indirect + github.com/multiformats/go-multihash v0.0.14 // indirect + github.com/multiformats/go-multistream v0.2.0 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/stretchr/objx v0.5.1 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/numcpus v0.7.0 // indirect + github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect + go.opencensus.io v0.22.4 // indirect + go.uber.org/atomic v1.6.0 // indirect + go.uber.org/multierr v1.5.0 // indirect + go.uber.org/zap v1.15.0 // indirect golang.org/x/crypto v0.18.0 // indirect golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect golang.org/x/mod v0.14.0 // indirect diff --git a/payment-channel-ckb/go.sum b/payment-channel-ckb/go.sum index 976b7c6..65a8e8c 100644 --- a/payment-channel-ckb/go.sum +++ b/payment-channel-ckb/go.sum @@ -37,6 +37,7 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= @@ -67,9 +68,11 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= @@ -80,6 +83,7 @@ github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= 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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -93,6 +97,7 @@ github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNu github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes= github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajstarks/svgo v0.0.0-20210923152817-c3b6e2f0c527/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -141,14 +146,26 @@ github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+Wji github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= 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/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -188,6 +205,8 @@ github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -200,9 +219,12 @@ github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXk github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= +github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018 h1:6xT9KW8zLC5IlbaIF5Q7JNieBoACT7iW0YTxQHR0in0= +github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= @@ -217,9 +239,14 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etly github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= @@ -262,10 +289,13 @@ github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6Ytix github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= +github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 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/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= @@ -322,7 +352,9 @@ github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q8 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= @@ -334,8 +366,10 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -345,6 +379,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -389,12 +424,15 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY= +github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -411,6 +449,8 @@ github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -418,6 +458,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -427,6 +468,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= @@ -435,7 +478,9 @@ github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5 github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +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/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= @@ -446,6 +491,7 @@ github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXei github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= @@ -466,19 +512,70 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= +github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= +github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= +github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= +github.com/ipfs/go-log v1.0.4 h1:6nLQdX4W8P9yZZFH7mO+X/PzjN8Laozm/lMJ6esdgzY= +github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= +github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/ipfs/go-log/v2 v2.1.1 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0= +github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -497,6 +594,7 @@ github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= @@ -508,6 +606,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -518,8 +617,11 @@ github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPR github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d h1:68u9r4wEvL3gYg2jvAOgROwZ3H+Y3hIDk4tbbmIjcYQ= +github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= 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.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -535,12 +637,193 @@ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4F github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-addr-util v0.0.2 h1:7cWK5cdA5x72jX0g8iLrQWm5TRJZ6CzGdPEhWj7plWU= +github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= +github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= +github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= +github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= +github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= +github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= +github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= +github.com/libp2p/go-libp2p v0.13.0 h1:tDdrXARSghmusdm0nf1U/4M8aj8Rr0V2IzQOXmbzQ3s= +github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= +github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= +github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= +github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= +github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= +github.com/libp2p/go-libp2p-autonat v0.4.0 h1:3y8XQbpr+ssX8QfZUHekjHCYK64sj6/4hnf/awD4+Ug= +github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= +github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk= +github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= +github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= +github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= +github.com/libp2p/go-libp2p-circuit v0.4.0 h1:eqQ3sEYkGTtybWgr6JLqJY6QLtPWRErvFjFDfAOO1wc= +github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= +github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= +github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= +github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= +github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= +github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= +github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= +github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= +github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= +github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.5 h1:aEgbIcPGsKy6zYcC+5AJivYFedhYa4sW7mIpWpUaLKw= +github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= +github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= +github.com/libp2p/go-libp2p-discovery v0.5.0 h1:Qfl+e5+lfDgwdrXdu4YNCWyEo3fWuP+WgN9mN0iWviQ= +github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= +github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= +github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= +github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= +github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= +github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= +github.com/libp2p/go-libp2p-nat v0.0.6 h1:wMWis3kYynCbHoyKLPBEMu4YRLltbm8Mk08HGSfvTkU= +github.com/libp2p/go-libp2p-nat v0.0.6/go.mod h1:iV59LVhB3IkFvS6S6sauVTSOrNEANnINbI/fkaLimiw= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-noise v0.1.1 h1:vqYQWvnIcHpIoWJKC7Al4D6Hgj0H012TuXRhPwSMGpQ= +github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= +github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= +github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= +github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= +github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= +github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= +github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= +github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= +github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= +github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= +github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= +github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-swarm v0.4.0 h1:hahq/ijRoeH6dgROOM8x7SeaKK5VgjjIr96vdrT+NUA= +github.com/libp2p/go-libp2p-swarm v0.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= +github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= +github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= +github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= +github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= +github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.0 h1:xwj4h3hJdBrxqMOyMUjwscjoVst0AASTsKtZiTChoHI= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX5AmegP+dK3CSnU2lMCKsSq/EY0s= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.2/go.mod h1:lIohaR0pT6mOt0AZ0L2dFze9hds9Req3OfS+B+dv4qw= +github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ48OpsfmQVTErwA= +github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= +github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= +github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= +github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= +github.com/libp2p/go-libp2p-yamux v0.5.1 h1:sX4WQPHMhRxJE5UZTfjEuBvlQWXB5Bo3A2JK9ZJ9EM0= +github.com/libp2p/go-libp2p-yamux v0.5.1/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= +github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU= +github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.6 h1:lQ7Uc0kS1wb1EfRxO2Eir/RJoHkHn7t6o+EiwsYIKJA= +github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= +github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= +github.com/libp2p/go-nat v0.0.5 h1:qxnwkco8RLKqVh1NmjQ+tJ8p8khNLFxuElYG/TwqW4Q= +github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= +github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.3 h1:1ngWRx61us/EpaKkdqkMjKk/ufr/JlIFYQAxV2XX8Ig= +github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= +github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= +github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport v0.0.2 h1:XSG94b1FJfGA01BUrT82imejHQyTxO4jEWqheyCXYvU= +github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= +github.com/libp2p/go-reuseport-transport v0.0.4 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM= +github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= +github.com/libp2p/go-sockaddr v0.0.2 h1:tCuXfpA9rq7llM/v834RKc/Xvovy/AqM9kHvTV/jY/Q= +github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY= +github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= +github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= +github.com/libp2p/go-tcp-transport v0.2.1 h1:ExZiVQV+h+qL16fzCWtd1HSzPsqWottJ8KXwWaVi8Ns= +github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M= +github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= +github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= +github.com/libp2p/go-ws-transport v0.4.0 h1:9tvtQ9xbws6cA5LvqdE6Ne3vcmGB4f1z9SByggk4s0k= +github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= +github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux/v2 v2.0.0 h1:vSGhAy5u6iHBq11ZDcyHH4Blcf9xlBhT4WQDoOE90LU= +github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -552,6 +835,7 @@ github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HN github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= @@ -572,9 +856,19 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= +github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -591,7 +885,64 @@ github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3P github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +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/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= +github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= +github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= +github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= +github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= +github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= +github.com/multiformats/go-multiaddr v0.3.3 h1:vo2OTSAqnENB2rLk79pLtr+uhj+VAzSe3uef5q0lRSs= +github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA= +github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= +github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= +github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= +github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.2.0 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEnKgQNvVfCX5VDJk= +github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= +github.com/multiformats/go-multistream v0.2.0 h1:6AuNmQVKUkRnddw2YiDjt5Elit40SFxMJkVnhmETXtU= +github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= @@ -600,6 +951,7 @@ github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -607,21 +959,33 @@ github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80 h1:45S239s+5oGVJHakd+BjfZmstG7wHnA8Tkeq43R9eFA= github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80/go.mod h1:nPpBML8fuaM1NgkKCwv2gSHiCv+xKH43fu8LA9LOQUg= +github.com/perun-network/perun-libp2p-wire v0.0.0-20240514121025-635388735967 h1:m+63gl1KMpLdseyNEKLnUFrCYipD9Q0Cnf/hmOwAkhs= +github.com/perun-network/perun-libp2p-wire v0.0.0-20240514121025-635388735967/go.mod h1:kA/iWKN+2BvzxuUllMmd1IY6H2oKUZ18U+60hrY19EM= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= @@ -705,8 +1069,14 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -718,6 +1088,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= @@ -726,24 +1097,28 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -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/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -772,8 +1147,16 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -797,26 +1180,47 @@ github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -872,8 +1276,10 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -901,6 +1307,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -913,6 +1320,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -986,12 +1394,16 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -999,6 +1411,7 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1099,6 +1512,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.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= @@ -1110,6 +1524,7 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1129,12 +1544,16 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1171,7 +1590,9 @@ golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps 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-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= @@ -1208,6 +1629,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1250,9 +1672,12 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 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.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 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= @@ -1282,6 +1707,9 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= +gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -1292,6 +1720,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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= @@ -1303,10 +1732,13 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh 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= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +perun.network/go-perun v0.10.6/go.mod h1:BGBZC3npkX457u87pjDd0NEIXr1a4dsH4H/YpLdGGe8= perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e h1:4SOKO0WZtcsQUwP5nKVUrLUohgUPIhMa8wto5iNCA/k= perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e/go.mod h1:BGBZC3npkX457u87pjDd0NEIXr1a4dsH4H/YpLdGGe8= perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166 h1:Y/3rPrDpspxiMDkh43sV7lkmbSDTM+m37e66kDEidR0= diff --git a/payment-channel-ckb/main.go b/payment-channel-ckb/main.go index 447e61d..a5db617 100644 --- a/payment-channel-ckb/main.go +++ b/payment-channel-ckb/main.go @@ -5,12 +5,14 @@ import ( "fmt" "io/ioutil" "log" + "math/rand" "os" + "time" "github.com/nervosnetwork/ckb-sdk-go/v2/types" + "github.com/perun-network/perun-libp2p-wire/p2p" "perun.network/go-perun/channel" "perun.network/go-perun/channel/persistence/keyvalue" - "perun.network/go-perun/wire" "perun.network/perun-ckb-backend/channel/asset" "perun.network/perun-ckb-backend/wallet" "perun.network/perun-ckb-demo/client" @@ -70,35 +72,57 @@ func main() { log.Fatalf("error adding bob's account: %v", err) } + aliceWireAcc := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano()))) + aliceNet, err := p2p.NewP2PBus(aliceWireAcc) + if err != nil { + log.Fatalf("creating p2p net", err) + } + aliceBus := aliceNet.Bus + aliceListener := aliceNet.Listener + go aliceBus.Listen(aliceListener) + // Setup clients. log.Println("Setting up clients.") - bus := wire.NewLocalBus() // Message bus used for off-chain communication. + //bus := wire.NewLocalBus() // Message bus used for off-chain communication. prAlice := keyvalue.NewPersistRestorer(memorydb.NewDatabase()) - prBob := keyvalue.NewPersistRestorer(memorydb.NewDatabase()) + alice, err := client.NewPaymentClient( "Alice", Network, d, - bus, rpcNodeURL, aliceAccount, *keyAlice, w, prAlice, + aliceWireAcc.Address(), + aliceNet, ) if err != nil { log.Fatalf("error creating alice's client: %v", err) } + + prBob := keyvalue.NewPersistRestorer(memorydb.NewDatabase()) + bobWireAcc := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano()))) + bobNet, err := p2p.NewP2PBus(bobWireAcc) + if err != nil { + log.Fatalf("creating p2p net", err) + } + bobBus := bobNet.Bus + bobListener := bobNet.Listener + go bobBus.Listen(bobListener) + bob, err := client.NewPaymentClient( "Bob", Network, d, - bus, rpcNodeURL, bobAccount, *keyBob, w, prBob, + bobWireAcc.Address(), + bobNet, ) if err != nil { log.Fatalf("error creating bob's client: %v", err) @@ -127,7 +151,7 @@ func main() { */ fmt.Println("Opening channel and depositing funds") - chAlice := alice.OpenChannel(bob.WireAddress(), map[channel.Asset]float64{ + chAlice := alice.OpenChannel(bob.WireAddress(), bob.PeerID(), map[channel.Asset]float64{ &asset.Asset{ IsCKBytes: true, SUDT: nil, @@ -184,12 +208,13 @@ func main() { "Alice", Network, d, - bus, rpcNodeURL, aliceAccount, *keyAlice, w, prAlice, + alice.WireAddress(), + aliceNet, ) if err != nil { log.Fatalf("error creating alice's client: %v", err) @@ -198,19 +223,21 @@ func main() { "Bob", Network, d, - bus, rpcNodeURL, bobAccount, *keyBob, w, prBob, + bob.WireAddress(), + bobNet, ) if err != nil { log.Fatalf("error creating bob's client: %v", err) } - - chansAlice := alice2.Restore() - chansBob := bob2.Restore() + fmt.Println("Starting restoring channels") + chansAlice := alice2.Restore(bob2.WireAddress(), bob2.PeerID()) + fmt.Println("Alice's channel restored") + chansBob := bob2.Restore(alice2.WireAddress(), alice2.PeerID()) fmt.Println("Alice and Bob's channels successfully restored") // Print balances after transactions. From a889f411ce89cbd7af5ff9218b3c3d97a3ddbdb0 Mon Sep 17 00:00:00 2001 From: ravi0131 Date: Tue, 9 Jul 2024 14:23:48 +0200 Subject: [PATCH 3/5] feat: add restore function to paymentClient && chore: cleanup - add Restore method to PaymentClient in client.go - update .gitignore and remove unecessary .idea files --- payment-channel-ckb/.gitignore | 1 + payment-channel-ckb/.idea/.gitignore | 8 ---- payment-channel-ckb/.idea/modules.xml | 8 ---- .../.idea/payment-channel-ckb.iml | 9 ----- payment-channel-ckb/.idea/vcs.xml | 6 --- payment-channel/client/client.go | 38 +++++++++++++++---- 6 files changed, 31 insertions(+), 39 deletions(-) delete mode 100644 payment-channel-ckb/.idea/.gitignore delete mode 100644 payment-channel-ckb/.idea/modules.xml delete mode 100644 payment-channel-ckb/.idea/payment-channel-ckb.iml delete mode 100644 payment-channel-ckb/.idea/vcs.xml diff --git a/payment-channel-ckb/.gitignore b/payment-channel-ckb/.gitignore index 146c59d..4f08510 100644 --- a/payment-channel-ckb/.gitignore +++ b/payment-channel-ckb/.gitignore @@ -25,3 +25,4 @@ devnet/ckb-miner.toml devnet/ckb.toml devnet/default.db-options devnet/system_scripts +.vscode diff --git a/payment-channel-ckb/.idea/.gitignore b/payment-channel-ckb/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/payment-channel-ckb/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/payment-channel-ckb/.idea/modules.xml b/payment-channel-ckb/.idea/modules.xml deleted file mode 100644 index 8b4f43e..0000000 --- a/payment-channel-ckb/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/payment-channel-ckb/.idea/payment-channel-ckb.iml b/payment-channel-ckb/.idea/payment-channel-ckb.iml deleted file mode 100644 index 5e764c4..0000000 --- a/payment-channel-ckb/.idea/payment-channel-ckb.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/payment-channel-ckb/.idea/vcs.xml b/payment-channel-ckb/.idea/vcs.xml deleted file mode 100644 index 6c0b863..0000000 --- a/payment-channel-ckb/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/payment-channel/client/client.go b/payment-channel/client/client.go index 7ef0cd8..4b22272 100644 --- a/payment-channel/client/client.go +++ b/payment-channel/client/client.go @@ -17,20 +17,20 @@ package client import ( "context" "fmt" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" "math/big" - ethchannel "perun.network/go-perun/backend/ethereum/channel" ethwallet "perun.network/go-perun/backend/ethereum/wallet" swallet "perun.network/go-perun/backend/ethereum/wallet/simple" + "perun.network/go-perun/channel/persistence" + "perun.network/go-perun/watcher/local" + "perun.network/go-perun/channel" "perun.network/go-perun/client" "perun.network/go-perun/wallet" - "perun.network/go-perun/watcher/local" "perun.network/go-perun/wire" - - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" ) const ( @@ -54,6 +54,7 @@ func SetupPaymentClient( chainID uint64, // chainID is the identifier of the blockchain. adjudicator common.Address, // adjudicator is the address of the adjudicator. asset ethwallet.Address, // asset is the address of the asset holder for our payment channels. + pr persistence.PersistRestorer, ) (*PaymentClient, error) { // Create Ethereum client and contract backend. cb, err := CreateContractBackend(nodeURL, chainID, w) @@ -74,11 +75,11 @@ func SetupPaymentClient( // Setup funder. funder := ethchannel.NewFunder(cb) dep := ethchannel.NewETHDepositor() - ethAcc := accounts.Account{Address: acc} + ethAcc := accounts.Account{Address: acc} // Account to be used for funding transactions funder.RegisterAsset(asset, dep, ethAcc) // Setup adjudicator. - adj := ethchannel.NewAdjudicator(cb, adjudicator, acc, ethAcc) + adj := ethchannel.NewAdjudicator(cb, adjudicator, acc, ethAcc) // acc is the address of the account that will receive the payout // Setup dispute watcher. watcher, err := local.NewWatcher(adj) @@ -89,6 +90,7 @@ func SetupPaymentClient( // Setup Perun client. waddr := ethwallet.AsWalletAddr(acc) perunClient, err := client.New(waddr, bus, funder, adj, w, watcher) + perunClient.EnablePersistence(pr) if err != nil { return nil, errors.WithMessage(err, "creating client") } @@ -162,3 +164,23 @@ func (c *PaymentClient) AcceptedChannel() *PaymentChannel { func (c *PaymentClient) Shutdown() { c.perunClient.Close() } + +func (c *PaymentClient) Restore() []*PaymentChannel { + var restoredChannels []*client.Channel + + c.perunClient.OnNewChannel(func(ch *client.Channel) { + restoredChannels = append(restoredChannels, ch) + }) + + err := c.perunClient.Restore(context.TODO()) + if err != nil { + fmt.Println("Error restoring channels") + } + + paymentChannels := make([]*PaymentChannel, len(restoredChannels)) + for i, ch := range restoredChannels { + paymentChannels[i] = newPaymentChannel(ch, c.currency) + } + + return paymentChannels +} From 6e78a06b3f0e5524354bfcdf192a13eb819e96aa Mon Sep 17 00:00:00 2001 From: ravi0131 Date: Thu, 17 Oct 2024 13:14:29 +0200 Subject: [PATCH 4/5] chore: update .gitignore --- payment-channel-ckb/.gitignore | 2 +- payment-channel-ckb/.vscode/launch.json | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 payment-channel-ckb/.vscode/launch.json diff --git a/payment-channel-ckb/.gitignore b/payment-channel-ckb/.gitignore index 4f08510..336fc31 100644 --- a/payment-channel-ckb/.gitignore +++ b/payment-channel-ckb/.gitignore @@ -25,4 +25,4 @@ devnet/ckb-miner.toml devnet/ckb.toml devnet/default.db-options devnet/system_scripts -.vscode +.vscode/ diff --git a/payment-channel-ckb/.vscode/launch.json b/payment-channel-ckb/.vscode/launch.json deleted file mode 100644 index 2a17be5..0000000 --- a/payment-channel-ckb/.vscode/launch.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - { - "name": "Launch Package", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${fileDirname}" - } - - ] -} \ No newline at end of file From d9c54faafb581e478efe1d2983119a26d7a4a2f2 Mon Sep 17 00:00:00 2001 From: Hendrik Amler Date: Thu, 24 Oct 2024 11:11:30 +0200 Subject: [PATCH 5/5] add: ckb payment example Signed-off-by: Hendrik Amler --- .github/workflows/ci.yml | 35 +++ payment-channel-ckb/client/balances.go | 28 +-- payment-channel-ckb/client/channel.go | 37 ++- payment-channel-ckb/client/client.go | 45 ++-- payment-channel-ckb/client/handle.go | 14 ++ payment-channel-ckb/client/util.go | 14 ++ payment-channel-ckb/deployment/deployment.go | 14 ++ payment-channel-ckb/deployment/keys.go | 17 +- .../deployment/system_scripts.go | 14 ++ .../deployment/system_scripts_test.go | 16 +- .../contracts/deployment/dev/deployment.toml | 2 +- .../devnet/default_scripts.json | 54 +++++ payment-channel-ckb/devnet/fund_accounts.sh | 2 +- payment-channel-ckb/devnet/fundingtx.json | 145 ++++++++++++ payment-channel-ckb/devnet/pubkey.sh | 4 + payment-channel-ckb/go.mod | 6 +- payment-channel-ckb/go.sum | 12 + payment-channel-ckb/main.go | 215 +++++++----------- payment-channel-ckb/package-lock.json | 110 +++++++++ payment-channel-ckb/package.json | 5 + payment-channel-ckb/payment-channel-ckb | Bin 0 -> 11341416 bytes 21 files changed, 585 insertions(+), 204 deletions(-) create mode 100644 payment-channel-ckb/devnet/default_scripts.json create mode 100644 payment-channel-ckb/devnet/fundingtx.json create mode 100644 payment-channel-ckb/devnet/pubkey.sh create mode 100644 payment-channel-ckb/package-lock.json create mode 100644 payment-channel-ckb/package.json create mode 100644 payment-channel-ckb/payment-channel-ckb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d16170..0ad4eae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,41 @@ jobs: go run . docker stop ganache + - name: Payment Channel CKB + working-directory: payment-channel-ckb + run: | + sudo apt-get update + sudo apt-get install -y jq sed gawk tmux tmuxp expect make + curl -LO https://github.com/nervosnetwork/ckb/releases/download/v0.109.0/ckb_v0.109.0_x86_64-unknown-linux-gnu.tar.gz + tar -xzf ckb_v0.109.0_x86_64-unknown-linux-gnu.tar.gz + sudo cp ckb_v0.109.0_x86_64-unknown-linux-gnu/ckb /usr/local/bin/ + curl -LO https://github.com/nervosnetwork/ckb-cli/releases/download/v1.4.0/ckb-cli_v1.4.0_x86_64-unknown-linux-gnu.tar.gz + tar -xzf ckb-cli_v1.4.0_x86_64-unknown-linux-gnu.tar.gz + sudo cp ckb-cli_v1.4.0_x86_64-unknown-linux-gnu/ckb-cli /usr/local/bin/ + curl -LO https://github.com/nervosnetwork/capsule/releases/download/v0.9.2/capsule_v0.9.2_x86_64-linux.tar.gz + tar -xzf capsule_v0.9.2_x86_64-linux.tar.gz + sudo cp capsule_v0.9.2_x86_64-linux/capsule /usr/local/bin/ + cd ./devnet + chmod +x setup-devnet.sh print_accounts.sh deploy_contracts.sh sudt_helper.sh + ./setup-devnet.sh + ckb run > /dev/null 2>&1 & + sleep 3 + ckb miner > /dev/null 2>&1 & + sleep 3 + ./print_accounts.sh + sleep 6 + expect fund_accounts.expect + sleep 10 + ./deploy_contracts.sh + sleep 15 + ./sudt_helper.sh fund + sleep 10 + ./sudt_helper.sh balances + + sleep 30 + cd .. + go run main.go + - name: Payment Channel ETH working-directory: payment-channel env: diff --git a/payment-channel-ckb/client/balances.go b/payment-channel-ckb/client/balances.go index a322278..2e658cc 100644 --- a/payment-channel-ckb/client/balances.go +++ b/payment-channel-ckb/client/balances.go @@ -1,3 +1,17 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package client import ( @@ -29,7 +43,6 @@ func sudtBalanceExtractor(cell *indexer.LiveCell) *big.Int { } func (p *PaymentClient) PollBalances() { - defer log.Println("PollBalances: stopped") pollingInterval := time.Second searchKey := &indexer.SearchKey{ Script: address.AsParticipant(p.Account.Address()).PaymentScript, @@ -38,7 +51,6 @@ func (p *PaymentClient) PollBalances() { Filter: nil, WithData: true, } - log.Println("PollBalances") updateBalance := func() { ctx, _ := context.WithTimeout(context.Background(), pollingInterval) @@ -58,30 +70,20 @@ func (p *PaymentClient) PollBalances() { if ckbBalance.Cmp(p.balance) != 0 || sudtBalance.Cmp(p.sudtBalance) != 0 { // Update ckb balance. p.balance = ckbBalance - //ckbBal := p.balance.Int64() // Update sudt balance. p.sudtBalance = sudtBalance p.balanceMutex.Unlock() - //p.NotifyAllBalance(ckbBal) // TODO: Update demo tui to allow for big.Int balances } else { p.balanceMutex.Unlock() } } updateBalance() - //return "CKbytes: " + p.balance.String() + ", SUDT: " + p.sudtBalance.String() - /* - // Poll the balance every 5 seconds. - for { - updateBalance() - time.Sleep(pollingInterval) - } - */ + } func FormatBalance(ckbBal, sudtBal *big.Int) string { - log.Printf("balances: ckb = %s || sudt = %s", ckbBal.String(), sudtBal.String()) balCKByte, _ := ShannonToCKByte(ckbBal).Float64() return fmt.Sprintf("[green]%s\t[yellow]%s[white]", strconv.FormatFloat(balCKByte, 'f', 2, 64)+" CKByte", diff --git a/payment-channel-ckb/client/channel.go b/payment-channel-ckb/client/channel.go index 05a5b61..6c846d6 100644 --- a/payment-channel-ckb/client/channel.go +++ b/payment-channel-ckb/client/channel.go @@ -1,8 +1,21 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package client import ( "context" - "fmt" "math/big" "perun.network/go-perun/channel" @@ -32,27 +45,11 @@ func (c PaymentChannel) SendPayment(amounts map[channel.Asset]float64) { err := c.ch.Update(context.TODO(), func(state *channel.State) { actor := c.ch.Idx() peer := 1 - actor - //fmt.Println("Send payment handler called") for a, amount := range amounts { - fmt.Println(a) - fmt.Println(amount) + if amount < 0 { continue } - /* - switch a := a.(type) { - case *asset.Asset: - if a.IsCKBytes { - fmt.Println("inside condition isCKBytes") - shannonAmount := CKByteToShannon(big.NewFloat(amount)) - state.Allocation.TransferBalance(actor, peer, a, shannonAmount) - } else { - fmt.Println("inside if conditional !isCKBytes") - intAmount := new(big.Int).SetUint64(uint64(amount)) - state.Allocation.TransferBalance(actor, peer, a, intAmount) - } - } - */ shannonAmount := CKByteToShannon(big.NewFloat(amount)) state.Allocation.TransferBalance(actor, peer, a, shannonAmount) @@ -63,9 +60,7 @@ func (c PaymentChannel) SendPayment(amounts map[channel.Asset]float64) { if err != nil { panic(err) } - if err != nil { - panic(err) // We panic on error to keep the code simple. - } + } // Settle settles the payment channel and withdraws the funds. diff --git a/payment-channel-ckb/client/client.go b/payment-channel-ckb/client/client.go index 7564e30..9d6cdb2 100644 --- a/payment-channel-ckb/client/client.go +++ b/payment-channel-ckb/client/client.go @@ -1,9 +1,22 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package client import ( "context" "fmt" - "log" "math/big" "github.com/decred/dcrd/dcrec/secp256k1/v4" @@ -70,18 +83,7 @@ func NewPaymentClient( if err != nil { return nil, err } - /* - wireAcc := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano()))) - net, err := p2p.NewP2PBus(wireAcc) - if err != nil { - panic(errors.Wrap(err, "creating p2p net")) - } - bus := net.Bus - listener := net.Listener - //wAddr := simple.NewAddress(account.Address().String()) - wAddr := wireAcc.Address() - */ perunClient, err := client.New(wAddr, net.Bus, f, a, wallet, watcher) if err != nil { return nil, err @@ -105,7 +107,6 @@ func NewPaymentClient( net: net, } - //go p.PollBalances() go perunClient.Handle(p, p) return p, nil } @@ -130,14 +131,6 @@ func (p *PaymentClient) GetSudtBalance() *big.Int { return new(big.Int).Set(p.sudtBalance) } -// TODO: Remove as probably not required -/* -func (p *PaymentClient) NotifyAllBalance(ckbBal int64) string { - str := FormatBalance(new(big.Int).SetInt64(ckbBal), p.GetSudtBalance()) - return str -} -*/ - // GetBalances retrieves the current balances of the client. func (p *PaymentClient) GetBalances() string { p.PollBalances() @@ -149,7 +142,6 @@ func (p *PaymentClient) OpenChannel(peer wire.Address, peerID string, amounts ma // We define the channel participants. The proposer always has index 0. Here // we use the on-chain addresses as off-chain addresses, but we could also // use different ones. - log.Println("OpenChannel called") participants := []wire.Address{p.WireAddress(), peer} p.net.Dialer.Register(peer, peerID) @@ -162,7 +154,6 @@ func (p *PaymentClient) OpenChannel(peer wire.Address, peerID string, amounts ma // We create an initial allocation which defines the starting balances. initAlloc := gpchannel.NewAllocation(2, assets...) - log.Println(initAlloc.Assets) for a, amount := range amounts { switch a := a.(type) { case *asset.Asset: @@ -183,7 +174,6 @@ func (p *PaymentClient) OpenChannel(peer wire.Address, peerID string, amounts ma } } - log.Println("Created Allocation") // Prepare the channel proposal by defining the channel parameters. challengeDuration := uint64(10) // On-chain challenge duration in seconds. @@ -197,22 +187,15 @@ func (p *PaymentClient) OpenChannel(peer wire.Address, peerID string, amounts ma panic(err) } - log.Println("Created Proposal") - // Send the proposal. ch, err := p.PerunClient.ProposeChannel(context.TODO(), proposal) if err != nil { panic(err) } - log.Println("Sent Channel") - // Start the on-chain event watcher. It automatically handles disputes. p.startWatching(ch) - log.Println("Started Watching") - - //p.Channel = newPaymentChannel(ch, assets) return newPaymentChannel(ch, assets) } diff --git a/payment-channel-ckb/client/handle.go b/payment-channel-ckb/client/handle.go index b509ac1..4c1e932 100644 --- a/payment-channel-ckb/client/handle.go +++ b/payment-channel-ckb/client/handle.go @@ -1,3 +1,17 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package client import ( diff --git a/payment-channel-ckb/client/util.go b/payment-channel-ckb/client/util.go index e0d8c11..9acd6eb 100644 --- a/payment-channel-ckb/client/util.go +++ b/payment-channel-ckb/client/util.go @@ -1,3 +1,17 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package client import ( diff --git a/payment-channel-ckb/deployment/deployment.go b/payment-channel-ckb/deployment/deployment.go index 376c050..dbc89dc 100644 --- a/payment-channel-ckb/deployment/deployment.go +++ b/payment-channel-ckb/deployment/deployment.go @@ -1,3 +1,17 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package deployment import ( diff --git a/payment-channel-ckb/deployment/keys.go b/payment-channel-ckb/deployment/keys.go index 1d7d6bc..d3756be 100644 --- a/payment-channel-ckb/deployment/keys.go +++ b/payment-channel-ckb/deployment/keys.go @@ -1,12 +1,27 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package deployment import ( "encoding/hex" "fmt" - "github.com/decred/dcrd/dcrec/secp256k1/v4" "io" "os" "strings" + + "github.com/decred/dcrd/dcrec/secp256k1/v4" ) func GetKey(path string) (*secp256k1.PrivateKey, error) { diff --git a/payment-channel-ckb/deployment/system_scripts.go b/payment-channel-ckb/deployment/system_scripts.go index 77ee117..080b41e 100644 --- a/payment-channel-ckb/deployment/system_scripts.go +++ b/payment-channel-ckb/deployment/system_scripts.go @@ -1,3 +1,17 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package deployment import ( diff --git a/payment-channel-ckb/deployment/system_scripts_test.go b/payment-channel-ckb/deployment/system_scripts_test.go index d7246a0..fffd5e4 100644 --- a/payment-channel-ckb/deployment/system_scripts_test.go +++ b/payment-channel-ckb/deployment/system_scripts_test.go @@ -1,3 +1,17 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package deployment_test import ( @@ -5,7 +19,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "perun.network/perun-ckb-demo/deployment" + "perun.network/perun-examples/payment-channel-ckb/deployment" ) func TestSystemScripts(t *testing.T) { diff --git a/payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml b/payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml index 899072d..d09b02b 100644 --- a/payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml +++ b/payment-channel-ckb/devnet/contracts/deployment/dev/deployment.toml @@ -37,5 +37,5 @@ location = { file = "build/release/sample-udt" } # # For example the secp256k1 lock [lock] code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" -args = "0x4a3c88737f8d4d26031ad9a6d6448ba75f1533e2" +args = "0x0e25b0d61b3884068dc69bf94a115037b5af436c" hash_type = "type" diff --git a/payment-channel-ckb/devnet/default_scripts.json b/payment-channel-ckb/devnet/default_scripts.json new file mode 100644 index 0000000..e041fd8 --- /dev/null +++ b/payment-channel-ckb/devnet/default_scripts.json @@ -0,0 +1,54 @@ +{ + "dao": { + "cell_dep": { + "dep_type": "code", + "out_point": { + "index": "0x2", + "tx_hash": "0x21f3f904e6c71c54ba5c18cd45fb250efd08e98f9836ca95a12fd5ae2ba54eb5" + } + }, + "script_id": { + "code_hash": "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", + "hash_type": "type" + } + }, + "secp256k1_blake160_multisig_all": { + "cell_dep": { + "dep_type": "dep_group", + "out_point": { + "index": "0x1", + "tx_hash": "0xecab1c0cb5d13fd4064b0574e799108f358e84f64b5fcbc70296f7e901060836" + } + }, + "script_id": { + "code_hash": "0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8", + "hash_type": "type" + } + }, + "secp256k1_blake160_sighash_all": { + "cell_dep": { + "dep_type": "dep_group", + "out_point": { + "index": "0x0", + "tx_hash": "0xecab1c0cb5d13fd4064b0574e799108f358e84f64b5fcbc70296f7e901060836" + } + }, + "script_id": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type" + } + }, + "secp256k1_data": { + "out_point": { + "index": "0x3", + "tx_hash": "0x21f3f904e6c71c54ba5c18cd45fb250efd08e98f9836ca95a12fd5ae2ba54eb5" + } + }, + "type_id": { + "script_id": { + "code_hash": "0x00000000000000000000000000000000000000000000000000545950455f4944", + "hash_type": "type" + } + } +} + diff --git a/payment-channel-ckb/devnet/fund_accounts.sh b/payment-channel-ckb/devnet/fund_accounts.sh index e404831..19aaba3 100755 --- a/payment-channel-ckb/devnet/fund_accounts.sh +++ b/payment-channel-ckb/devnet/fund_accounts.sh @@ -8,7 +8,7 @@ genesis_tx_hash=$(ckb-cli wallet get-live-cells --address $genesis | awk '/tx_ha genesis_tx_index=$(ckb-cli wallet get-live-cells --address $genesis | awk '/output_index/ && !found {print $2; found=1}') genesis_tx_amount=$(ckb-cli wallet get-live-cells --address $genesis | awk '/capacity/ {print $3}') FUNDINGTX="fundingtx.json" -FUNDING_AMOUNT=1000 +FUNDING_AMOUNT=5000 CHANGE_AMOUNT=$(python -c "print(\"{:.8f}\".format($genesis_tx_amount - 2.0 * 10.0 * $FUNDING_AMOUNT - 1.0))") add_output() { diff --git a/payment-channel-ckb/devnet/fundingtx.json b/payment-channel-ckb/devnet/fundingtx.json new file mode 100644 index 0000000..904bbc4 --- /dev/null +++ b/payment-channel-ckb/devnet/fundingtx.json @@ -0,0 +1,145 @@ +{ + "transaction": { + "version": "0x0", + "cell_deps": [], + "header_deps": [], + "inputs": [], + "outputs": [ + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0xfb7b530f741a87ba5d7696a4ea967d2f8e68f2ee" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0x60173145c6a1733304a18991d94123d836c88997" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0x60173145c6a1733304a18991d94123d836c88997" + }, + "type": null + }, + { + "capacity": "0x174876e800", + "lock": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": "0x60173145c6a1733304a18991d94123d836c88997" + }, + "type": null + } + ], + "outputs_data": [ + "0x", + "0x", + "0x", + "0x", + "0x", + "0x", + "0x", + "0x", + "0x", + "0x", + "0x", + "0x", + "0x" + ], + "witnesses": [] + }, + "multisig_configs": {}, + "signatures": {} +} \ No newline at end of file diff --git a/payment-channel-ckb/devnet/pubkey.sh b/payment-channel-ckb/devnet/pubkey.sh new file mode 100644 index 0000000..8950982 --- /dev/null +++ b/payment-channel-ckb/devnet/pubkey.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Ignore stderr, as it will print some config information. +ckb-cli util key-info --privkey-path $1 2>/dev/null | awk '/pubkey/ { print $2 }' diff --git a/payment-channel-ckb/go.mod b/payment-channel-ckb/go.mod index 0907bf1..5e29bee 100644 --- a/payment-channel-ckb/go.mod +++ b/payment-channel-ckb/go.mod @@ -1,4 +1,4 @@ -module perun.network/perun-ckb-demo +module perun.network/perun-examples/payment-channel-ckb go 1.17 @@ -8,7 +8,7 @@ require ( github.com/perun-network/perun-libp2p-wire v0.0.0-20240514121025-635388735967 github.com/stretchr/testify v1.9.0 perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e - perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166 + perun.network/perun-ckb-backend v0.0.0-20241024114309-500054212d66 polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37 ) @@ -111,4 +111,4 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace github.com/nervosnetwork/ckb-sdk-go/v2 v2.2.0 => github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80 +replace github.com/nervosnetwork/ckb-sdk-go/v2 v2.2.0 => github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20241016165355-d1c9686fe018 diff --git a/payment-channel-ckb/go.sum b/payment-channel-ckb/go.sum index 65a8e8c..20e9298 100644 --- a/payment-channel-ckb/go.sum +++ b/payment-channel-ckb/go.sum @@ -984,6 +984,8 @@ github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7ir github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80 h1:45S239s+5oGVJHakd+BjfZmstG7wHnA8Tkeq43R9eFA= github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20230601140721-2bf596fddd80/go.mod h1:nPpBML8fuaM1NgkKCwv2gSHiCv+xKH43fu8LA9LOQUg= +github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20241016165355-d1c9686fe018 h1:oURRmvOUVKfNFqhqBonJY1VHKxziyhw4zkL0QLj+m3M= +github.com/perun-network/ckb-sdk-go/v2 v2.2.1-0.20241016165355-d1c9686fe018/go.mod h1:nPpBML8fuaM1NgkKCwv2gSHiCv+xKH43fu8LA9LOQUg= github.com/perun-network/perun-libp2p-wire v0.0.0-20240514121025-635388735967 h1:m+63gl1KMpLdseyNEKLnUFrCYipD9Q0Cnf/hmOwAkhs= github.com/perun-network/perun-libp2p-wire v0.0.0-20240514121025-635388735967/go.mod h1:kA/iWKN+2BvzxuUllMmd1IY6H2oKUZ18U+60hrY19EM= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= @@ -1743,6 +1745,16 @@ perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e h1:4SOKO0WZtcsQUwP5 perun.network/go-perun v0.10.7-0.20230808153546-74844191e56e/go.mod h1:BGBZC3npkX457u87pjDd0NEIXr1a4dsH4H/YpLdGGe8= perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166 h1:Y/3rPrDpspxiMDkh43sV7lkmbSDTM+m37e66kDEidR0= perun.network/perun-ckb-backend v0.0.0-20240514141411-35bdf3afa166/go.mod h1:Ebp1GCFpmlSlxuP+fSO9yk/qAllF+6GhRCe7b2533zs= +perun.network/perun-ckb-backend v0.0.0-20241015122508-45da4c9d6fe5 h1:YbzclIVXy50wJbcTcdmhjS7bGnQgh//fT7FlNpNPnzA= +perun.network/perun-ckb-backend v0.0.0-20241015122508-45da4c9d6fe5/go.mod h1:Ebp1GCFpmlSlxuP+fSO9yk/qAllF+6GhRCe7b2533zs= +perun.network/perun-ckb-backend v0.0.0-20241023133833-11f690d8c9e7 h1:07bC19/sog24+i1nmeaVs3MhrfYw5CoNUNcr9DXuMYA= +perun.network/perun-ckb-backend v0.0.0-20241023133833-11f690d8c9e7/go.mod h1:Ebp1GCFpmlSlxuP+fSO9yk/qAllF+6GhRCe7b2533zs= +perun.network/perun-ckb-backend v0.0.0-20241023162805-3b8074dc74c2 h1:kDCZrLR3ko/+b9foUJ0MfQ7fMmnjnQEh9M6cKp+tX+g= +perun.network/perun-ckb-backend v0.0.0-20241023162805-3b8074dc74c2/go.mod h1:cFfA6/mX8ePTuFrd5cyHhzx1H8hnHs99WrLB9LS+Xbo= +perun.network/perun-ckb-backend v0.0.0-20241024105944-780da45b4f9a h1:Di+tDK9d19gTGlfFn6fxXHCkcfQnvbZs40U+1KQQgRA= +perun.network/perun-ckb-backend v0.0.0-20241024105944-780da45b4f9a/go.mod h1:cFfA6/mX8ePTuFrd5cyHhzx1H8hnHs99WrLB9LS+Xbo= +perun.network/perun-ckb-backend v0.0.0-20241024114309-500054212d66 h1:0k3zF5+xY7TXbTRbCsrSqPJ7I6hRdu/6mHxRwUtnakU= +perun.network/perun-ckb-backend v0.0.0-20241024114309-500054212d66/go.mod h1:cFfA6/mX8ePTuFrd5cyHhzx1H8hnHs99WrLB9LS+Xbo= polycry.pt/poly-go v0.0.0-20220222131629-aa4bdbaab60b/go.mod h1:XUBrNtqgEhN3EEOP/5gh7IBd3xVHKidCjXDZfl9+kMU= polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37 h1:iA5GzEa/hHfVlQpimEjPV09NATwHXxSjWNB0VVodtew= polycry.pt/poly-go v0.0.0-20220301085937-fb9d71b45a37/go.mod h1:XUBrNtqgEhN3EEOP/5gh7IBd3xVHKidCjXDZfl9+kMU= diff --git a/payment-channel-ckb/main.go b/payment-channel-ckb/main.go index a5db617..52cc3a5 100644 --- a/payment-channel-ckb/main.go +++ b/payment-channel-ckb/main.go @@ -1,3 +1,17 @@ +// Copyright 2024 PolyCrypt GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -5,8 +19,8 @@ import ( "fmt" "io/ioutil" "log" + "math/big" "math/rand" - "os" "time" "github.com/nervosnetwork/ckb-sdk-go/v2/types" @@ -15,8 +29,8 @@ import ( "perun.network/go-perun/channel/persistence/keyvalue" "perun.network/perun-ckb-backend/channel/asset" "perun.network/perun-ckb-backend/wallet" - "perun.network/perun-ckb-demo/client" - "perun.network/perun-ckb-demo/deployment" + "perun.network/perun-examples/payment-channel-ckb/client" + "perun.network/perun-examples/payment-channel-ckb/deployment" "polycry.pt/poly-go/sortedkv/memorydb" ) @@ -25,16 +39,9 @@ const ( Network = types.NetworkTest ) -func SetLogFile(path string) { - logFile, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - if err != nil { - log.Fatalf("error opening file: %v", err) - } - log.SetOutput(logFile) -} - func main() { - SetLogFile("demo.log") + //Setup devnet environment + log.Println("Deploying Devnet") sudtOwnerLockArg, err := parseSUDTOwnerLockArg("./devnet/accounts/sudt-owner-lock-hash.txt") if err != nil { log.Fatalf("error getting SUDT owner lock arg: %v", err) @@ -43,13 +50,9 @@ func main() { if err != nil { log.Fatalf("error getting deployment: %v", err) } - /* - maxSudtCapacity := transaction.CalculateCellCapacity(types.CellOutput{ - Capacity: 0, - Lock: &d.DefaultLockScript, - Type: sudtInfo.Script, - }) - */ + + //Setup wallets + log.Println("Creating wallets") w := wallet.NewEphemeralWallet() keyAlice, err := deployment.GetKey("./devnet/accounts/alice.pk") @@ -75,15 +78,15 @@ func main() { aliceWireAcc := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano()))) aliceNet, err := p2p.NewP2PBus(aliceWireAcc) if err != nil { - log.Fatalf("creating p2p net", err) + log.Fatalf("creating p2p net: %v", err) } aliceBus := aliceNet.Bus aliceListener := aliceNet.Listener go aliceBus.Listen(aliceListener) - // Setup clients. - log.Println("Setting up clients.") - //bus := wire.NewLocalBus() // Message bus used for off-chain communication. + log.Println("Setting up payment channel clients") + + //Setup Payment Clients prAlice := keyvalue.NewPersistRestorer(memorydb.NewDatabase()) alice, err := client.NewPaymentClient( @@ -106,7 +109,7 @@ func main() { bobWireAcc := p2p.NewRandomAccount(rand.New(rand.NewSource(time.Now().UnixNano()))) bobNet, err := p2p.NewP2PBus(bobWireAcc) if err != nil { - log.Fatalf("creating p2p net", err) + log.Fatalf("creating p2p net: %v", err) } bobBus := bobNet.Bus bobListener := bobNet.Listener @@ -128,148 +131,96 @@ func main() { log.Fatalf("error creating bob's client: %v", err) } - //print balances before transaction - - fmt.Println("Balances of Alice and Bob before transaction") - str := "'s account balance" - fmt.Println(alice.Name, str, alice.GetBalances()) - fmt.Println(bob.Name, str, bob.GetBalances()) - ckbAsset := asset.Asset{ IsCKBytes: true, SUDT: nil, } - /* - sudtAsset := asset.Asset{ - IsCKBytes: false, - SUDT: &asset.SUDT{ - TypeScript: *sudtInfo.Script, - MaxCapacity: maxSudtCapacity, - }, - } - */ - - fmt.Println("Opening channel and depositing funds") + fmt.Println("Alice Balance:", alice.GetBalances()) + fmt.Println("Bob Balance:", bob.GetBalances()) + + //Open Channel between Alice and Bob + log.Println("Opening channel and depositing funds") chAlice := alice.OpenChannel(bob.WireAddress(), bob.PeerID(), map[channel.Asset]float64{ &asset.Asset{ IsCKBytes: true, SUDT: nil, }: 100.0, }) - strAlice := "Alice" - strBob := "Bob" - fmt.Println(alice.Name, str, alice.GetBalances()) - fmt.Println(bob.Name, str, bob.GetBalances()) - fmt.Println("Alice sent proposal") + log.Println("Alice sent proposal") + //Bob accepts channel chBob := bob.AcceptedChannel() - fmt.Println("Bob accepted proposal") - fmt.Println("Sending payments....") + log.Println("Bob accepted proposal") + + printBalances(chAlice, ckbAsset) + log.Println("Sending payments....") + + //Alice sends payment chAlice.SendPayment(map[channel.Asset]float64{ &ckbAsset: 10.0, }) - fmt.Println("Alice sent Bob a payment") - printAllocationBalances(chAlice, ckbAsset, strAlice) - printAllocationBalances(chBob, ckbAsset, strBob) + log.Println("Alice sent Bob a payment") + printBalances(chAlice, ckbAsset) + //Bob sends payment chBob.SendPayment(map[channel.Asset]float64{ &ckbAsset: 10.0, }) - fmt.Println("Bob sent Alice a payment") - printAllocationBalances(chAlice, ckbAsset, strAlice) - printAllocationBalances(chBob, ckbAsset, strBob) + log.Println("Bob sent Alice a payment") + printBalances(chAlice, ckbAsset) chAlice.SendPayment(map[channel.Asset]float64{ &ckbAsset: 10.0, }) - fmt.Println("Alice sent Bob a payment") - printAllocationBalances(chAlice, ckbAsset, strAlice) - printAllocationBalances(chBob, ckbAsset, strBob) - - fmt.Println("Payments completed") - printAllocationBalances(chAlice, ckbAsset, strAlice) - printAllocationBalances(chBob, ckbAsset, strBob) + log.Println("Alice sent Bob a payment") + printBalances(chAlice, ckbAsset) - fmt.Println("Skip Settling Channel and force client shutdown") - //chAlice.Settle() + log.Println("Payments completed") - fmt.Println(alice.Name, str, alice.GetBalances()) - fmt.Println(bob.Name, str, bob.GetBalances()) + //Settling channels + log.Println("Settle channels") + chAlice.Settle() - //cleanup + //Cleanup alice.Shutdown() bob.Shutdown() - fmt.Println("Clients shutdown, exiting method") - - fmt.Println("Creating clients again to see if channels can be restored") - alice2, err := client.NewPaymentClient( - "Alice", - Network, - d, - rpcNodeURL, - aliceAccount, - *keyAlice, - w, - prAlice, - alice.WireAddress(), - aliceNet, - ) - if err != nil { - log.Fatalf("error creating alice's client: %v", err) - } - bob2, err := client.NewPaymentClient( - "Bob", - Network, - d, - rpcNodeURL, - bobAccount, - *keyBob, - w, - prBob, - bob.WireAddress(), - bobNet, - ) - if err != nil { - log.Fatalf("error creating bob's client: %v", err) - } - fmt.Println("Starting restoring channels") - chansAlice := alice2.Restore(bob2.WireAddress(), bob2.PeerID()) - fmt.Println("Alice's channel restored") - chansBob := bob2.Restore(alice2.WireAddress(), alice2.PeerID()) - fmt.Println("Alice and Bob's channels successfully restored") - - // Print balances after transactions. - fmt.Println(alice.Name, str, alice.GetBalances()) - fmt.Println(bob.Name, str, bob.GetBalances()) - - fmt.Println("Alice sending payment to Bob") - chansAlice[0].SendPayment(map[channel.Asset]float64{ - &ckbAsset: 10.0, - }) - fmt.Println("Bob sending payment to Alice") - chansBob[0].SendPayment(map[channel.Asset]float64{ - &ckbAsset: 10.0, - }) - - chansAlice[0].Settle() - fmt.Println("Balances after settling channel") - fmt.Println(alice.Name, str, alice.GetBalances()) - fmt.Println(bob.Name, str, bob.GetBalances()) + log.Println("Clients shutdown, exiting method") } -func printAllocationBalances(ch *client.PaymentChannel, asset asset.Asset, name string) { +func printBalances(ch *client.PaymentChannel, asset asset.Asset) { chAlloc := ch.State().Allocation - //_assets := chAlloc.Assets - fmt.Println("Assets held by" + name) - /* - for _, a := range _assets { - fmt.Println(a) - } - */ - fmt.Println(name + "'s allocation in channel: " + chAlloc.Balance(1, &asset).String()) + + // Constants for formatting CKBytes + const ckbyteConversionFactor = 100_000_000 // 1 CKByte = 100,000,000 smallest units + + // Log general information + log.Println("=== Allocation Balances ===") + + // Get Alice's balance (participant 0) + aliceBalance := chAlloc.Balance(0, &asset) + aliceBalanceCKBytes := new(big.Float).Quo(new(big.Float).SetInt(aliceBalance), big.NewFloat(ckbyteConversionFactor)) + + // Get Bob's balance (participant 1) + bobBalance := chAlloc.Balance(1, &asset) + bobBalanceCKBytes := new(big.Float).Quo(new(big.Float).SetInt(bobBalance), big.NewFloat(ckbyteConversionFactor)) + + // Print Alice's balance + log.Printf("Alice's allocation: %s CKBytes", aliceBalanceCKBytes.Text('f', 2)) + + // Print Bob's balance + log.Printf("Bob's allocation: %s CKBytes", bobBalanceCKBytes.Text('f', 2)) + + // Calculate the total balance + totalBalance := new(big.Int).Add(aliceBalance, bobBalance) + totalBalanceCKBytes := new(big.Float).Quo(new(big.Float).SetInt(totalBalance), big.NewFloat(ckbyteConversionFactor)) + + // Print the total channel balance + log.Printf("Total channel balance: %s CKBytes", totalBalanceCKBytes.Text('f', 2)) + + log.Println("===========================") } func parseSUDTOwnerLockArg(pathToSUDTOwnerLockArg string) (string, error) { diff --git a/payment-channel-ckb/package-lock.json b/payment-channel-ckb/package-lock.json new file mode 100644 index 0000000..4f7c5f8 --- /dev/null +++ b/payment-channel-ckb/package-lock.json @@ -0,0 +1,110 @@ +{ + "name": "payment-channel-ckb", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "secp256k1": "^5.0.0" + } + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "license": "MIT" + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "license": "MIT" + }, + "node_modules/elliptic": { + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + } + } +} diff --git a/payment-channel-ckb/package.json b/payment-channel-ckb/package.json new file mode 100644 index 0000000..629e7c2 --- /dev/null +++ b/payment-channel-ckb/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "secp256k1": "^5.0.0" + } +} diff --git a/payment-channel-ckb/payment-channel-ckb b/payment-channel-ckb/payment-channel-ckb new file mode 100644 index 0000000000000000000000000000000000000000..16d867860235fa0b15be5cd1cc257860476f8cb6 GIT binary patch literal 11341416 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 z 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 wxun5KMuwSaJ;5QHYU+#ccW+yxB2ANxdvk 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%0Au9kWmHVQjrN8ZJAe2W7Upo62R^lNIL~ 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 z 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