Incorporate the new PublishStorageDealsReturn
This commit is contained in:
parent
2bafdf7271
commit
84b6734063
@ -1,6 +1,7 @@
|
|||||||
package market
|
package market
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
@ -103,7 +104,28 @@ type DealProposals interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
||||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
|
||||||
|
type PublishStorageDealsReturn interface {
|
||||||
|
DealIDs() ([]abi.DealID, error)
|
||||||
|
// Note that this index is based on the batch of deals that were published, NOT the DealID
|
||||||
|
IsDealValid(index uint64) (bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodePublishStorageDealsReturn(b []byte, nv network.Version) (PublishStorageDealsReturn, error) {
|
||||||
|
av, err := actors.VersionForNetwork(nv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch av {
|
||||||
|
{{range .versions}}
|
||||||
|
case actors.Version{{.}}:
|
||||||
|
return decodePublishStorageDealsReturn{{.}}(b)
|
||||||
|
{{end}}
|
||||||
|
}
|
||||||
|
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||||
|
}
|
||||||
|
|
||||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
||||||
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package market
|
package market
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
@ -177,7 +178,43 @@ type DealProposals interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
||||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
|
||||||
|
type PublishStorageDealsReturn interface {
|
||||||
|
DealIDs() ([]abi.DealID, error)
|
||||||
|
// Note that this index is based on the batch of deals that were published, NOT the DealID
|
||||||
|
IsDealValid(index uint64) (bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodePublishStorageDealsReturn(b []byte, nv network.Version) (PublishStorageDealsReturn, error) {
|
||||||
|
av, err := actors.VersionForNetwork(nv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch av {
|
||||||
|
|
||||||
|
case actors.Version0:
|
||||||
|
return decodePublishStorageDealsReturn0(b)
|
||||||
|
|
||||||
|
case actors.Version2:
|
||||||
|
return decodePublishStorageDealsReturn2(b)
|
||||||
|
|
||||||
|
case actors.Version3:
|
||||||
|
return decodePublishStorageDealsReturn3(b)
|
||||||
|
|
||||||
|
case actors.Version4:
|
||||||
|
return decodePublishStorageDealsReturn4(b)
|
||||||
|
|
||||||
|
case actors.Version5:
|
||||||
|
return decodePublishStorageDealsReturn5(b)
|
||||||
|
|
||||||
|
case actors.Version6:
|
||||||
|
return decodePublishStorageDealsReturn6(b)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||||
|
}
|
||||||
|
|
||||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
||||||
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -236,3 +237,31 @@ func fromV{{.v}}DealProposal(v{{.v}} market{{.v}}.DealProposal) DealProposal {
|
|||||||
func (s *state{{.v}}) GetState() interface{} {
|
func (s *state{{.v}}) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ PublishStorageDealsReturn = (*publishStorageDealsReturn{{.v}})(nil)
|
||||||
|
|
||||||
|
func decodePublishStorageDealsReturn{{.v}}(b []byte) (PublishStorageDealsReturn, error) {
|
||||||
|
var retval market{{.v}}.PublishStorageDealsReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publishStorageDealsReturn{{.v}}{retval}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type publishStorageDealsReturn{{.v}} struct {
|
||||||
|
market{{.v}}.PublishStorageDealsReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn{{.v}}) IsDealValid(index uint64) (bool, error) {
|
||||||
|
{{if (ge .v 6)}}
|
||||||
|
return r.ValidDeals.IsSet(index)
|
||||||
|
{{else}}
|
||||||
|
// PublishStorageDeals only succeeded if all deals were valid in this version of actors
|
||||||
|
return true, nil
|
||||||
|
{{end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn{{.v}}) DealIDs() ([]abi.DealID, error) {
|
||||||
|
return r.IDs, nil
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -229,3 +230,29 @@ func fromV0DealProposal(v0 market0.DealProposal) DealProposal {
|
|||||||
func (s *state0) GetState() interface{} {
|
func (s *state0) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ PublishStorageDealsReturn = (*publishStorageDealsReturn0)(nil)
|
||||||
|
|
||||||
|
func decodePublishStorageDealsReturn0(b []byte) (PublishStorageDealsReturn, error) {
|
||||||
|
var retval market0.PublishStorageDealsReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publishStorageDealsReturn0{retval}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type publishStorageDealsReturn0 struct {
|
||||||
|
market0.PublishStorageDealsReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn0) IsDealValid(index uint64) (bool, error) {
|
||||||
|
|
||||||
|
// PublishStorageDeals only succeeded if all deals were valid in this version of actors
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn0) DealIDs() ([]abi.DealID, error) {
|
||||||
|
return r.IDs, nil
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -229,3 +230,29 @@ func fromV2DealProposal(v2 market2.DealProposal) DealProposal {
|
|||||||
func (s *state2) GetState() interface{} {
|
func (s *state2) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ PublishStorageDealsReturn = (*publishStorageDealsReturn2)(nil)
|
||||||
|
|
||||||
|
func decodePublishStorageDealsReturn2(b []byte) (PublishStorageDealsReturn, error) {
|
||||||
|
var retval market2.PublishStorageDealsReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publishStorageDealsReturn2{retval}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type publishStorageDealsReturn2 struct {
|
||||||
|
market2.PublishStorageDealsReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn2) IsDealValid(index uint64) (bool, error) {
|
||||||
|
|
||||||
|
// PublishStorageDeals only succeeded if all deals were valid in this version of actors
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn2) DealIDs() ([]abi.DealID, error) {
|
||||||
|
return r.IDs, nil
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -224,3 +225,29 @@ func fromV3DealProposal(v3 market3.DealProposal) DealProposal {
|
|||||||
func (s *state3) GetState() interface{} {
|
func (s *state3) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ PublishStorageDealsReturn = (*publishStorageDealsReturn3)(nil)
|
||||||
|
|
||||||
|
func decodePublishStorageDealsReturn3(b []byte) (PublishStorageDealsReturn, error) {
|
||||||
|
var retval market3.PublishStorageDealsReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publishStorageDealsReturn3{retval}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type publishStorageDealsReturn3 struct {
|
||||||
|
market3.PublishStorageDealsReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn3) IsDealValid(index uint64) (bool, error) {
|
||||||
|
|
||||||
|
// PublishStorageDeals only succeeded if all deals were valid in this version of actors
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn3) DealIDs() ([]abi.DealID, error) {
|
||||||
|
return r.IDs, nil
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -224,3 +225,29 @@ func fromV4DealProposal(v4 market4.DealProposal) DealProposal {
|
|||||||
func (s *state4) GetState() interface{} {
|
func (s *state4) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ PublishStorageDealsReturn = (*publishStorageDealsReturn4)(nil)
|
||||||
|
|
||||||
|
func decodePublishStorageDealsReturn4(b []byte) (PublishStorageDealsReturn, error) {
|
||||||
|
var retval market4.PublishStorageDealsReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publishStorageDealsReturn4{retval}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type publishStorageDealsReturn4 struct {
|
||||||
|
market4.PublishStorageDealsReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn4) IsDealValid(index uint64) (bool, error) {
|
||||||
|
|
||||||
|
// PublishStorageDeals only succeeded if all deals were valid in this version of actors
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn4) DealIDs() ([]abi.DealID, error) {
|
||||||
|
return r.IDs, nil
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -224,3 +225,29 @@ func fromV5DealProposal(v5 market5.DealProposal) DealProposal {
|
|||||||
func (s *state5) GetState() interface{} {
|
func (s *state5) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ PublishStorageDealsReturn = (*publishStorageDealsReturn5)(nil)
|
||||||
|
|
||||||
|
func decodePublishStorageDealsReturn5(b []byte) (PublishStorageDealsReturn, error) {
|
||||||
|
var retval market5.PublishStorageDealsReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publishStorageDealsReturn5{retval}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type publishStorageDealsReturn5 struct {
|
||||||
|
market5.PublishStorageDealsReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn5) IsDealValid(index uint64) (bool, error) {
|
||||||
|
|
||||||
|
// PublishStorageDeals only succeeded if all deals were valid in this version of actors
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn5) DealIDs() ([]abi.DealID, error) {
|
||||||
|
return r.IDs, nil
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -224,3 +225,28 @@ func fromV6DealProposal(v6 market6.DealProposal) DealProposal {
|
|||||||
func (s *state6) GetState() interface{} {
|
func (s *state6) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ PublishStorageDealsReturn = (*publishStorageDealsReturn6)(nil)
|
||||||
|
|
||||||
|
func decodePublishStorageDealsReturn6(b []byte) (PublishStorageDealsReturn, error) {
|
||||||
|
var retval market6.PublishStorageDealsReturn
|
||||||
|
if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publishStorageDealsReturn6{retval}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type publishStorageDealsReturn6 struct {
|
||||||
|
market6.PublishStorageDealsReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn6) IsDealValid(index uint64) (bool, error) {
|
||||||
|
|
||||||
|
return r.ValidDeals.IsSet(index)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *publishStorageDealsReturn6) DealIDs() ([]abi.DealID, error) {
|
||||||
|
return r.IDs, nil
|
||||||
|
}
|
||||||
|
@ -193,12 +193,22 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
|
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
|
||||||
}
|
}
|
||||||
var ids market.PublishStorageDealsReturn
|
|
||||||
if err := ids.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
|
retval, err := market.DecodePublishStorageDealsReturn(ret, nv)
|
||||||
return xerrors.Errorf("unmarsahling publishStorageDeals result: %w", err)
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to create genesis miner (decoding published deals): %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
minerInfos[i].dealIDs = append(minerInfos[i].dealIDs, ids.IDs...)
|
ids, err := retval.DealIDs()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to create genesis miner (getting published dealIDs): %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ids) != len(params.Deals) {
|
||||||
|
return xerrors.Errorf("failed to create genesis miner (at least one deal was invalid on publication")
|
||||||
|
}
|
||||||
|
|
||||||
|
minerInfos[i].dealIDs = append(minerInfos[i].dealIDs, ids...)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,8 @@ USAGE:
|
|||||||
lotus-miner actor withdraw [command options] [amount (FIL)]
|
lotus-miner actor withdraw [command options] [amount (FIL)]
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
--help, -h show help (default: false)
|
--confidence value number of block confirmations to wait for (default: 5)
|
||||||
|
--help, -h show help (default: false)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -388,6 +388,7 @@ USAGE:
|
|||||||
OPTIONS:
|
OPTIONS:
|
||||||
--wallet value, -w value Specify address to withdraw funds to, otherwise it will use the default wallet address
|
--wallet value, -w value Specify address to withdraw funds to, otherwise it will use the default wallet address
|
||||||
--address value, -a value Market address to withdraw from (account or miner actor address, defaults to --wallet address)
|
--address value, -a value Market address to withdraw from (account or miner actor address, defaults to --wallet address)
|
||||||
|
--confidence value number of block confirmations to wait for (default: 5)
|
||||||
--help, -h show help (default: false)
|
--help, -h show help (default: false)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
53
extern/storage-sealing/currentdealinfo.go
vendored
53
extern/storage-sealing/currentdealinfo.go
vendored
@ -4,6 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
@ -20,6 +22,7 @@ type CurrentDealInfoAPI interface {
|
|||||||
StateLookupID(context.Context, address.Address, TipSetToken) (address.Address, error)
|
StateLookupID(context.Context, address.Address, TipSetToken) (address.Address, error)
|
||||||
StateMarketStorageDeal(context.Context, abi.DealID, TipSetToken) (*api.MarketDeal, error)
|
StateMarketStorageDeal(context.Context, abi.DealID, TipSetToken) (*api.MarketDeal, error)
|
||||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||||
|
StateNetworkVersion(ctx context.Context, tok TipSetToken) (network.Version, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CurrentDealInfo struct {
|
type CurrentDealInfo struct {
|
||||||
@ -77,27 +80,38 @@ func (mgr *CurrentDealInfoManager) dealIDFromPublishDealsMsg(ctx context.Context
|
|||||||
return dealID, nil, xerrors.Errorf("looking for publish deal message %s: non-ok exit code: %s", publishCid, lookup.Receipt.ExitCode)
|
return dealID, nil, xerrors.Errorf("looking for publish deal message %s: non-ok exit code: %s", publishCid, lookup.Receipt.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
var retval market.PublishStorageDealsReturn
|
nv, err := mgr.CDAPI.StateNetworkVersion(ctx, lookup.TipSetTok)
|
||||||
if err := retval.UnmarshalCBOR(bytes.NewReader(lookup.Receipt.Return)); err != nil {
|
if err != nil {
|
||||||
return dealID, nil, xerrors.Errorf("looking for publish deal message %s: unmarshalling message return: %w", publishCid, err)
|
return dealID, nil, xerrors.Errorf("getting network version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retval, err := market.DecodePublishStorageDealsReturn(lookup.Receipt.Return, nv)
|
||||||
|
if err != nil {
|
||||||
|
return dealID, nil, xerrors.Errorf("looking for publish deal message %s: decoding message return: %w", publishCid, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dealIDs, err := retval.DealIDs()
|
||||||
|
if err != nil {
|
||||||
|
return dealID, nil, xerrors.Errorf("looking for publish deal message %s: getting dealIDs: %w", publishCid, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Can we delete this? We're well past the point when we first introduced the proposals into sealing deal info
|
||||||
// Previously, publish deals messages contained a single deal, and the
|
// Previously, publish deals messages contained a single deal, and the
|
||||||
// deal proposal was not included in the sealing deal info.
|
// deal proposal was not included in the sealing deal info.
|
||||||
// So check if the proposal is nil and check the number of deals published
|
// So check if the proposal is nil and check the number of deals published
|
||||||
// in the message.
|
// in the message.
|
||||||
if proposal == nil {
|
if proposal == nil {
|
||||||
if len(retval.IDs) > 1 {
|
if len(dealIDs) > 1 {
|
||||||
return dealID, nil, xerrors.Errorf(
|
return dealID, nil, xerrors.Errorf(
|
||||||
"getting deal ID from publish deal message %s: "+
|
"getting deal ID from publish deal message %s: "+
|
||||||
"no deal proposal supplied but message return value has more than one deal (%d deals)",
|
"no deal proposal supplied but message return value has more than one deal (%d deals)",
|
||||||
publishCid, len(retval.IDs))
|
publishCid, len(dealIDs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a single deal in this publish message and no deal proposal
|
// There is a single deal in this publish message and no deal proposal
|
||||||
// was supplied, so we have nothing to compare against. Just assume
|
// was supplied, so we have nothing to compare against. Just assume
|
||||||
// the deal ID is correct.
|
// the deal ID is correct and that it was valid
|
||||||
return retval.IDs[0], lookup.TipSetTok, nil
|
return dealIDs[0], lookup.TipSetTok, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the parameters to the publish deals message
|
// Get the parameters to the publish deals message
|
||||||
@ -129,13 +143,22 @@ func (mgr *CurrentDealInfoManager) dealIDFromPublishDealsMsg(ctx context.Context
|
|||||||
return dealID, nil, xerrors.Errorf("could not find deal in publish deals message %s", publishCid)
|
return dealID, nil, xerrors.Errorf("could not find deal in publish deals message %s", publishCid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dealIdx >= len(retval.IDs) {
|
if dealIdx >= len(dealIDs) {
|
||||||
return dealID, nil, xerrors.Errorf(
|
return dealID, nil, xerrors.Errorf(
|
||||||
"deal index %d out of bounds of deals (len %d) in publish deals message %s",
|
"deal index %d out of bounds of deals (len %d) in publish deals message %s",
|
||||||
dealIdx, len(retval.IDs), publishCid)
|
dealIdx, len(dealIDs), publishCid)
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval.IDs[dealIdx], lookup.TipSetTok, nil
|
valid, err := retval.IsDealValid(uint64(dealIdx))
|
||||||
|
if err != nil {
|
||||||
|
return dealID, nil, xerrors.Errorf("determining deal validity: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !valid {
|
||||||
|
return dealID, nil, xerrors.New("deal was invalid at publication")
|
||||||
|
}
|
||||||
|
|
||||||
|
return dealIDs[dealIdx], lookup.TipSetTok, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mgr *CurrentDealInfoManager) CheckDealEquality(ctx context.Context, tok TipSetToken, p1, p2 market.DealProposal) (bool, error) {
|
func (mgr *CurrentDealInfoManager) CheckDealEquality(ctx context.Context, tok TipSetToken, p1, p2 market.DealProposal) (bool, error) {
|
||||||
@ -165,6 +188,7 @@ type CurrentDealInfoTskAPI interface {
|
|||||||
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error)
|
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error)
|
||||||
StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error)
|
StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error)
|
||||||
|
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CurrentDealInfoAPIAdapter struct {
|
type CurrentDealInfoAPIAdapter struct {
|
||||||
@ -210,4 +234,13 @@ func (c *CurrentDealInfoAPIAdapter) StateSearchMsg(ctx context.Context, k cid.Ci
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CurrentDealInfoAPIAdapter) StateNetworkVersion(ctx context.Context, tok TipSetToken) (network.Version, error) {
|
||||||
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
|
if err != nil {
|
||||||
|
return network.VersionMax, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.CurrentDealInfoTskAPI.StateNetworkVersion(ctx, tsk)
|
||||||
|
}
|
||||||
|
|
||||||
var _ CurrentDealInfoAPI = (*CurrentDealInfoAPIAdapter)(nil)
|
var _ CurrentDealInfoAPI = (*CurrentDealInfoAPIAdapter)(nil)
|
||||||
|
12
extern/storage-sealing/currentdealinfo_test.go
vendored
12
extern/storage-sealing/currentdealinfo_test.go
vendored
@ -8,6 +8,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -207,7 +211,7 @@ func TestGetCurrentDealInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
targetProposal: &proposal,
|
targetProposal: &proposal,
|
||||||
expectedDealID: zeroDealID,
|
expectedDealID: zeroDealID,
|
||||||
expectedError: xerrors.Errorf("looking for publish deal message %s: unmarshalling message return: cbor input should be of type array", dummyCid),
|
expectedError: xerrors.Errorf("looking for publish deal message %s: decoding message return: failed to unmarshal PublishStorageDealsReturn: cbor input should be of type array", dummyCid),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runTestCase := func(testCase string, data testCaseData) {
|
runTestCase := func(testCase string, data testCaseData) {
|
||||||
@ -305,9 +309,13 @@ func (mapi *CurrentDealInfoMockAPI) StateSearchMsg(ctx context.Context, c cid.Ci
|
|||||||
return mapi.SearchMessageLookup, mapi.SearchMessageErr
|
return mapi.SearchMessageLookup, mapi.SearchMessageErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mapi *CurrentDealInfoMockAPI) StateNetworkVersion(ctx context.Context, tok TipSetToken) (network.Version, error) {
|
||||||
|
return network.Version0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func makePublishDealsReturnBytes(t *testing.T, dealIDs []abi.DealID) []byte {
|
func makePublishDealsReturnBytes(t *testing.T, dealIDs []abi.DealID) []byte {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
dealsReturn := market.PublishStorageDealsReturn{
|
dealsReturn := market0.PublishStorageDealsReturn{
|
||||||
IDs: dealIDs,
|
IDs: dealIDs,
|
||||||
}
|
}
|
||||||
err := dealsReturn.MarshalCBOR(buf)
|
err := dealsReturn.MarshalCBOR(buf)
|
||||||
|
4
extern/storage-sealing/states_failed_test.go
vendored
4
extern/storage-sealing/states_failed_test.go
vendored
@ -5,6 +5,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
mh "github.com/multiformats/go-multihash"
|
mh "github.com/multiformats/go-multihash"
|
||||||
@ -52,7 +54,7 @@ func TestStateRecoverDealIDs(t *testing.T) {
|
|||||||
api.EXPECT().StateSearchMsg(ctx, pc).Return(&sealing.MsgLookup{
|
api.EXPECT().StateSearchMsg(ctx, pc).Return(&sealing.MsgLookup{
|
||||||
Receipt: sealing.MessageReceipt{
|
Receipt: sealing.MessageReceipt{
|
||||||
ExitCode: exitcode.Ok,
|
ExitCode: exitcode.Ok,
|
||||||
Return: cborRet(&market.PublishStorageDealsReturn{
|
Return: cborRet(&market0.PublishStorageDealsReturn{
|
||||||
IDs: []abi.DealID{dealId},
|
IDs: []abi.DealID{dealId},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,9 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
|
builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@ -19,9 +22,6 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
|
|
||||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
marketactor "github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
marketactor "github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||||
@ -108,10 +108,10 @@ func (c *ClientNodeAdapter) VerifySignature(ctx context.Context, sig crypto.Sign
|
|||||||
func (c *ClientNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) {
|
func (c *ClientNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) {
|
||||||
// (Provider Node API)
|
// (Provider Node API)
|
||||||
smsg, err := c.MpoolPushMessage(ctx, &types.Message{
|
smsg, err := c.MpoolPushMessage(ctx, &types.Message{
|
||||||
To: miner2.StorageMarketActorAddr,
|
To: marketactor.Address,
|
||||||
From: addr,
|
From: addr,
|
||||||
Value: amount,
|
Value: amount,
|
||||||
Method: miner2.MethodsMarket.AddBalance,
|
Method: builtin6.MethodsMarket.AddBalance,
|
||||||
}, nil)
|
}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
@ -171,19 +171,20 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !pubOk {
|
if !pubOk {
|
||||||
return 0, xerrors.Errorf("deal wasn't published by storage provider: from=%s, provider=%s,%+v", pubmsg.From, deal.Proposal.Provider, pubAddrs)
|
return 0, xerrors.Errorf("deal wasn't published by storage provider: from=%s, provider=%s,%+v", pubmsg.From, deal.Proposal.Provider, pubAddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pubmsg.To != miner2.StorageMarketActorAddr {
|
if pubmsg.To != marketactor.Address {
|
||||||
return 0, xerrors.Errorf("deal publish message wasn't set to StorageMarket actor (to=%s)", pubmsg.To)
|
return 0, xerrors.Errorf("deal publish message wasn't set to StorageMarket actor (to=%s)", pubmsg.To)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pubmsg.Method != miner2.MethodsMarket.PublishStorageDeals {
|
if pubmsg.Method != builtin6.MethodsMarket.PublishStorageDeals {
|
||||||
return 0, xerrors.Errorf("deal publish message called incorrect method (method=%s)", pubmsg.Method)
|
return 0, xerrors.Errorf("deal publish message called incorrect method (method=%s)", pubmsg.Method)
|
||||||
}
|
}
|
||||||
|
|
||||||
var params market2.PublishStorageDealsParams
|
var params marketactor.PublishStorageDealsParams
|
||||||
if err := params.UnmarshalCBOR(bytes.NewReader(pubmsg.Params)); err != nil {
|
if err := params.UnmarshalCBOR(bytes.NewReader(pubmsg.Params)); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -215,12 +216,37 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor
|
|||||||
return 0, xerrors.Errorf("deal publish failed: exit=%d", ret.Receipt.ExitCode)
|
return 0, xerrors.Errorf("deal publish failed: exit=%d", ret.Receipt.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
var res market2.PublishStorageDealsReturn
|
nv, err := c.StateNetworkVersion(ctx, ret.TipSet)
|
||||||
if err := res.UnmarshalCBOR(bytes.NewReader(ret.Receipt.Return)); err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, xerrors.Errorf("getting network version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.IDs[dealIdx], nil
|
res, err := marketactor.DecodePublishStorageDealsReturn(ret.Receipt.Return, nv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, xerrors.Errorf("decoding deal publish return: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dealIDs, err := res.DealIDs()
|
||||||
|
if err != nil {
|
||||||
|
return 0, xerrors.Errorf("getting dealIDs: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dealIdx >= len(dealIDs) {
|
||||||
|
return 0, xerrors.Errorf(
|
||||||
|
"deal index %d out of bounds of deals (len %d) in publish deals message %s",
|
||||||
|
dealIdx, len(dealIDs), pubmsg.Cid())
|
||||||
|
}
|
||||||
|
|
||||||
|
valid, err := res.IsDealValid(uint64(dealIdx))
|
||||||
|
if err != nil {
|
||||||
|
return 0, xerrors.Errorf("determining deal validity: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !valid {
|
||||||
|
return 0, xerrors.New("deal was invalid at publication")
|
||||||
|
}
|
||||||
|
|
||||||
|
return dealIDs[dealIdx], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientOverestimation = struct {
|
var clientOverestimation = struct {
|
||||||
@ -243,12 +269,12 @@ func (c *ClientNodeAdapter) DealProviderCollateralBounds(ctx context.Context, si
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove dealID parameter, change publishCid to be cid.Cid (instead of pointer)
|
// TODO: Remove dealID parameter, change publishCid to be cid.Cid (instead of pointer)
|
||||||
func (c *ClientNodeAdapter) OnDealSectorPreCommitted(ctx context.Context, provider address.Address, dealID abi.DealID, proposal market2.DealProposal, publishCid *cid.Cid, cb storagemarket.DealSectorPreCommittedCallback) error {
|
func (c *ClientNodeAdapter) OnDealSectorPreCommitted(ctx context.Context, provider address.Address, dealID abi.DealID, proposal market0.DealProposal, publishCid *cid.Cid, cb storagemarket.DealSectorPreCommittedCallback) error {
|
||||||
return c.scMgr.OnDealSectorPreCommitted(ctx, provider, marketactor.DealProposal(proposal), *publishCid, cb)
|
return c.scMgr.OnDealSectorPreCommitted(ctx, provider, marketactor.DealProposal(proposal), *publishCid, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove dealID parameter, change publishCid to be cid.Cid (instead of pointer)
|
// TODO: Remove dealID parameter, change publishCid to be cid.Cid (instead of pointer)
|
||||||
func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider address.Address, dealID abi.DealID, sectorNumber abi.SectorNumber, proposal market2.DealProposal, publishCid *cid.Cid, cb storagemarket.DealSectorCommittedCallback) error {
|
func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider address.Address, dealID abi.DealID, sectorNumber abi.SectorNumber, proposal market0.DealProposal, publishCid *cid.Cid, cb storagemarket.DealSectorCommittedCallback) error {
|
||||||
return c.scMgr.OnDealSectorCommitted(ctx, provider, sectorNumber, marketactor.DealProposal(proposal), *publishCid, cb)
|
return c.scMgr.OnDealSectorCommitted(ctx, provider, sectorNumber, marketactor.DealProposal(proposal), *publishCid, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +368,7 @@ func (c *ClientNodeAdapter) OnDealExpiredOrSlashed(ctx context.Context, dealID a
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Address, proposal market2.DealProposal) (*market2.ClientDealProposal, error) {
|
func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Address, proposal market0.DealProposal) (*marketactor.ClientDealProposal, error) {
|
||||||
// TODO: output spec signed proposal
|
// TODO: output spec signed proposal
|
||||||
buf, err := cborutil.Dump(&proposal)
|
buf, err := cborutil.Dump(&proposal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -361,7 +387,7 @@ func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &market2.ClientDealProposal{
|
return &marketactor.ClientDealProposal{
|
||||||
Proposal: proposal,
|
Proposal: proposal,
|
||||||
ClientSignature: *sig,
|
ClientSignature: *sig,
|
||||||
}, nil
|
}, nil
|
||||||
|
Loading…
Reference in New Issue
Block a user