lotus/node/impl/full/multisig.go

278 lines
8.4 KiB
Go
Raw Normal View History

package full
import (
"context"
2020-07-21 00:17:53 +00:00
2020-09-07 03:49:10 +00:00
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-address"
2020-09-07 03:49:10 +00:00
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
2020-09-30 19:30:02 +00:00
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/types"
2020-09-21 23:01:29 +00:00
2020-10-08 01:09:33 +00:00
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
"github.com/ipfs/go-cid"
"go.uber.org/fx"
"golang.org/x/xerrors"
)
type MsigAPI struct {
fx.In
StateAPI StateAPI
MpoolAPI MpoolAPI
}
2020-09-30 19:30:02 +00:00
func (a *MsigAPI) messageBuilder(ctx context.Context, from address.Address) (multisig.MessageBuilder, error) {
nver, err := a.StateAPI.StateNetworkVersion(ctx, types.EmptyTSK)
if err != nil {
return nil, err
}
2020-09-30 19:30:02 +00:00
return multisig.Message(actors.VersionForNetwork(nver), from), nil
}
2020-09-30 19:30:02 +00:00
// TODO: remove gp (gasPrice) from arguments
// TODO: Add "vesting start" to arguments.
func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) {
2020-09-30 19:30:02 +00:00
mb, err := a.messageBuilder(ctx, src)
if err != nil {
return cid.Undef, err
}
2020-09-30 19:30:02 +00:00
msg, err := mb.Create(addrs, req, 0, duration, val)
if err != nil {
return cid.Undef, err
}
// send the message out to the network
2020-09-30 19:30:02 +00:00
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, err
}
return smsg.Cid(), nil
}
func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
2020-09-30 19:30:02 +00:00
mb, err := a.messageBuilder(ctx, src)
if err != nil {
return cid.Undef, err
}
2020-09-30 19:30:02 +00:00
msg, err := mb.Propose(msig, to, amt, abi.MethodNum(method), params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create proposal: %w", err)
}
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
if err != nil {
2020-07-21 00:17:53 +00:00
return cid.Undef, xerrors.Errorf("failed to push message: %w", err)
}
return smsg.Cid(), nil
}
func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
enc, actErr := serializeAddParams(newAdd, inc)
if actErr != nil {
return cid.Undef, actErr
}
return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
}
func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
enc, actErr := serializeAddParams(newAdd, inc)
if actErr != nil {
return cid.Undef, actErr
}
return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
}
func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
enc, actErr := serializeAddParams(newAdd, inc)
if actErr != nil {
return cid.Undef, actErr
}
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
}
2020-07-16 00:55:27 +00:00
func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
enc, actErr := serializeSwapParams(oldAdd, newAdd)
if actErr != nil {
return cid.Undef, actErr
}
return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
2020-07-16 00:55:27 +00:00
}
func (a *MsigAPI) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
enc, actErr := serializeSwapParams(oldAdd, newAdd)
if actErr != nil {
return cid.Undef, actErr
}
return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
2020-07-16 00:55:27 +00:00
}
func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
enc, actErr := serializeSwapParams(oldAdd, newAdd)
if actErr != nil {
return cid.Undef, actErr
}
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
2020-07-16 00:55:27 +00:00
}
func (a *MsigAPI) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) {
return a.msigApproveOrCancelSimple(ctx, api.MsigApprove, msig, txID, src)
}
func (a *MsigAPI) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
return a.msigApproveOrCancelTxnHash(ctx, api.MsigApprove, msig, txID, proposer, to, amt, src, method, params)
}
2020-07-12 03:54:25 +00:00
func (a *MsigAPI) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
return a.msigApproveOrCancelTxnHash(ctx, api.MsigCancel, msig, txID, src, to, amt, src, method, params)
}
func (a *MsigAPI) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) {
enc, actErr := serializeRemoveParams(toRemove, decrease)
if actErr != nil {
return cid.Undef, actErr
}
return a.MsigPropose(ctx, msig, msig, types.NewInt(0), proposer, uint64(multisig.Methods.RemoveSigner), enc)
}
func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) {
if msig == address.Undef {
return cid.Undef, xerrors.Errorf("must provide multisig address")
}
if src == address.Undef {
return cid.Undef, xerrors.Errorf("must provide source address")
}
mb, err := a.messageBuilder(ctx, src)
if err != nil {
return cid.Undef, err
}
var msg *types.Message
switch operation {
case api.MsigApprove:
msg, err = mb.Approve(msig, txID, nil)
case api.MsigCancel:
msg, err = mb.Cancel(msig, txID, nil)
default:
return cid.Undef, xerrors.Errorf("Invalid operation for msigApproveOrCancel")
}
if err != nil {
return cid.Undef, err
}
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, err
}
return smsg.Cid(), nil
}
func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
if msig == address.Undef {
return cid.Undef, xerrors.Errorf("must provide multisig address")
}
if src == address.Undef {
return cid.Undef, xerrors.Errorf("must provide source address")
}
if proposer.Protocol() != address.ID {
proposerID, err := a.StateAPI.StateLookupID(ctx, proposer, types.EmptyTSK)
if err != nil {
return cid.Undef, err
}
proposer = proposerID
}
2020-09-30 19:30:02 +00:00
p := multisig.ProposalHashData{
Requester: proposer,
To: to,
Value: amt,
Method: abi.MethodNum(method),
Params: params,
}
2020-09-30 19:30:02 +00:00
mb, err := a.messageBuilder(ctx, src)
if err != nil {
return cid.Undef, err
}
2020-09-30 19:30:02 +00:00
var msg *types.Message
switch operation {
case api.MsigApprove:
2020-09-30 19:30:02 +00:00
msg, err = mb.Approve(msig, txID, &p)
case api.MsigCancel:
2020-09-30 19:30:02 +00:00
msg, err = mb.Cancel(msig, txID, &p)
default:
return cid.Undef, xerrors.Errorf("Invalid operation for msigApproveOrCancel")
}
2020-09-30 19:30:02 +00:00
if err != nil {
return cid.Undef, err
}
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, err
}
return smsg.Cid(), nil
}
2020-07-16 00:55:27 +00:00
func serializeAddParams(new address.Address, inc bool) ([]byte, error) {
2020-10-08 01:09:33 +00:00
enc, actErr := actors.SerializeParams(&multisig2.AddSignerParams{
Signer: new,
Increase: inc,
})
if actErr != nil {
return nil, actErr
}
return enc, nil
}
2020-07-16 00:55:27 +00:00
func serializeSwapParams(old address.Address, new address.Address) ([]byte, error) {
2020-10-08 01:09:33 +00:00
enc, actErr := actors.SerializeParams(&multisig2.SwapSignerParams{
2020-07-16 00:55:27 +00:00
From: old,
To: new,
})
if actErr != nil {
return nil, actErr
}
return enc, nil
}
func serializeRemoveParams(rem address.Address, dec bool) ([]byte, error) {
2020-10-08 01:09:33 +00:00
enc, actErr := actors.SerializeParams(&multisig2.RemoveSignerParams{
Signer: rem,
Decrease: dec,
})
if actErr != nil {
return nil, actErr
}
return enc, nil
}