diff --git a/api/api.go b/api/api.go index 6ffbdd3e7..9017921bd 100644 --- a/api/api.go +++ b/api/api.go @@ -84,6 +84,7 @@ type FullNode interface { ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error) ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error) + ChainGetBlockReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error) // if tipset is nil, we'll use heaviest ChainCall(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) diff --git a/api/struct.go b/api/struct.go index a0032de64..c125c7bdd 100644 --- a/api/struct.go +++ b/api/struct.go @@ -46,6 +46,7 @@ type FullNodeStruct struct { ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"` ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"` + ChainGetBlockReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` ChainCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"` @@ -195,6 +196,10 @@ func (c *FullNodeStruct) ChainGetBlockMessages(ctx context.Context, b cid.Cid) ( return c.Internal.ChainGetBlockMessages(ctx, b) } +func (c *FullNodeStruct) ChainGetBlockReceipts(ctx context.Context, b cid.Cid) ([]*types.MessageReceipt, error) { + return c.Internal.ChainGetBlockReceipts(ctx, b) +} + func (c *FullNodeStruct) ChainNotify(ctx context.Context) (<-chan *store.HeadChange, error) { return c.Internal.ChainNotify(ctx) } diff --git a/chain/gen/mining.go b/chain/gen/mining.go index 733a0a717..13804ca5b 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -2,6 +2,7 @@ package gen import ( "context" + "fmt" bls "github.com/filecoin-project/go-bls-sigs" cid "github.com/ipfs/go-cid" @@ -69,14 +70,20 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, miner address.A if err != nil { return nil, errors.Wrap(err, "apply message failure") } + if rec.ActorErr != nil { + fmt.Println(rec.ActorErr) + } - receipts = append(receipts, rec) + receipts = append(receipts, rec.MessageReceipt) } for _, msg := range secpkMessages { rec, err := vmi.ApplyMessage(ctx, &msg.Message) if err != nil { return nil, errors.Wrap(err, "apply message failure") } + if rec.ActorErr != nil { + fmt.Println(rec.ActorErr) + } receipts = append(receipts, rec.MessageReceipt) } diff --git a/chain/types/bigint.go b/chain/types/bigint.go index 23027c4ab..062ea44eb 100644 --- a/chain/types/bigint.go +++ b/chain/types/bigint.go @@ -41,6 +41,15 @@ func BigFromBytes(b []byte) BigInt { return BigInt{i} } +func BigFromString(s string) (BigInt, error) { + v, ok := big.NewInt(0).SetString(s, 10) + if !ok { + return BigInt{}, fmt.Errorf("failed to parse string as a big int") + } + + return BigInt{v}, nil +} + func BigMul(a, b BigInt) BigInt { return BigInt{big.NewInt(0).Mul(a.Int, b.Int)} } diff --git a/cli/chain.go b/cli/chain.go index 5f32a2264..a3459a38b 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -86,15 +86,22 @@ var chainGetBlock = &cli.Command{ return err } + recpts, err := api.ChainGetBlockReceipts(ctx, bcid) + if err != nil { + return err + } + cblock := struct { types.BlockHeader - BlsMessages []*types.Message - SecpkMessages []*types.SignedMessage + BlsMessages []*types.Message + SecpkMessages []*types.SignedMessage + MessageReceipts []*types.MessageReceipt }{} cblock.BlockHeader = *blk cblock.BlsMessages = msgs.BlsMessages cblock.SecpkMessages = msgs.SecpkMessages + cblock.MessageReceipts = recpts out, err := json.MarshalIndent(cblock, "", " ") if err != nil { diff --git a/cli/cmd.go b/cli/cmd.go index 1816122fb..c1faa92f1 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -109,4 +109,5 @@ var Commands = []*cli.Command{ walletCmd, createMinerCmd, stateCmd, + sendCmd, } diff --git a/cli/send.go b/cli/send.go new file mode 100644 index 000000000..37d2d334d --- /dev/null +++ b/cli/send.go @@ -0,0 +1,94 @@ +package cli + +import ( + "fmt" + + "github.com/filecoin-project/go-lotus/chain/address" + types "github.com/filecoin-project/go-lotus/chain/types" + "gopkg.in/urfave/cli.v2" +) + +var sendCmd = &cli.Command{ + Name: "send", + Usage: "send funds between accounts", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "source", + Usage: "optinally specifiy the account to send funds from", + }, + }, + Action: func(cctx *cli.Context) error { + api, err := GetAPI(cctx) + if err != nil { + return err + } + + ctx := ReqContext(cctx) + + if cctx.Args().Len() != 2 { + return fmt.Errorf("'send' expects two arguments, target and amount") + } + + toAddr, err := address.NewFromString(cctx.Args().Get(0)) + if err != nil { + return err + } + + val, err := types.BigFromString(cctx.Args().Get(1)) + if err != nil { + return err + } + + var fromAddr address.Address + if from := cctx.String("source"); from == "" { + defaddr, err := api.WalletDefaultAddress(ctx) + if err != nil { + return err + } + + fromAddr = defaddr + } else { + addr, err := address.NewFromString(from) + if err != nil { + return err + } + + fromAddr = addr + } + + nonce, err := api.MpoolGetNonce(ctx, fromAddr) + if err != nil { + return err + } + + msg := &types.Message{ + From: fromAddr, + To: toAddr, + Value: val, + Nonce: nonce, + GasLimit: types.NewInt(10000), + GasPrice: types.NewInt(1), + } + + sermsg, err := msg.Serialize() + if err != nil { + return err + } + + sig, err := api.WalletSign(ctx, fromAddr, sermsg) + if err != nil { + return err + } + + smsg := &types.SignedMessage{ + Message: *msg, + Signature: *sig, + } + + if err := api.MpoolPush(ctx, smsg); err != nil { + return err + } + + return nil + }, +} diff --git a/go.mod b/go.mod index 2215a07db..29d51b76a 100644 --- a/go.mod +++ b/go.mod @@ -61,10 +61,10 @@ require ( github.com/multiformats/go-multiaddr-net v0.0.1 github.com/multiformats/go-multihash v0.0.6 github.com/pkg/errors v0.8.1 - github.com/polydawn/refmt v0.0.0-20190804001829-26ba426d088b + github.com/polydawn/refmt v0.0.0-20190731040541-eff0b363297a github.com/prometheus/common v0.6.0 github.com/smartystreets/assertions v1.0.1 // indirect - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect + github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect github.com/stretchr/testify v1.3.0 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d @@ -76,8 +76,8 @@ require ( go4.org v0.0.0-20190313082347-94abd6928b1d // indirect golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect - golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa // indirect - golang.org/x/tools v0.0.0-20190806215303-88ddfcebc769 // indirect + golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect + golang.org/x/sys v0.0.0-20190730183949-1393eb018365 // indirect golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect diff --git a/lib/sectorbuilder/poll.go b/lib/sectorbuilder/poll.go index 0e93efc16..d0af6270b 100644 --- a/lib/sectorbuilder/poll.go +++ b/lib/sectorbuilder/poll.go @@ -3,12 +3,12 @@ package sectorbuilder import ( "context" "time" - - "github.com/prometheus/common/log" ) // TODO: really need to get a callbacks API from the rust-sectorbuilder func (sb *SectorBuilder) pollForSealedSectors(ctx context.Context) { + log.Info("starting sealed sector poller") + defer log.Info("leaving sealed sector polling routine") watching := make(map[uint64]bool) staged, err := sb.GetAllStagedSectors() @@ -33,9 +33,11 @@ func (sb *SectorBuilder) pollForSealedSectors(ctx context.Context) { log.Errorf("in loop: failed to get staged sectors: %s", err) continue } + log.Info("num staged sectors: ", len(staged)) for _, s := range staged { watching[s.SectorID] = true } + log.Info("len watching: ", len(watching)) for s := range watching { status, err := sb.SealStatus(s) @@ -44,6 +46,7 @@ func (sb *SectorBuilder) pollForSealedSectors(ctx context.Context) { continue } + log.Infof("sector %d has status %d", s, status.SealStatusCode) if status.SealStatusCode == 0 { // constant pls, zero implies the last step? delete(watching, s) sb.sschan <- status diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 23d840ae6..96bed72dc 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -7,8 +7,12 @@ import ( "github.com/filecoin-project/go-lotus/chain/address" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + + logging "github.com/ipfs/go-log" ) +var log = logging.Logger("sectorbuilder") + type SectorSealingStatus = sectorbuilder.SectorSealingStatus type StagedSectorMetadata = sectorbuilder.StagedSectorMetadata @@ -39,6 +43,7 @@ func New(cfg *SectorBuilderConfig) (*SectorBuilder, error) { return &SectorBuilder{ handle: sbp, + sschan: make(chan SectorSealingStatus, 32), }, nil } diff --git a/node/builder.go b/node/builder.go index a4c23a9bb..cf32623c4 100644 --- a/node/builder.go +++ b/node/builder.go @@ -211,7 +211,7 @@ func Online() Option { // Storage miner ApplyIf(func(s *Settings) bool { return s.nodeType == nodeStorageMiner }, - Override(new(*sectorbuilder.SectorBuilder), sectorbuilder.New), + Override(new(*sectorbuilder.SectorBuilder), modules.SectorBuilder), Override(new(*storage.Miner), modules.StorageMiner), ), ) diff --git a/node/impl/full.go b/node/impl/full.go index a996e1a91..d9467a403 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -100,6 +100,31 @@ func (a *FullNodeAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (* }, nil } +func (a *FullNodeAPI) ChainGetBlockReceipts(ctx context.Context, bcid cid.Cid) ([]*types.MessageReceipt, error) { + b, err := a.Chain.GetBlock(bcid) + if err != nil { + return nil, err + } + + // TODO: need to get the number of messages better than this + bm, sm, err := a.Chain.MessagesForBlock(b) + if err != nil { + return nil, err + } + + var out []*types.MessageReceipt + for i := 0; i < len(bm)+len(sm); i++ { + r, err := a.Chain.GetReceipt(b, i) + if err != nil { + return nil, err + } + + out = append(out, r) + } + + return out, nil +} + func (a *FullNodeAPI) ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) { if ts == nil { ts = a.Chain.GetHeaviestTipSet() @@ -240,6 +265,8 @@ func (a *FullNodeAPI) StateMinerSectors(ctx context.Context, addr address.Addres return nil, err } + log.Info("miner sector count: ", minerState.SectorSetSize) + var sinfos []*api.SectorInfo // Note to self: the hamt isnt a great data structure to use here... need to implement the sector set err = nd.ForEach(ctx, func(k string, val interface{}) error { diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 9668b64fd..2bcbf656a 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -76,6 +76,7 @@ func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h return nil, err } + log.Infof("setting up miner: %s", maddr) sm, err := storage.NewMiner(api, maddr, h, ds, sb, w) if err != nil { return nil, err diff --git a/storage/miner.go b/storage/miner.go index 0a4ea8822..9a3c988e0 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -73,15 +73,18 @@ func (m *Miner) Run(ctx context.Context) error { } func (m *Miner) handlePostingSealedSectors(ctx context.Context) { + defer log.Info("leaving handle posting sealed sectors routine") for { select { case sinfo, ok := <-m.sb.SealedSectorChan(): + log.Info("got a sealed sector notification!") if !ok { // TODO: set some state variable so that this state can be // visible via some status command log.Warning("sealed sector channel closed, aborting process") return } + log.Info("about to send commit sector message: ", sinfo.SectorID, m.maddr) if err := m.commitSector(ctx, sinfo); err != nil { log.Errorf("failed to commit sector: %s", err) @@ -114,7 +117,7 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal Method: actors.MAMethods.CommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(10000 /* i dont know help */), + GasLimit: types.NewInt(1000 /* i dont know help */), GasPrice: types.NewInt(1), }