convert multisig to new actor abstractions
This commit is contained in:
parent
f9a896f6f2
commit
0ab2459fce
@ -3,9 +3,12 @@ package multisig
|
|||||||
import (
|
import (
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"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/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
|
||||||
"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"
|
||||||
@ -31,4 +34,10 @@ type State interface {
|
|||||||
StartEpoch() abi.ChainEpoch
|
StartEpoch() abi.ChainEpoch
|
||||||
UnlockDuration() abi.ChainEpoch
|
UnlockDuration() abi.ChainEpoch
|
||||||
InitialBalance() abi.TokenAmount
|
InitialBalance() abi.TokenAmount
|
||||||
|
Threshold() uint64
|
||||||
|
Signers() []address.Address
|
||||||
|
|
||||||
|
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Transaction = msig0.Transaction
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
package multisig
|
package multisig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
"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/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
multisig.State
|
msig0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,3 +34,26 @@ func (s *state0) UnlockDuration() abi.ChainEpoch {
|
|||||||
func (s *state0) InitialBalance() abi.TokenAmount {
|
func (s *state0) InitialBalance() abi.TokenAmount {
|
||||||
return s.State.InitialBalance
|
return s.State.InitialBalance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state0) Threshold() uint64 {
|
||||||
|
return s.State.NumApprovalsThreshold
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state0) Signers() []address.Address {
|
||||||
|
return s.State.Signers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
||||||
|
arr, err := adt0.AsMap(s.store, s.State.PendingTxns)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var out msig0.Transaction
|
||||||
|
return arr.ForEach(&out, func(key string) error {
|
||||||
|
txid, n := binary.Varint([]byte(key))
|
||||||
|
if n <= 0 {
|
||||||
|
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||||
|
}
|
||||||
|
return cb(txid, (Transaction)(out))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
103
cli/multisig.go
103
cli/multisig.go
@ -2,8 +2,6 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"encoding/binary"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -12,21 +10,21 @@ import (
|
|||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
|
||||||
cid "github.com/ipfs/go-cid"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api/apibstore"
|
"github.com/filecoin-project/lotus/api/apibstore"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
types "github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var multisigCmd = &cli.Command{
|
var multisigCmd = &cli.Command{
|
||||||
@ -146,7 +144,7 @@ var msigCreateCmd = &cli.Command{
|
|||||||
|
|
||||||
// get address of newly created miner
|
// get address of newly created miner
|
||||||
|
|
||||||
var execreturn init_.ExecReturn
|
var execreturn init0.ExecReturn
|
||||||
if err := execreturn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
|
if err := execreturn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -179,50 +177,54 @@ var msigInspectCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
store := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(api)))
|
||||||
|
|
||||||
maddr, err := address.NewFromString(cctx.Args().First())
|
maddr, err := address.NewFromString(cctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
act, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
obj, err := api.ChainReadObj(ctx, act.Head)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
head, err := api.ChainHead(ctx)
|
head, err := api.ChainHead(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var mstate msig0.State
|
act, err := api.StateGetActor(ctx, maddr, head.Key())
|
||||||
if err := mstate.UnmarshalCBOR(bytes.NewReader(obj)); err != nil {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mstate, err := multisig.Load(store, act)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
locked, err := mstate.LockedBalance(head.Height())
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
locked := mstate.AmountLocked(head.Height() - mstate.StartEpoch)
|
|
||||||
fmt.Printf("Balance: %s\n", types.FIL(act.Balance))
|
fmt.Printf("Balance: %s\n", types.FIL(act.Balance))
|
||||||
fmt.Printf("Spendable: %s\n", types.FIL(types.BigSub(act.Balance, locked)))
|
fmt.Printf("Spendable: %s\n", types.FIL(types.BigSub(act.Balance, locked)))
|
||||||
|
|
||||||
if cctx.Bool("vesting") {
|
if cctx.Bool("vesting") {
|
||||||
fmt.Printf("InitialBalance: %s\n", types.FIL(mstate.InitialBalance))
|
fmt.Printf("InitialBalance: %s\n", types.FIL(mstate.InitialBalance()))
|
||||||
fmt.Printf("StartEpoch: %d\n", mstate.StartEpoch)
|
fmt.Printf("StartEpoch: %d\n", mstate.StartEpoch())
|
||||||
fmt.Printf("UnlockDuration: %d\n", mstate.UnlockDuration)
|
fmt.Printf("UnlockDuration: %d\n", mstate.UnlockDuration())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Threshold: %d / %d\n", mstate.NumApprovalsThreshold, len(mstate.Signers))
|
signers := mstate.Signers()
|
||||||
|
fmt.Printf("Threshold: %d / %d\n", mstate.Threshold(), len(signers))
|
||||||
fmt.Println("Signers:")
|
fmt.Println("Signers:")
|
||||||
for _, s := range mstate.Signers {
|
for _, s := range signers {
|
||||||
fmt.Printf("\t%s\n", s)
|
fmt.Printf("\t%s\n", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pending, err := GetMultisigPending(ctx, api, mstate.PendingTxns)
|
pending := make(map[int64]multisig.Transaction)
|
||||||
if err != nil {
|
if err := mstate.ForEachPendingTxn(func(id int64, txn multisig.Transaction) error {
|
||||||
return fmt.Errorf("reading pending transactions: %w", err)
|
pending[id] = txn
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return xerrors.Errorf("reading pending transactions: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Transactions: ", len(pending))
|
fmt.Println("Transactions: ", len(pending))
|
||||||
@ -239,7 +241,7 @@ var msigInspectCmd = &cli.Command{
|
|||||||
fmt.Fprintf(w, "ID\tState\tApprovals\tTo\tValue\tMethod\tParams\n")
|
fmt.Fprintf(w, "ID\tState\tApprovals\tTo\tValue\tMethod\tParams\n")
|
||||||
for _, txid := range txids {
|
for _, txid := range txids {
|
||||||
tx := pending[txid]
|
tx := pending[txid]
|
||||||
fmt.Fprintf(w, "%d\t%s\t%d\t%s\t%s\t%d\t%x\n", txid, state(tx), len(tx.Approved), tx.To, types.FIL(tx.Value), tx.Method, tx.Params)
|
fmt.Fprintf(w, "%d\t%s\t%d\t%s\t%s\t%d\t%x\n", txid, "pending", len(tx.Approved), tx.To, types.FIL(tx.Value), tx.Method, tx.Params)
|
||||||
}
|
}
|
||||||
if err := w.Flush(); err != nil {
|
if err := w.Flush(); err != nil {
|
||||||
return xerrors.Errorf("flushing output: %+v", err)
|
return xerrors.Errorf("flushing output: %+v", err)
|
||||||
@ -251,43 +253,6 @@ var msigInspectCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) (map[int64]*msig0.Transaction, error) {
|
|
||||||
bs := apibstore.NewAPIBlockstore(lapi)
|
|
||||||
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
|
||||||
|
|
||||||
nd, err := adt.AsMap(store, hroot)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
txs := make(map[int64]*msig0.Transaction)
|
|
||||||
var tx msig0.Transaction
|
|
||||||
err = nd.ForEach(&tx, func(k string) error {
|
|
||||||
txid, _ := binary.Varint([]byte(k))
|
|
||||||
|
|
||||||
cpy := tx // copy so we don't clobber on future iterations.
|
|
||||||
txs[txid] = &cpy
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to iterate transactions hamt: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return txs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func state(tx *msig0.Transaction) string {
|
|
||||||
/* // TODO(why): I strongly disagree with not having these... but i need to move forward
|
|
||||||
if tx.Complete {
|
|
||||||
return "done"
|
|
||||||
}
|
|
||||||
if tx.Canceled {
|
|
||||||
return "canceled"
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
var msigProposeCmd = &cli.Command{
|
var msigProposeCmd = &cli.Command{
|
||||||
Name: "propose",
|
Name: "propose",
|
||||||
Usage: "Propose a multisig transaction",
|
Usage: "Propose a multisig transaction",
|
||||||
|
Loading…
Reference in New Issue
Block a user