From 257685342699a6465d1d702d348634f97d86aef0 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 29 Jul 2019 11:57:23 -0700 Subject: [PATCH 1/6] begin work on storage miner processes --- go.mod | 3 + go.sum | 17 +++ lib/sectorbuilder/poll.go | 57 ++++++++++ lib/sectorbuilder/sectorbuilder.go | 12 ++ storage/miner.go | 173 +++++++++++++++++++++++++++++ 5 files changed, 262 insertions(+) create mode 100644 lib/sectorbuilder/poll.go create mode 100644 storage/miner.go diff --git a/go.mod b/go.mod index d4ea9604b..454dc74d4 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.12 require ( contrib.go.opencensus.io/exporter/jaeger v0.1.0 github.com/BurntSushi/toml v0.3.1 + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 // indirect github.com/filecoin-project/go-bls-sigs v0.0.0-20190718224239-4bc4b8a7bbf8 github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543 github.com/filecoin-project/go-sectorbuilder v0.0.0-00010101000000-000000000000 @@ -60,6 +62,7 @@ require ( github.com/multiformats/go-multihash v0.0.6 github.com/pkg/errors v0.8.1 github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14 + github.com/prometheus/common v0.6.0 github.com/smartystreets/assertions v1.0.1 // indirect github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect github.com/stretchr/testify v1.3.0 diff --git a/go.sum b/go.sum index 55488b54b..0f87ce619 100644 --- a/go.sum +++ b/go.sum @@ -14,11 +14,16 @@ github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cB github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50 h1:4i3KsuVA0o0KoBxAC5x+MY7RbteiMK1V7gf/G08NGIQ= @@ -72,6 +77,7 @@ github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJY github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -221,6 +227,7 @@ github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr1 github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -228,6 +235,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -402,6 +410,8 @@ github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= @@ -453,11 +463,17 @@ github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14 h1:2m16U/rLwVaRdz7A github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= @@ -575,6 +591,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= diff --git a/lib/sectorbuilder/poll.go b/lib/sectorbuilder/poll.go new file mode 100644 index 000000000..0e93efc16 --- /dev/null +++ b/lib/sectorbuilder/poll.go @@ -0,0 +1,57 @@ +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) { + watching := make(map[uint64]bool) + + staged, err := sb.GetAllStagedSectors() + if err != nil { + // TODO: this is probably worth shutting the miner down over until we + // have better recovery mechanisms + log.Errorf("failed to get staged sectors: %s", err) + } + for _, s := range staged { + watching[s.SectorID] = true + } + + tick := time.Tick(time.Second * 30) + for { + select { + case <-tick: + log.Info("polling for sealed sectors...") + + // add new staged sectors to watch list + staged, err := sb.GetAllStagedSectors() + if err != nil { + log.Errorf("in loop: failed to get staged sectors: %s", err) + continue + } + for _, s := range staged { + watching[s.SectorID] = true + } + + for s := range watching { + status, err := sb.SealStatus(s) + if err != nil { + log.Errorf("getting seal status: %s", err) + continue + } + + if status.SealStatusCode == 0 { // constant pls, zero implies the last step? + delete(watching, s) + sb.sschan <- status + } + } + case <-ctx.Done(): + close(sb.sschan) + return + } + } +} diff --git a/lib/sectorbuilder/sectorbuilder.go b/lib/sectorbuilder/sectorbuilder.go index 20bc8fb27..81d036e6e 100644 --- a/lib/sectorbuilder/sectorbuilder.go +++ b/lib/sectorbuilder/sectorbuilder.go @@ -1,6 +1,7 @@ package sectorbuilder import ( + "context" "unsafe" "github.com/filecoin-project/go-lotus/chain/address" @@ -15,6 +16,8 @@ const CommLen = sectorbuilder.CommitmentBytesLen type SectorBuilder struct { handle unsafe.Pointer + + sschan chan SectorSealingStatus } type SectorBuilderConfig struct { @@ -39,6 +42,10 @@ func New(cfg *SectorBuilderConfig) (*SectorBuilder, error) { }, nil } +func (sb *SectorBuilder) Run(ctx context.Context) { + go sb.pollForSealedSectors(ctx) +} + func (sb *SectorBuilder) Destroy() { sectorbuilder.DestroySectorBuilder(sb.handle) } @@ -70,6 +77,11 @@ func (sb *SectorBuilder) GeneratePoSt(sortedCommRs [][CommLen]byte, challengeSee return sectorbuilder.GeneratePoSt(sb.handle, sortedCommRs, challengeSeed) } +func (sb *SectorBuilder) SealedSectorChan() <-chan SectorSealingStatus { + // is this ever going to be multi-consumer? If so, switch to using pubsub/eventbus + return sb.sschan +} + var UserBytesForSectorSize = sectorbuilder.GetMaxUserBytesPerStagedSector func VerifySeal(sectorSize uint64, commR, commD, commRStar [CommLen]byte, proverID address.Address, sectorID uint64, proof []byte) (bool, error) { diff --git a/storage/miner.go b/storage/miner.go new file mode 100644 index 000000000..35c79c810 --- /dev/null +++ b/storage/miner.go @@ -0,0 +1,173 @@ +package storage + +import ( + "context" + + "github.com/filecoin-project/go-lotus/api" + "github.com/filecoin-project/go-lotus/chain/actors" + "github.com/filecoin-project/go-lotus/chain/address" + "github.com/filecoin-project/go-lotus/chain/store" + "github.com/filecoin-project/go-lotus/chain/types" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + logging "github.com/ipfs/go-log" + host "github.com/libp2p/go-libp2p-core/host" + "github.com/pkg/errors" + + "github.com/filecoin-project/go-lotus/lib/sectorbuilder" +) + +var log = logging.Logger("storageminer") + +type Miner struct { + api storageMinerApi + + sb *sectorbuilder.SectorBuilder + + maddr address.Address + + worker address.Address + + h host.Host + + ds datastore.Batching +} + +type storageMinerApi interface { + // I think I want this... but this is tricky + //ReadState(ctx context.Context, addr address.Address) (????, error) + + // Call a read only method on actors (no interaction with the chain required) + CallMethod(ctx context.Context, addr address.Address, method uint64, params []byte) ([]byte, error) + + MpoolPush(context.Context, *types.SignedMessage) error + MpoolGetNonce(context.Context, address.Address) (uint64, error) + + ChainWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) + ChainNotifs(context.Context) (<-chan *store.HeadChange, error) + + WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) +} + +func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, sb *sectorbuilder.SectorBuilder) (*Miner, error) { + return &Miner{ + api: api, + maddr: addr, + h: h, + ds: ds, + sb: sb, + }, nil +} + +func (m *Miner) Run(ctx context.Context) error { + if err := m.runPreflightChecks(ctx); err != nil { + return errors.Wrap(err, "miner preflight checks failed") + } + + go m.handlePostingSealedSectors(ctx) + go m.runPoSt(ctx) + return nil +} + +func (m *Miner) handlePostingSealedSectors(ctx context.Context) { + for { + select { + case sinfo, ok := <-m.sb.SealedSectorChan(): + 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 + } + + case <-ctx.Done(): + log.Warning("exiting seal posting routine") + return + } + } +} +func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSealingStatus) error { + params := &actors.CommitSectorParams{ + SectorId: types.NewInt(sinfo.SectorID), + CommD: sinfo.CommD, + CommR: sinfo.CommR, + CommRStar: sinfo.CommRStar, + Proof: sinfo.Proof, + } + enc, err := actors.SerializeParams(params) + if err != nil { + return errors.wrap(err, "could not serialize commit sector parameters") + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.CommitSector, + Params: params, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(10000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + nonce, err := m.api.MpoolGetNonce(ctx, m.worker) + if err != nil { + return errors.Wrap(err, "failed to get nonce") + } + + msg.Nonce = nonce + + data, err := msg.Serialize() + if err != nil { + return errors.Wrap(err, "serializing commit sector message") + } + + sig, err := m.api.WalletSign(ctx, m.worker, data) + if err != nil { + return errors.Wrap(err, "signing commit sector message") + } + + smsg := &types.SignedMessage{ + Message: msg, + Signature: sig, + } + + if err := m.api.MpoolPush(ctx, smsg); err != nil { + return errors.Wrap(err, "pushing commit sector message to mpool") + } + + m.trackCommitSectorMessage(smsg) +} + +// make sure the message gets included in the chain successfully +func (m *Miner) trackCommitSectorMessage(smsg *types.SignedMessage) { + log.Warning("not currently tracking commit sector messages") +} + +func (m *Miner) runPoSt(ctx context.Context) { + log.Warning("dont care about posts yet") +} + +func (m *Miner) runPreflightChecks(ctx context.Context) error { + worker, err := m.getWorkerAddr(ctx) + if err != nil { + return err + } + + m.worker = worker + + // try signing something with that key to make sure we can + if _, err := m.api.WalletSign(ctx, worker, []byte("sign me")); err != nil { + return errors.Wrap(err, "failed to verify ablity to sign with worker key") + } + + return nil +} + +func (m *Miner) getWorkerAddr(ctx context.Context) (address.Address, error) { + ret, err := m.api.CallMethod(ctx, m.maddr, actors.MAMethods.GetWorkerAddr, actors.EmptyStructCBOR) + if err != nil { + return address.Undef, errors.Wrapf(err, "calling getWorker(%s)", m.maddr) + } + + return address.NewFromBytes(ret) +} From ee224e5b210593b0a22ec59b4a4bc12a8a529357 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 29 Jul 2019 17:46:56 -0700 Subject: [PATCH 2/6] Implement 'storage miner' module, wire up a few bits it needs to start --- api/api.go | 1 + api/struct.go | 19 ++++++---- chain/actors/actor_miner.go | 11 +++++- chain/address/address.go | 5 +++ chain/state/statetree.go | 5 +++ chain/types/bigint.go | 2 + chain/wallet/wallet.go | 8 ++++ cmd/lotus-storage-miner/init.go | 10 ++++- cmd/lotus-storage-miner/run.go | 1 + node/builder.go | 6 ++- node/impl/full.go | 27 ++++++++++++++ node/impl/storminer.go | 3 ++ node/modules/core.go | 49 ++++++++++++++++++++++++- storage/miner.go | 65 +++++++++++++++++++++++---------- 14 files changed, 181 insertions(+), 31 deletions(-) diff --git a/api/api.go b/api/api.go index d5ba98f64..8fcaadc5f 100644 --- a/api/api.go +++ b/api/api.go @@ -73,6 +73,7 @@ type FullNode interface { ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error) ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) ChainGetBlockMessages(context.Context, cid.Cid) ([]*types.SignedMessage, error) + ChainCall(context.Context, *types.Message) (*types.MessageReceipt, error) // messages diff --git a/api/struct.go b/api/struct.go index 82379f278..b33701b8e 100644 --- a/api/struct.go +++ b/api/struct.go @@ -39,13 +39,14 @@ type FullNodeStruct struct { CommonStruct Internal struct { - ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"` - ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"` - ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` - ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"` - 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) ([]*types.SignedMessage, error) `perm:"read"` + ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"` + ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"` + ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` + ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"` + 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) ([]*types.SignedMessage, error) `perm:"read"` + ChainCall func(context.Context, *types.Message) (*types.MessageReceipt, error) `perm:"read"` MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"` MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"` @@ -155,6 +156,10 @@ func (c *FullNodeStruct) ChainWaitMsg(ctx context.Context, msgc cid.Cid) (*MsgWa return c.Internal.ChainWaitMsg(ctx, msgc) } +func (c *FullNodeStruct) ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) { + return c.Internal.ChainCall(ctx, msg) +} + func (c *FullNodeStruct) WalletNew(ctx context.Context, typ string) (address.Address, error) { return c.Internal.WalletNew(ctx, typ) } diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 34d023048..f40f8bb40 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -118,7 +118,7 @@ func (sma StorageMinerActor) Exports() []interface{} { //6: sma.ArbitrateDeal, //7: sma.DePledge, //8: sma.GetOwner, - //9: sma.GetWorkerAddr, + 9: sma.GetWorkerAddr, 10: sma.GetPower, //11: sma.GetPeerID, //12: sma.GetSectorSize, @@ -275,3 +275,12 @@ func CollateralForPower(power types.BigInt) types.BigInt { return collateralRequired */ } + +func (sma StorageMinerActor) GetWorkerAddr(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { + var self StorageMinerActorState + state := vmctx.Storage().GetHead() + if err := vmctx.Storage().Get(state, &self); err != nil { + return nil, err + } + return self.Worker.Bytes(), nil +} diff --git a/chain/address/address.go b/chain/address/address.go index 362477148..2ebec4fd6 100644 --- a/chain/address/address.go +++ b/chain/address/address.go @@ -62,10 +62,15 @@ const ( Actor // BLS represents the address BLS protocol. BLS + + Unknown = Protocol(255) ) // Protocol returns the protocol used by the address. func (a Address) Protocol() Protocol { + if len(a.str) == 0 { + return Unknown + } return a.str[0] } diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 462918120..7239fc282 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -2,6 +2,7 @@ package state import ( "context" + "fmt" "github.com/ipfs/go-cid" hamt "github.com/ipfs/go-hamt-ipld" @@ -79,6 +80,10 @@ func (st *StateTree) lookupID(addr address.Address) (address.Address, error) { } func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) { + if addr == address.Undef { + return nil, fmt.Errorf("GetActor called on undefined address") + } + if addr.Protocol() != address.ID { iaddr, err := st.lookupID(addr) if err != nil { diff --git a/chain/types/bigint.go b/chain/types/bigint.go index 5e5b54dc5..23027c4ab 100644 --- a/chain/types/bigint.go +++ b/chain/types/bigint.go @@ -26,6 +26,8 @@ func init() { Complete()) } +var EmptyInt = BigInt{} + type BigInt struct { *big.Int } diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index c6cb3fc18..337ac1e89 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -153,6 +153,14 @@ func (w *Wallet) GenerateKey(typ string) (address.Address, error) { return k.Address, nil } +func (w *Wallet) HasKey(addr address.Address) (bool, error) { + k, err := w.findKey(addr) + if err != nil { + return false, err + } + return k != nil, nil +} + type Key struct { types.KeyInfo diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 0b15bb611..59e4a7ada 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -1,6 +1,7 @@ package main import ( + "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p-core/peer" "golang.org/x/xerrors" "gopkg.in/urfave/cli.v2" @@ -166,9 +167,16 @@ var initCmd = &cli.Command{ return err } - // TODO: persist this address in the storage-miner repo log.Infof("New storage miners address is: %s", addr) + ds, err := lr.Datastore("/metadata") + if err != nil { + return err + } + if err := ds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil { + return err + } + // TODO: Point to setting storage price, maybe do it interactively or something log.Info("Storage miner successfully created, you can now start it with 'lotus-storage-miner run'") diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 80df5015b..9a7f207b5 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -74,6 +74,7 @@ var runCmd = &cli.Command{ return lr.SetAPIEndpoint(apima) }), node.Override(new(*sectorbuilder.SectorBuilderConfig), modules.SectorBuilderConfig(storageRepoPath)), + node.Override(new(api.FullNode), func() api.FullNode { return nodeApi }), ) if err != nil { return err diff --git a/node/builder.go b/node/builder.go index 3167d1d5b..c41ea1e31 100644 --- a/node/builder.go +++ b/node/builder.go @@ -37,6 +37,7 @@ import ( "github.com/filecoin-project/go-lotus/node/modules/lp2p" "github.com/filecoin-project/go-lotus/node/modules/testing" "github.com/filecoin-project/go-lotus/node/repo" + "github.com/filecoin-project/go-lotus/storage" ) // special is a type used to give keys to modules which @@ -180,6 +181,9 @@ func Online() Option { libp2p(), + // common + Override(new(*wallet.Wallet), wallet.NewWallet), + // Full node ApplyIf(func(s *Settings) bool { return s.nodeType == nodeFull }, @@ -198,7 +202,6 @@ func Online() Option { // Filecoin services Override(new(*chain.Syncer), chain.NewSyncer), Override(new(*chain.BlockSync), chain.NewBlockSyncClient), - Override(new(*wallet.Wallet), wallet.NewWallet), Override(new(*chain.MessagePool), chain.NewMessagePool), Override(new(modules.Genesis), modules.ErrorGenesis), @@ -214,6 +217,7 @@ func Online() Option { // Storage miner ApplyIf(func(s *Settings) bool { return s.nodeType == nodeStorageMiner }, Override(new(*sectorbuilder.SectorBuilder), sectorbuilder.New), + Override(new(*storage.Miner), modules.StorageMiner), ), ) } diff --git a/node/impl/full.go b/node/impl/full.go index e08233248..67ae2d8a6 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -11,6 +11,7 @@ import ( "github.com/filecoin-project/go-lotus/chain/gen" "github.com/filecoin-project/go-lotus/chain/store" "github.com/filecoin-project/go-lotus/chain/types" + "github.com/filecoin-project/go-lotus/chain/vm" "github.com/filecoin-project/go-lotus/chain/wallet" "github.com/filecoin-project/go-lotus/miner" "github.com/filecoin-project/go-lotus/node/client" @@ -85,6 +86,32 @@ func (a *FullNodeAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) ([ return a.Chain.MessagesForBlock(b) } +func (a *FullNodeAPI) ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) { + hts := a.Chain.GetHeaviestTipSet() + state, err := a.Chain.TipSetState(hts.Cids()) + if err != nil { + return nil, err + } + + vmi, err := vm.NewVM(state, hts.Height(), hts.Blocks()[0].Miner, a.Chain) + if err != nil { + return nil, xerrors.Errorf("failed to set up vm: %w", err) + } + + if msg.GasLimit == types.EmptyInt { + msg.GasLimit = types.NewInt(10000000000) + } + if msg.GasPrice == types.EmptyInt { + msg.GasPrice = types.NewInt(0) + } + if msg.Value == types.EmptyInt { + msg.Value = types.NewInt(0) + } + + // TODO: maybe just use the invoker directly? + return vmi.ApplyMessage(ctx, msg) +} + func (a *FullNodeAPI) MpoolPending(ctx context.Context, ts *types.TipSet) ([]*types.SignedMessage, error) { // TODO: need to make sure we don't return messages that were already included in the referenced chain // also need to accept ts == nil just fine, assume nil == chain.Head() diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 013d04f04..3219f9943 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -8,12 +8,15 @@ import ( "github.com/filecoin-project/go-lotus/api" "github.com/filecoin-project/go-lotus/lib/sectorbuilder" + "github.com/filecoin-project/go-lotus/storage" ) type StorageMinerAPI struct { CommonAPI SectorBuilder *sectorbuilder.SectorBuilder + + Miner *storage.Miner } func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) (uint64, error) { diff --git a/node/modules/core.go b/node/modules/core.go index 96accfb74..33760fede 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -34,9 +34,11 @@ import ( "github.com/filecoin-project/go-lotus/chain/address" "github.com/filecoin-project/go-lotus/chain/store" "github.com/filecoin-project/go-lotus/chain/types" + "github.com/filecoin-project/go-lotus/chain/wallet" "github.com/filecoin-project/go-lotus/lib/sectorbuilder" "github.com/filecoin-project/go-lotus/node/modules/helpers" "github.com/filecoin-project/go-lotus/node/repo" + "github.com/filecoin-project/go-lotus/storage" ) var log = logging.Logger("modules") @@ -237,12 +239,55 @@ func SectorBuilderConfig(storagePath string) func() (*sectorbuilder.SectorBuilde return nil, err } - return §orbuilder.SectorBuilderConfig{ + sb := §orbuilder.SectorBuilderConfig{ Miner: minerAddr, SectorSize: 1024, MetadataDir: metadata, SealedDir: sealed, StagedDir: staging, - }, nil + } + + return sb, nil } } + +func SectorBuilder(lc fx.Lifecycle, sbc *sectorbuilder.SectorBuilderConfig) (*sectorbuilder.SectorBuilder, error) { + sb, err := sectorbuilder.New(sbc) + if err != nil { + return nil, err + } + + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + sb.Run(ctx) + return nil + }, + }) + + return sb, nil +} + +func StorageMiner(lc fx.Lifecycle, api api.FullNode, h host.Host, ds datastore.Batching, sb *sectorbuilder.SectorBuilder, w *wallet.Wallet) (*storage.Miner, error) { + maddrb, err := ds.Get(datastore.NewKey("miner-address")) + if err != nil { + return nil, err + } + + maddr, err := address.NewFromBytes(maddrb) + if err != nil { + return nil, err + } + + sm, err := storage.NewMiner(api, maddr, h, ds, sb, w) + if err != nil { + return nil, err + } + + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + return sm.Run(ctx) + }, + }) + + return sm, nil +} diff --git a/storage/miner.go b/storage/miner.go index 35c79c810..f9eeb125a 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -2,12 +2,14 @@ package storage import ( "context" + "fmt" "github.com/filecoin-project/go-lotus/api" "github.com/filecoin-project/go-lotus/chain/actors" "github.com/filecoin-project/go-lotus/chain/address" "github.com/filecoin-project/go-lotus/chain/store" "github.com/filecoin-project/go-lotus/chain/types" + "github.com/filecoin-project/go-lotus/chain/wallet" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" logging "github.com/ipfs/go-log" @@ -24,6 +26,8 @@ type Miner struct { sb *sectorbuilder.SectorBuilder + w *wallet.Wallet + maddr address.Address worker address.Address @@ -38,24 +42,23 @@ type storageMinerApi interface { //ReadState(ctx context.Context, addr address.Address) (????, error) // Call a read only method on actors (no interaction with the chain required) - CallMethod(ctx context.Context, addr address.Address, method uint64, params []byte) ([]byte, error) + ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) MpoolPush(context.Context, *types.SignedMessage) error MpoolGetNonce(context.Context, address.Address) (uint64, error) ChainWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) - ChainNotifs(context.Context) (<-chan *store.HeadChange, error) - - WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) + ChainNotify(context.Context) (<-chan *store.HeadChange, error) } -func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, sb *sectorbuilder.SectorBuilder) (*Miner, error) { +func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, sb *sectorbuilder.SectorBuilder, w *wallet.Wallet) (*Miner, error) { return &Miner{ api: api, maddr: addr, h: h, ds: ds, sb: sb, + w: w, }, nil } @@ -80,30 +83,36 @@ func (m *Miner) handlePostingSealedSectors(ctx context.Context) { return } + if err := m.commitSector(ctx, sinfo); err != nil { + log.Errorf("failed to commit sector: %s", err) + continue + } + case <-ctx.Done(): log.Warning("exiting seal posting routine") return } } } + func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSealingStatus) error { params := &actors.CommitSectorParams{ SectorId: types.NewInt(sinfo.SectorID), - CommD: sinfo.CommD, - CommR: sinfo.CommR, - CommRStar: sinfo.CommRStar, + CommD: sinfo.CommD[:], + CommR: sinfo.CommR[:], + CommRStar: sinfo.CommRStar[:], Proof: sinfo.Proof, } - enc, err := actors.SerializeParams(params) - if err != nil { - return errors.wrap(err, "could not serialize commit sector parameters") + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return errors.Wrap(aerr, "could not serialize commit sector parameters") } - msg := &types.Message{ + msg := types.Message{ To: m.maddr, From: m.worker, Method: actors.MAMethods.CommitSector, - Params: params, + Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(10000 /* i dont know help */), GasPrice: types.NewInt(1), @@ -121,14 +130,14 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal return errors.Wrap(err, "serializing commit sector message") } - sig, err := m.api.WalletSign(ctx, m.worker, data) + sig, err := m.w.Sign(m.worker, data) if err != nil { return errors.Wrap(err, "signing commit sector message") } smsg := &types.SignedMessage{ Message: msg, - Signature: sig, + Signature: *sig, } if err := m.api.MpoolPush(ctx, smsg); err != nil { @@ -136,6 +145,7 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal } m.trackCommitSectorMessage(smsg) + return nil } // make sure the message gets included in the chain successfully @@ -156,18 +166,35 @@ func (m *Miner) runPreflightChecks(ctx context.Context) error { m.worker = worker // try signing something with that key to make sure we can - if _, err := m.api.WalletSign(ctx, worker, []byte("sign me")); err != nil { - return errors.Wrap(err, "failed to verify ablity to sign with worker key") + has, err := m.w.HasKey(worker) + if err != nil { + return errors.Wrap(err, "failed to check wallet for worker key") } + if !has { + return errors.New("key for worker not found in local wallet") + } + + log.Infof("starting up miner %s, worker addr %s", m.maddr, m.worker) return nil } func (m *Miner) getWorkerAddr(ctx context.Context) (address.Address, error) { - ret, err := m.api.CallMethod(ctx, m.maddr, actors.MAMethods.GetWorkerAddr, actors.EmptyStructCBOR) + msg := &types.Message{ + To: m.maddr, + From: m.maddr, // it doesnt like it if we dont give it a from... probably should fix that + Method: actors.MAMethods.GetWorkerAddr, + Params: actors.EmptyStructCBOR, + } + + recpt, err := m.api.ChainCall(ctx, msg) if err != nil { return address.Undef, errors.Wrapf(err, "calling getWorker(%s)", m.maddr) } - return address.NewFromBytes(ret) + if recpt.ExitCode != 0 { + return address.Undef, fmt.Errorf("failed to call getWorker(%s): return %d", m.maddr, recpt.ExitCode) + } + + return address.NewFromBytes(recpt.Return) } From eb854467c84b61cd4500a7875376bf6a226750e3 Mon Sep 17 00:00:00 2001 From: Whyrusleeping Date: Tue, 30 Jul 2019 10:18:01 -0700 Subject: [PATCH 3/6] Update cmd/lotus-storage-miner/run.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Ɓukasz Magiera --- cmd/lotus-storage-miner/run.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 9a7f207b5..0e3d06932 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -74,7 +74,7 @@ var runCmd = &cli.Command{ return lr.SetAPIEndpoint(apima) }), node.Override(new(*sectorbuilder.SectorBuilderConfig), modules.SectorBuilderConfig(storageRepoPath)), - node.Override(new(api.FullNode), func() api.FullNode { return nodeApi }), + node.Override(new(api.FullNode), nodeApi), ) if err != nil { return err From d8bd222cb17b7fbc3d2374fee22bc19c59ba6906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 31 Jul 2019 18:54:28 +0200 Subject: [PATCH 4/6] Optional tipset param for ChainCall --- api/api.go | 4 +++- api/struct.go | 20 ++++++++++---------- node/impl/full.go | 10 ++++++---- storage/miner.go | 4 ++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/api/api.go b/api/api.go index 8fcaadc5f..d99cfab0a 100644 --- a/api/api.go +++ b/api/api.go @@ -73,7 +73,9 @@ type FullNode interface { ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error) ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) ChainGetBlockMessages(context.Context, cid.Cid) ([]*types.SignedMessage, error) - ChainCall(context.Context, *types.Message) (*types.MessageReceipt, error) + + // if tipset is nil, we'll use heaviest + ChainCall(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) // messages diff --git a/api/struct.go b/api/struct.go index b33701b8e..321376376 100644 --- a/api/struct.go +++ b/api/struct.go @@ -39,14 +39,14 @@ type FullNodeStruct struct { CommonStruct Internal struct { - ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"` - ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"` - ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` - ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"` - 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) ([]*types.SignedMessage, error) `perm:"read"` - ChainCall func(context.Context, *types.Message) (*types.MessageReceipt, error) `perm:"read"` + ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"` + ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"` + ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` + ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"` + 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) ([]*types.SignedMessage, 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"` MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"` @@ -156,8 +156,8 @@ func (c *FullNodeStruct) ChainWaitMsg(ctx context.Context, msgc cid.Cid) (*MsgWa return c.Internal.ChainWaitMsg(ctx, msgc) } -func (c *FullNodeStruct) ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) { - return c.Internal.ChainCall(ctx, msg) +func (c *FullNodeStruct) ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) { + return c.Internal.ChainCall(ctx, msg, ts) } func (c *FullNodeStruct) WalletNew(ctx context.Context, typ string) (address.Address, error) { diff --git a/node/impl/full.go b/node/impl/full.go index 67ae2d8a6..9afd68e0e 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -86,14 +86,16 @@ func (a *FullNodeAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) ([ return a.Chain.MessagesForBlock(b) } -func (a *FullNodeAPI) ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) { - hts := a.Chain.GetHeaviestTipSet() - state, err := a.Chain.TipSetState(hts.Cids()) +func (a *FullNodeAPI) ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) { + if ts == nil { + ts = a.Chain.GetHeaviestTipSet() + } + state, err := a.Chain.TipSetState(ts.Cids()) if err != nil { return nil, err } - vmi, err := vm.NewVM(state, hts.Height(), hts.Blocks()[0].Miner, a.Chain) + vmi, err := vm.NewVM(state, ts.Height(), ts.Blocks()[0].Miner, a.Chain) if err != nil { return nil, xerrors.Errorf("failed to set up vm: %w", err) } diff --git a/storage/miner.go b/storage/miner.go index f9eeb125a..2d99afa17 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -42,7 +42,7 @@ type storageMinerApi interface { //ReadState(ctx context.Context, addr address.Address) (????, error) // Call a read only method on actors (no interaction with the chain required) - ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) + ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) MpoolPush(context.Context, *types.SignedMessage) error MpoolGetNonce(context.Context, address.Address) (uint64, error) @@ -187,7 +187,7 @@ func (m *Miner) getWorkerAddr(ctx context.Context) (address.Address, error) { Params: actors.EmptyStructCBOR, } - recpt, err := m.api.ChainCall(ctx, msg) + recpt, err := m.api.ChainCall(ctx, msg, nil) if err != nil { return address.Undef, errors.Wrapf(err, "calling getWorker(%s)", m.maddr) } From a968eef32269b247b22b9e3cb32b419628a6e3a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 31 Jul 2019 18:58:19 +0200 Subject: [PATCH 5/6] wallet: filter repo.ErrKeyNotFound --- chain/wallet/wallet.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index 337ac1e89..a94ba69ef 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -5,6 +5,8 @@ import ( "strings" "github.com/filecoin-project/go-bls-sigs" + "github.com/filecoin-project/go-lotus/node/repo" + "github.com/minio/blake2b-simd" "golang.org/x/xerrors" @@ -71,6 +73,9 @@ func (w *Wallet) findKey(addr address.Address) (*Key, error) { } ki, err := w.keystore.Get(KNamePrefix + addr.String()) if err != nil { + if xerrors.Is(err, repo.ErrKeyNotFound) { + return nil, nil + } return nil, xerrors.Errorf("getting from keystore: %w", err) } k, err = NewKey(ki) From 006fbe556f2aaa7646bba2a1b29e0f0fa90213d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 31 Jul 2019 19:01:04 +0200 Subject: [PATCH 6/6] Use correct ctx for SectorBuilder/Miner --- node/modules/core.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/node/modules/core.go b/node/modules/core.go index 33760fede..0ddae1224 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -251,14 +251,16 @@ func SectorBuilderConfig(storagePath string) func() (*sectorbuilder.SectorBuilde } } -func SectorBuilder(lc fx.Lifecycle, sbc *sectorbuilder.SectorBuilderConfig) (*sectorbuilder.SectorBuilder, error) { +func SectorBuilder(mctx helpers.MetricsCtx, lc fx.Lifecycle, sbc *sectorbuilder.SectorBuilderConfig) (*sectorbuilder.SectorBuilder, error) { sb, err := sectorbuilder.New(sbc) if err != nil { return nil, err } + ctx := helpers.LifecycleCtx(mctx, lc) + lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { + OnStart: func(context.Context) error { sb.Run(ctx) return nil }, @@ -267,7 +269,7 @@ func SectorBuilder(lc fx.Lifecycle, sbc *sectorbuilder.SectorBuilderConfig) (*se return sb, nil } -func StorageMiner(lc fx.Lifecycle, api api.FullNode, h host.Host, ds datastore.Batching, sb *sectorbuilder.SectorBuilder, w *wallet.Wallet) (*storage.Miner, error) { +func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h host.Host, ds datastore.Batching, sb *sectorbuilder.SectorBuilder, w *wallet.Wallet) (*storage.Miner, error) { maddrb, err := ds.Get(datastore.NewKey("miner-address")) if err != nil { return nil, err @@ -283,8 +285,10 @@ func StorageMiner(lc fx.Lifecycle, api api.FullNode, h host.Host, ds datastore.B return nil, err } + ctx := helpers.LifecycleCtx(mctx, lc) + lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { + OnStart: func(context.Context) error { return sm.Run(ctx) }, })