2021-04-26 14:48:20 +00:00
|
|
|
package multisig
|
|
|
|
|
|
|
|
import (
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/go-address"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
|
|
|
|
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
|
|
|
init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init"
|
|
|
|
multisig{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/multisig"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
|
|
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type message{{.v}} struct{ {{if (ge .v 2)}}message0{{else}}from address.Address{{end}} }
|
|
|
|
|
|
|
|
func (m message{{.v}}) Create(
|
|
|
|
signers []address.Address, threshold uint64,
|
|
|
|
unlockStart, unlockDuration abi.ChainEpoch,
|
|
|
|
initialAmount abi.TokenAmount,
|
|
|
|
) (*types.Message, error) {
|
|
|
|
|
|
|
|
lenAddrs := uint64(len(signers))
|
|
|
|
|
|
|
|
if lenAddrs < threshold {
|
|
|
|
return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
|
|
|
|
}
|
|
|
|
|
|
|
|
if threshold == 0 {
|
|
|
|
threshold = lenAddrs
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.from == address.Undef {
|
|
|
|
return nil, xerrors.Errorf("must provide source address")
|
|
|
|
}
|
|
|
|
{{if (le .v 1)}}
|
|
|
|
if unlockStart != 0 {
|
|
|
|
return nil, xerrors.Errorf("actors v0 does not support a non-zero vesting start time")
|
|
|
|
}
|
|
|
|
{{end}}
|
|
|
|
// Set up constructor parameters for multisig
|
|
|
|
msigParams := &multisig{{.v}}.ConstructorParams{
|
|
|
|
Signers: signers,
|
|
|
|
NumApprovalsThreshold: threshold,
|
|
|
|
UnlockDuration: unlockDuration,{{if (ge .v 2)}}
|
|
|
|
StartEpoch: unlockStart,{{end}}
|
|
|
|
}
|
|
|
|
|
|
|
|
enc, actErr := actors.SerializeParams(msigParams)
|
|
|
|
if actErr != nil {
|
|
|
|
return nil, actErr
|
|
|
|
}
|
|
|
|
|
2022-04-21 12:09:49 +00:00
|
|
|
{{if (le .v 7)}}
|
|
|
|
actorCodeID := builtin{{.v}}.MultisigActorCodeID
|
|
|
|
{{else}}
|
|
|
|
actorCodeID, ok := actors.GetActorCodeID(actors.Version{{.v}}, "multisig")
|
|
|
|
if !ok {
|
|
|
|
return nil, xerrors.Errorf("error getting actor multisig code id for actor version %d", {{.v}})
|
|
|
|
}
|
|
|
|
{{end}}
|
2021-04-26 14:48:20 +00:00
|
|
|
// new actors are created by invoking 'exec' on the init actor with the constructor params
|
|
|
|
execParams := &init{{.v}}.ExecParams{
|
2022-04-21 12:09:49 +00:00
|
|
|
CodeCID: actorCodeID,
|
2021-04-26 14:48:20 +00:00
|
|
|
ConstructorParams: enc,
|
|
|
|
}
|
|
|
|
|
|
|
|
enc, actErr = actors.SerializeParams(execParams)
|
|
|
|
if actErr != nil {
|
|
|
|
return nil, actErr
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.Message{
|
|
|
|
To: init_.Address,
|
|
|
|
From: m.from,
|
|
|
|
Method: builtin{{.v}}.MethodsInit.Exec,
|
|
|
|
Params: enc,
|
|
|
|
Value: initialAmount,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
{{if (le .v 1)}}
|
|
|
|
|
|
|
|
func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount,
|
|
|
|
method abi.MethodNum, params []byte) (*types.Message, error) {
|
|
|
|
|
|
|
|
if msig == address.Undef {
|
|
|
|
return nil, xerrors.Errorf("must provide a multisig address for proposal")
|
|
|
|
}
|
|
|
|
|
|
|
|
if to == address.Undef {
|
|
|
|
return nil, xerrors.Errorf("must provide a target address for proposal")
|
|
|
|
}
|
|
|
|
|
|
|
|
if amt.Sign() == -1 {
|
|
|
|
return nil, xerrors.Errorf("must provide a non-negative amount for proposed send")
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.from == address.Undef {
|
|
|
|
return nil, xerrors.Errorf("must provide source address")
|
|
|
|
}
|
|
|
|
|
|
|
|
enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{
|
|
|
|
To: to,
|
|
|
|
Value: amt,
|
|
|
|
Method: method,
|
|
|
|
Params: params,
|
|
|
|
})
|
|
|
|
if actErr != nil {
|
|
|
|
return nil, xerrors.Errorf("failed to serialize parameters: %w", actErr)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.Message{
|
|
|
|
To: msig,
|
|
|
|
From: m.from,
|
|
|
|
Value: abi.NewTokenAmount(0),
|
|
|
|
Method: builtin0.MethodsMultisig.Propose,
|
|
|
|
Params: enc,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
|
|
|
enc, err := txnParams(txID, hashData)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.Message{
|
|
|
|
To: msig,
|
|
|
|
From: m.from,
|
|
|
|
Value: types.NewInt(0),
|
|
|
|
Method: builtin0.MethodsMultisig.Approve,
|
|
|
|
Params: enc,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
|
|
|
enc, err := txnParams(txID, hashData)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.Message{
|
|
|
|
To: msig,
|
|
|
|
From: m.from,
|
|
|
|
Value: types.NewInt(0),
|
|
|
|
Method: builtin0.MethodsMultisig.Cancel,
|
|
|
|
Params: enc,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
{{end}}
|