From 7c15d1e8c3104f6855adb6d09e768af022566b2d Mon Sep 17 00:00:00 2001 From: lijunlong Date: Sat, 28 Mar 2020 12:31:16 +0800 Subject: [PATCH 001/379] add bench mark for bls sign and verify --- lib/sigs/bls/bls_bench_test.go | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/sigs/bls/bls_bench_test.go diff --git a/lib/sigs/bls/bls_bench_test.go b/lib/sigs/bls/bls_bench_test.go new file mode 100644 index 000000000..883d1bd15 --- /dev/null +++ b/lib/sigs/bls/bls_bench_test.go @@ -0,0 +1,58 @@ +package bls + +import ( + "crypto/rand" + "github.com/filecoin-project/go-address" + "testing" +) + +func Benchmark_blsSigner_Sign(b *testing.B) { + signer := blsSigner{} + b.ResetTimer() + for i:=0;i Date: Wed, 1 Apr 2020 09:41:26 +0800 Subject: [PATCH 002/379] simplify code --- lib/sigs/bls/bls_bench_test.go | 52 +++++++++++----------------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/lib/sigs/bls/bls_bench_test.go b/lib/sigs/bls/bls_bench_test.go index 883d1bd15..a6c033912 100644 --- a/lib/sigs/bls/bls_bench_test.go +++ b/lib/sigs/bls/bls_bench_test.go @@ -6,53 +6,33 @@ import ( "testing" ) -func Benchmark_blsSigner_Sign(b *testing.B) { +func BenchmarkBLSSign(b *testing.B) { signer := blsSigner{} - b.ResetTimer() - for i:=0;i Date: Tue, 26 May 2020 19:55:16 +0200 Subject: [PATCH 003/379] Set devnet params --- build/params_shared.go | 2 +- build/params_testnet.go | 7 ++++--- build/version.go | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build/params_shared.go b/build/params_shared.go index 2b2f3e985..550afc928 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -118,7 +118,7 @@ const VerifSigCacheSize = 32000 // TODO: If this is gonna stay, it should move to specs-actors const BlockMessageLimit = 512 -const BlockGasLimit = 100_000_000 +const BlockGasLimit = 100_000_000_000 var DrandCoeffs = []string{ "82c279cce744450e68de98ee08f9698a01dd38f8e3be3c53f2b840fb9d09ad62a0b6b87981e179e1b14bc9a2d284c985", diff --git a/build/params_testnet.go b/build/params_testnet.go index 5d5e6b81f..917b8059e 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -12,10 +12,11 @@ import ( ) func init() { - power.ConsensusMinerMinPower = big.NewInt(1024 << 30) + power.ConsensusMinerMinPower = big.NewInt(1024 << 20) miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG32GiBSeal: {}, - abi.RegisteredProof_StackedDRG64GiBSeal: {}, + abi.RegisteredProof_StackedDRG512MiBSeal: {}, + abi.RegisteredProof_StackedDRG32GiBSeal: {}, + abi.RegisteredProof_StackedDRG64GiBSeal: {}, } } diff --git a/build/version.go b/build/version.go index b704f2e80..c5d96e9af 100644 --- a/build/version.go +++ b/build/version.go @@ -5,7 +5,7 @@ import "fmt" var CurrentCommit string // BuildVersion is the local build version, set by build system -const BuildVersion = "0.3.0" +const BuildVersion = "0.4.0" var UserVersion = BuildVersion + CurrentCommit From b06b0147a90230c6dfb9b83a29b671fa8efcc546 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 22 May 2020 16:07:38 +0200 Subject: [PATCH 004/379] Switch to new drand client This is a preview of a change to new drand client. Signed-off-by: Jakub Sztandera --- build/params_shared.go | 7 +- chain/beacon/drand/drand.go | 152 +++++----------- chain/beacon/drand/drand_test.go | 22 ++- chain/gen/gen.go | 4 + go.mod | 11 +- go.sum | 290 ++++++++++++++++++++++++------- 6 files changed, 295 insertions(+), 191 deletions(-) diff --git a/build/params_shared.go b/build/params_shared.go index 2b2f3e985..7de5a11d0 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -120,9 +120,4 @@ const VerifSigCacheSize = 32000 const BlockMessageLimit = 512 const BlockGasLimit = 100_000_000 -var DrandCoeffs = []string{ - "82c279cce744450e68de98ee08f9698a01dd38f8e3be3c53f2b840fb9d09ad62a0b6b87981e179e1b14bc9a2d284c985", - "82d51308ad346c686f81b8094551597d7b963295cbf313401a93df9baf52d5ae98a87745bee70839a4d6e65c342bd15b", - "94eebfd53f4ba6a3b8304236400a12e73885e5a781509a5c8d41d2e8b476923d8ea6052649b3c17282f596217f96c5de", - "8dc4231e42b4edf39e86ef1579401692480647918275da767d3e558c520d6375ad953530610fd27daf110187877a65d0", -} +var DrandChain = `{"public_key":"kiouk4KP+DNFuuUz9RcmaaJsAtx21r9ZyAiS4SqxRVwikhGIbzW7Vq9tW+qYECTf","period":25,"genesis_time":1590445175,"hash":"E4oySqZUD5PQ2tACqolFSxvsK26UhoLN5r1NtA9LfJs="}` diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 94ee2a28d..39c185ee7 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -1,11 +1,12 @@ package drand import ( + "bytes" "context" - "math/rand" "sync" "time" + "github.com/drand/kyber" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/types" @@ -14,32 +15,26 @@ import ( logging "github.com/ipfs/go-log" - dbeacon "github.com/drand/drand/beacon" - "github.com/drand/drand/core" - dkey "github.com/drand/drand/key" - dnet "github.com/drand/drand/net" - dproto "github.com/drand/drand/protobuf/drand" + dchain "github.com/drand/drand/chain" + dclient "github.com/drand/drand/client" ) var log = logging.Logger("drand") var drandServers = []string{ - "nicolas.drand.fil-test.net:443", - "philipp.drand.fil-test.net:443", - "mathilde.drand.fil-test.net:443", - "ludovic.drand.fil-test.net:443", - "gabbi.drand.fil-test.net:443", - "linus.drand.fil-test.net:443", - "jeff.drand.fil-test.net:443", + "https://pl-eu.testnet.drand.sh", + "https://pl-us.testnet.drand.sh", + "https://pl-sin.testnet.drand.sh", } -var drandPubKey *dkey.DistPublic +var drandChain *dchain.Info func init() { - drandPubKey = new(dkey.DistPublic) - err := drandPubKey.FromTOML(&dkey.DistPublicTOML{Coefficients: build.DrandCoeffs}) + + var err error + drandChain, err = dchain.InfoFromJSON(bytes.NewReader([]byte(build.DrandChain))) if err != nil { - panic(err) + panic("could not unmarshal chain info: " + err.Error()) } } @@ -57,13 +52,9 @@ func (dp *drandPeer) IsTLS() bool { } type DrandBeacon struct { - client dnet.Client + client dclient.Client - peers []dnet.Peer - peersIndex int - peersIndexMtx sync.Mutex - - pubkey *dkey.DistPublic + pubkey kyber.Point // seconds interval time.Duration @@ -80,107 +71,50 @@ func NewDrandBeacon(genesisTs, interval uint64) (*DrandBeacon, error) { if genesisTs == 0 { panic("what are you doing this cant be zero") } + client, err := dclient.New( + dclient.WithHTTPEndpoints(drandServers), + dclient.WithChainInfo(drandChain), + dclient.WithCacheSize(1024), + ) + if err != nil { + return nil, xerrors.Errorf("creating drand client") + } + db := &DrandBeacon{ - client: dnet.NewGrpcClient(), + client: client, localCache: make(map[uint64]types.BeaconEntry), } - for _, ds := range drandServers { - db.peers = append(db.peers, &drandPeer{addr: ds, tls: true}) - } - db.peersIndex = rand.Intn(len(db.peers)) - - groupResp, err := db.client.Group(context.TODO(), db.peers[db.peersIndex], &dproto.GroupRequest{}) - if err != nil { - return nil, xerrors.Errorf("failed to get group response from beacon peer: %w", err) - } - - kgroup, err := core.ProtoToGroup(groupResp) - if err != nil { - return nil, xerrors.Errorf("failed to parse group response: %w", err) - } - - // TODO: verify these values are what we expect them to be - if !kgroup.PublicKey.Equal(drandPubKey) { - return nil, xerrors.Errorf("public key does not match") - } - // fmt.Printf("Drand Pubkey:\n%#v\n", kgroup.PublicKey.TOML()) // use to print public key - db.pubkey = drandPubKey - db.interval = kgroup.Period - db.drandGenTime = uint64(kgroup.GenesisTime) + db.pubkey = drandChain.PublicKey + db.interval = drandChain.Period + db.drandGenTime = uint64(drandChain.GenesisTime) db.filRoundTime = interval db.filGenTime = genesisTs - // TODO: the stream currently gives you back *all* values since drand genesis. - // Having the stream in the background is merely an optimization, so not a big deal to disable it for now - // go db.handleStreamingUpdates() - return db, nil } -func (db *DrandBeacon) rotatePeersIndex() { - db.peersIndexMtx.Lock() - nval := rand.Intn(len(db.peers)) - db.peersIndex = nval - db.peersIndexMtx.Unlock() - - log.Warnf("rotated to drand peer %d, %q", nval, db.peers[nval].Address()) -} - -func (db *DrandBeacon) getPeerIndex() int { - db.peersIndexMtx.Lock() - defer db.peersIndexMtx.Unlock() - return db.peersIndex -} - -func (db *DrandBeacon) handleStreamingUpdates() { - for { - p := db.peers[db.getPeerIndex()] - ch, err := db.client.PublicRandStream(context.Background(), p, &dproto.PublicRandRequest{}) - if err != nil { - log.Warnf("failed to get public rand stream to peer %q: %s", p.Address(), err) - log.Warnf("trying again in 10 seconds") - db.rotatePeersIndex() - time.Sleep(time.Second * 10) - continue - } - - for e := range ch { - db.cacheValue(types.BeaconEntry{ - Round: e.Round, - Data: e.Signature, - }) - } - - log.Warnf("drand beacon stream to peer %q broke, reconnecting in 10 seconds", p.Address()) - db.rotatePeersIndex() - time.Sleep(time.Second * 10) - } -} - func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Response { - // check cache, it it if there, otherwise query the endpoint - cres := db.getCachedValue(round) - if cres != nil { - out := make(chan beacon.Response, 1) - out <- beacon.Response{Entry: *cres} - close(out) - return out - } - out := make(chan beacon.Response, 1) + if round != 0 { + be := db.getCachedValue(round) + if be != nil { + out <- beacon.Response{Entry: *be} + close(out) + return out + } + } go func() { - p := db.peers[db.getPeerIndex()] - resp, err := db.client.PublicRand(ctx, p, &dproto.PublicRandRequest{Round: round}) + log.Warnw("fetching randomness", "round", round) + resp, err := db.client.Get(ctx, round) var br beacon.Response if err != nil { - db.rotatePeersIndex() - br.Err = xerrors.Errorf("drand peer %q failed publicRand request: %w", p.Address(), err) + br.Err = xerrors.Errorf("drand failed Get request: %w", err) } else { - br.Entry.Round = resp.GetRound() - br.Entry.Data = resp.GetSignature() + br.Entry.Round = resp.Round() + br.Entry.Data = resp.Signature() } out <- br @@ -189,7 +123,6 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re return out } - func (db *DrandBeacon) cacheValue(e types.BeaconEntry) { db.cacheLk.Lock() defer db.cacheLk.Unlock() @@ -211,13 +144,12 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr // TODO handle genesis better return nil } - b := &dbeacon.Beacon{ + b := &dchain.Beacon{ PreviousSig: prev.Data, Round: curr.Round, Signature: curr.Data, } - //log.Warnw("VerifyEntry", "beacon", b) - err := dbeacon.VerifyBeacon(db.pubkey.Key(), b) + err := dchain.VerifyBeacon(db.pubkey, b) if err == nil { db.cacheValue(curr) } diff --git a/chain/beacon/drand/drand_test.go b/chain/beacon/drand/drand_test.go index 2055597bd..b8b089732 100644 --- a/chain/beacon/drand/drand_test.go +++ b/chain/beacon/drand/drand_test.go @@ -1,14 +1,24 @@ package drand import ( + "encoding/json" "fmt" "testing" + + dchain "github.com/drand/drand/chain" + dclient "github.com/drand/drand/client" + "github.com/stretchr/testify/assert" ) -func TestPrintDrandPubkey(t *testing.T) { - bc, err := NewDrandBeacon(1, 1) - if err != nil { - t.Fatal(err) - } - fmt.Printf("Drand Pubkey:\n%#v\n", bc.pubkey.TOML()) +func TestPrintGroupInfo(t *testing.T) { + c, err := dclient.NewHTTPClient(drandServers[0], nil, nil) + assert.NoError(t, err) + cg := c.(interface { + FetchChainInfo(groupHash []byte) (*dchain.Info, error) + }) + chain, err := cg.FetchChainInfo(nil) + assert.NoError(t, err) + cbytes, err := json.Marshal(chain.ToProto()) + assert.NoError(t, err) + fmt.Printf("%s\n", cbytes) } diff --git a/chain/gen/gen.go b/chain/gen/gen.go index c9ebebcef..b0c4cc044 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -219,6 +219,10 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { miners := []address.Address{maddr1, maddr2} beac := beacon.NewMockBeacon(time.Second) + //beac, err := drand.NewDrandBeacon(tpl.Timestamp, build.BlockDelay) + //if err != nil { + //return nil, xerrors.Errorf("creating drand beacon: %w", err) + //} gen := &ChainGen{ bs: bs, diff --git a/go.mod b/go.mod index 7b04d39be..3a4912c92 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,8 @@ require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/coreos/go-systemd/v22 v22.0.0 github.com/docker/go-units v0.4.0 - github.com/drand/drand v0.8.2-0.20200518165838-d61135e6e2c8 + github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e + github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 github.com/filecoin-project/chain-validation v0.0.6-0.20200518190139-483332336e8e github.com/filecoin-project/filecoin-ffi v0.0.0-20200427223233-a0014b17f124 @@ -39,7 +40,7 @@ require ( github.com/gorilla/websocket v1.4.2 github.com/hashicorp/go-multierror v1.1.0 github.com/hashicorp/golang-lru v0.5.4 - github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e + github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/ipfs/go-bitswap v0.2.8 github.com/ipfs/go-block-format v0.0.2 github.com/ipfs/go-blockservice v0.1.3 @@ -61,7 +62,7 @@ require ( github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf github.com/ipfs/go-ipld-format v0.2.0 github.com/ipfs/go-log v1.0.4 - github.com/ipfs/go-log/v2 v2.0.8 + github.com/ipfs/go-log/v2 v2.1.0 github.com/ipfs/go-merkledag v0.3.1 github.com/ipfs/go-path v0.0.7 github.com/ipfs/go-unixfs v0.2.4 @@ -109,7 +110,7 @@ require ( go.uber.org/zap v1.15.0 go4.org v0.0.0-20190313082347-94abd6928b1d // indirect golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 - golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 + golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 gotest.tools v2.2.0+incompatible @@ -119,5 +120,3 @@ require ( replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi - -replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0 diff --git a/go.sum b/go.sum index b407f56ba..155a60127 100644 --- a/go.sum +++ b/go.sum @@ -10,12 +10,12 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee h1:8doiS7ib3zi6/K172oDhSKU0dJ/miJramo9NITOMyZQ= github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee/go.mod h1:W0GbEAA4uFNYOGG2cJpmFJ04E6SD1NLELPYZB57/7AY= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -26,23 +26,36 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrU github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3oM7gXIttpYDAJXpVNnSCiUMYBLIZ6cb1t+Ip982MRo= github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 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/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= -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/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= github.com/benbjohnson/clock v1.0.1 h1:lVM1R/o5khtrr7t3qAr+sS6uagZOP+7iprc7gS3V9CE= github.com/benbjohnson/clock v1.0.1/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= 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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 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/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= @@ -57,6 +70,8 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -64,23 +79,31 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY= @@ -93,8 +116,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc= github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= -github.com/dchest/blake2b v1.0.0 h1:KK9LimVmE0MjRl9095XJmKqZ+iLxWATvlcpVFRtaw6s= -github.com/dchest/blake2b v1.0.0/go.mod h1:U034kXgbJpCle2wSk5ybGIVhOSHCVLMDqOzcPEA0F7s= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -105,6 +126,7 @@ github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32y github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -112,24 +134,31 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE= github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= -github.com/drand/drand v0.8.2-0.20200518165838-d61135e6e2c8 h1:i5Dh4bklVI1mRLflpOJa5igk6xdPJWgZAe8iesZSs0o= -github.com/drand/drand v0.8.2-0.20200518165838-d61135e6e2c8/go.mod h1:ZdzIrSqqEYZvMiS1UuZlJs3WTb9uLz1I9uH0icYPqoE= +github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e h1:e9JEgW+3GaPAqskYoEtL98HueHmUskO5tsRqmPs1ZxE= +github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e/go.mod h1:xRGkp/+RCz/BWvF1KjaH2AGJ81hrGFqA6Uml1k1zNto= github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= -github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99 h1:BxLbcT0yq9ii6ShXn7U+0oXB2ABfEfw6GutaVPxoj2Y= -github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99/go.mod h1:Rzu9PGFt3q8d7WWdrHmR8dktHucO0dSTWlMYrgqjSpA= +github.com/drand/kyber v1.0.2 h1:dHjtWJZJdn3zBBZ9pqLsLfcR9ScvDvSqzS1sWA8seao= +github.com/drand/kyber v1.0.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elastic/go-sysinfo v1.3.0 h1:eb2XFGTMlSwG/yyU9Y8jVAYLIzU2sFzWXwo2gmetyrE= github.com/elastic/go-sysinfo v1.3.0/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= github.com/elastic/go-windows v1.0.0 h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY= github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= +github.com/ema/qdisc v0.0.0-20190904071900-b82c76788043/go.mod h1:ix4kG2zvdUd8kEKSW0ZTr1XLks0epFpI4j745DXxlNE= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= @@ -176,6 +205,7 @@ github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= +github.com/filecoin-project/specs-actors v0.4.1-0.20200509020627-3c96f54f3d7d/go.mod h1:UW3ft23q6VS8wQoNqLWjENsu9gu1uh6lxOd+H8cwhT8= github.com/filecoin-project/specs-actors v0.5.2/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461 h1:yyAoJ9dNboljDWj0uBdJEbdaTak/YhkjYUQt0GzlY0A= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= @@ -183,6 +213,8 @@ github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1: github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= github.com/filecoin-project/storage-fsm v0.0.0-20200522010518-83fd743db8bc h1:6du9HB53x8frk+Cky9ymGYsRbvXZDE91EsaOJoCb5Ok= github.com/filecoin-project/storage-fsm v0.0.0-20200522010518-83fd743db8bc/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0= @@ -190,28 +222,37 @@ github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1/go.mod h1:0eHX/BVySxPc6SE2mZRoppGq7qcE github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 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-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= 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-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968 h1:s+PDl6lozQ+dEUtUtQnO7+A2iPG3sK1pI4liU+jxn90= +github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= 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= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/gogo/status v1.0.3 h1:WkVBY59mw7qUNTr/bLwO7J2vesJ0rQ2C3tMXrTd3w5M= +github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -225,6 +266,8 @@ github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgj github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -234,6 +277,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -241,16 +285,23 @@ github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY= github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= @@ -261,26 +312,44 @@ github.com/hannahhoward/cbor-gen-for v0.0.0-20191218204337-9ab7b1bcc099 h1:vQqOW github.com/hannahhoward/cbor-gen-for v0.0.0-20191218204337-9ab7b1bcc099/go.mod h1:WVPCl0HO/0RAL5+vBH2GMxBomlxBF70MAS78+Lu1//k= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hodgesds/perf-utils v0.0.8/go.mod h1:F6TfvsbtrF88i++hou29dTXlI2sfsJv+gRZDtmTJkAs= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e h1:txQltCyjXAqVVSZDArPEhUTg35hKwVIuXwtQo7eAMNQ= -github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= @@ -406,10 +475,10 @@ github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kP github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -github.com/ipfs/go-log/v2 v2.0.5 h1:fL4YI+1g5V/b1Yxr1qAiXTMg1H8z9vx/VmJxBuQMHvU= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= -github.com/ipfs/go-log/v2 v2.0.8 h1:3b3YNopMHlj4AvyhWAx0pDxqSQWYi4/WuWO7yRV6/Qg= github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/ipfs/go-log/v2 v2.1.0 h1:7l5yjP7aLl5xr7RmqEvPZy9Skq7PP2fIP0Pa7lU/UII= +github.com/ipfs/go-log/v2 v2.1.0/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= @@ -465,15 +534,20 @@ github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1 h1:qBCV/RLV02TSfQa7tFmxTihnG+u+7JXByOkhlkR5rmQ= github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= +github.com/jsimonetti/rtnetlink v0.0.0-20190830100107-3784a6c7c552/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= +github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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= @@ -486,6 +560,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d h1:68u9r4wEvL3gYg2jvAOgROwZ3H+Y3hIDk4tbbmIjcYQ= @@ -499,7 +574,6 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-addr-util v0.0.2 h1:7cWK5cdA5x72jX0g8iLrQWm5TRJZ6CzGdPEhWj7plWU= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= @@ -509,7 +583,6 @@ github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoR github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= -github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= @@ -530,7 +603,6 @@ github.com/libp2p/go-libp2p v0.6.0/go.mod h1:mfKWI7Soz3ABX+XEBR61lGbg+ewyMtJHVt0 github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= -github.com/libp2p/go-libp2p v0.8.1 h1:6AK178W4GmfGxV+L51bd54/fSWEjNR+S0DO0odk/CwI= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM= github.com/libp2p/go-libp2p v0.9.2 h1:5rViLwtjkaEWcIBbk6oII39cVjPTElo3F78SSLf9yho= @@ -541,7 +613,6 @@ github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3Pt github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= -github.com/libp2p/go-libp2p-autonat v0.2.2 h1:4dlgcEEugTFWSvdG2UIFxhnOMpX76QaZSRAtXmYB8n4= github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.2.3 h1:w46bKK3KTOUWDe5mDYMRjJu1uryqBp8HCNDp/TWMqKw= github.com/libp2p/go-libp2p-autonat v0.2.3/go.mod h1:2U6bNWCNsAG9LEbwccBDQbjzQ8Krdjge1jLTE9rdoMM= @@ -549,7 +620,6 @@ github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6 github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg= -github.com/libp2p/go-libp2p-blankhost v0.1.4 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= github.com/libp2p/go-libp2p-blankhost v0.1.6 h1:CkPp1/zaCrCnBo0AdsQA0O1VkUYoUOtyHOnoa8gKIcE= github.com/libp2p/go-libp2p-blankhost v0.1.6/go.mod h1:jONCAJqEP+Z8T6EQviGL4JsQcLx1LgTGtVqFNY8EMfQ= @@ -559,11 +629,9 @@ github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFk github.com/libp2p/go-libp2p-circuit v0.1.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM= github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= -github.com/libp2p/go-libp2p-circuit v0.2.1 h1:BDiBcQxX/ZJJ/yDl3sqZt1bjj4PkZCEi7IEpwxXr13k= github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= github.com/libp2p/go-libp2p-circuit v0.2.2 h1:87RLabJ9lrhoiSDDZyCJ80ZlI5TLJMwfyoGAaWXzWqA= github.com/libp2p/go-libp2p-circuit v0.2.2/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4= -github.com/libp2p/go-libp2p-connmgr v0.1.1 h1:BIul1BPoN1vPAByMh6CeD33NpGjD+PkavmUjTS7uai8= github.com/libp2p/go-libp2p-connmgr v0.1.1/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= github.com/libp2p/go-libp2p-connmgr v0.2.3 h1:v7skKI9n+0obPpzMIO6aIlOSdQOmhxTf40cbpzqaGMQ= github.com/libp2p/go-libp2p-connmgr v0.2.3/go.mod h1:Gqjg29zI8CwXX21zRxy6gOg8VYu3zVerJRt2KyktzH4= @@ -583,7 +651,6 @@ github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZas github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.2/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.3 h1:b9W3w7AZR2n/YJhG8d0qPFGhGhCWKIvPuJgp4hhc4MM= github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= @@ -645,7 +712,6 @@ github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVd github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -github.com/libp2p/go-libp2p-peerstore v0.2.3 h1:MofRq2l3c15vQpEygTetV+zRRrncz+ktiXW7H2EKoEQ= github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= github.com/libp2p/go-libp2p-peerstore v0.2.4 h1:jU9S4jYN30kdzTpDAR7SlHUD+meDUjTODh4waLWF1ws= github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= @@ -679,7 +745,6 @@ github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= github.com/libp2p/go-libp2p-swarm v0.2.1/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU= github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= -github.com/libp2p/go-libp2p-swarm v0.2.3 h1:uVkCb8Blfg7HQ/f30TyHn1g/uCwXsAET7pU0U59gx/A= github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= github.com/libp2p/go-libp2p-swarm v0.2.4 h1:94XL76/tFeTdJNcIGugi+1uZo5O/a7y4i21PirwbgZI= github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h/GGZes8Wku/M5Y= @@ -698,7 +763,6 @@ github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwq github.com/libp2p/go-libp2p-transport-upgrader v0.0.1/go.mod h1:NJpUAgQab/8K6K0m+JmZCe5RUXG10UMEx4kWe9Ipj5c= github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= -github.com/libp2p/go-libp2p-transport-upgrader v0.2.0 h1:5EhPgQhXZNyfL22ERZTUoVp9UVVbNowWNVtELQaKCHk= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0 h1:q3ULhsknEQ34eVDhv4YwKS8iet69ffs9+Fir6a7weN4= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= @@ -734,7 +798,6 @@ github.com/libp2p/go-netroute v0.1.2 h1:UHhB35chwgvcRI392znJA3RCBtZ3MpE3ahNCN5MR github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.5 h1:pQkejVhF0xp08D4CQUcw8t+BFJeXowja6RVcb5p++EA= github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= @@ -744,14 +807,12 @@ github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA2 github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= github.com/libp2p/go-reuseport-transport v0.0.3 h1:zzOeXnTooCkRvoH+bSXEfXhn76+LAiwoneM0gnXjF2M= github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= -github.com/libp2p/go-sockaddr v0.0.2 h1:tCuXfpA9rq7llM/v834RKc/Xvovy/AqM9kHvTV/jY/Q= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= -github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY= github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= @@ -768,7 +829,6 @@ github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9t github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= -github.com/libp2p/go-ws-transport v0.3.0 h1:mjo6pL5aVR9rCjl9wNq3DupbaQlyR61pzoOT2MdtxaA= github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= github.com/libp2p/go-ws-transport v0.3.1 h1:ZX5rWB8nhRRJVaPO6tmkGI/Xx8XNboYX20PW5hXIscw= github.com/libp2p/go-ws-transport v0.3.1/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= @@ -777,12 +837,15 @@ github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZ github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.5 h1:ibuz4naPAully0pN6J/kmUARiqLpnDQIzI/8GCOrljg= github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.3.6 h1:O5qcBXRcfqecvQ/My9NqDNHB3/5t58yuJYqthcKhhgE= github.com/libp2p/go-yamux v1.3.6/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2 h1:Mop0ac3zALaBR3wGs6j8OYe/tcFvFsxTUFMkE/7yUOI= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= +github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA= @@ -796,15 +859,23 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= +github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= +github.com/mdlayher/netlink v0.0.0-20190828143259-340058475d09/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= +github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= +github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY= +github.com/mdlayher/wifi v0.0.0-20190303161829-b1436901ddee/go.mod h1:Evt/EIne46u9PtQbeTx2NTcqURpr5K4SvKtGmBuDPN8= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= @@ -816,8 +887,14 @@ github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 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/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -836,7 +913,6 @@ github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.2.1 h1:SgG/cw5vqyB5QQe5FPe2TqggU9WtrA9X4nZw7LlVqOI= github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= github.com/multiformats/go-multiaddr v0.2.2 h1:XZLDTszBIJe6m0zF6ITBrEcZR73OPUhCBBS9rYAuUzI= github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= @@ -857,7 +933,6 @@ github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysj github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= github.com/multiformats/go-multiaddr-net v0.1.5 h1:QoRKvu0xHN1FCFJcMQLbG/yQE2z441L5urvG3+qyz7g= github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.2 h1:2pAgScmS1g9XjH7EtAfNhTuyrWYEWcxy0G5Wo85hWDA= github.com/multiformats/go-multibase v0.0.2/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= @@ -879,12 +954,19 @@ github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= -github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e h1:07zdEcJ4Fble5uWsqKpjW19699kQWRLXP+RZh1a6ZRg= -github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e/go.mod h1:79GLCU4P87rYvYYACbNwVyc1WmRvkwQbYnybpCmRXzg= -github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -895,16 +977,32 @@ github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q= +github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9 h1:QsgXACQhd9QJhEmRumbsMQQvBtmdS0mafoVEBplWXEg= +github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= @@ -912,34 +1010,42 @@ github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a h1:hjZfReYVLbqFkAtr2us7vdy04YWz3LVAirzP7reh8+M= github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= 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_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= 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/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 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/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/node_exporter v1.0.0-rc.0.0.20200428091818-01054558c289/go.mod h1:FGbBv5OPKjch+jNUJmEQpMZytIdyW0NdBtWFcfSKusc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/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.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= @@ -948,11 +1054,19 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sercand/kuberesolver v2.1.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ= +github.com/sercand/kuberesolver v2.4.0+incompatible h1:WE2OlRf6wjLxHwNkkFLQGaZcVLEXjMjBPjjEU5vksH8= +github.com/sercand/kuberesolver v2.4.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ= github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM= github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745/go.mod h1:G81aIFAMS9ECrwBYR9YxhlPjWgrItd+Kje78O6+uqm8= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -960,11 +1074,13 @@ github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHei github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a/go.mod h1:LeFCbQYJ3KJlPs/FvPz2dy1tkpxyeNESVyCNNzRXFR0= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= @@ -973,13 +1089,17 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -990,21 +1110,31 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.23.1+incompatible h1:uArBYHQR0HqLFFAypI7RsWTzPSj/bDpmZZuQjMLSg1A= +github.com/uber/jaeger-client-go v2.23.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v1.5.1-0.20181102163054-1fc5c315e03c/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/weaveworks/common v0.0.0-20200512154658-384f10054ec5 h1:EYxr08r8x6r/5fLEAMMkida1BVgxVXE4LfZv/XV+znU= +github.com/weaveworks/common v0.0.0-20200512154658-384f10054ec5/go.mod h1:c98fKi5B9u8OsKGiWHLRKus6ToQ1Tubeow44ECO1uxY= +github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M= +github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba h1:X4n8JG2e2biEZZXdBKt9HX7DN3bYGFUqljqqy0DqgnY= github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CHQnYnQUEPydYCwuy8lmTHfGmdw9TKrhWV0xLx8l0oM= @@ -1024,7 +1154,6 @@ github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1 github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/whyrusleeping/go-logging v0.0.1 h1:fwpzlmT0kRC/Fmd0MdmGgJG/CXIZ6gFq46FQZjprUcc= github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE= github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible/go.mod h1:34LEDbeKFZInPUrAG+bjuJmUXONGdEFW7XL0SpTY1y4= @@ -1043,6 +1172,7 @@ github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSv github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= @@ -1054,14 +1184,18 @@ go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRL go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= -go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1082,16 +1216,15 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEa go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go4.org v0.0.0-20190218023631-ce4c26f7be8e h1:m9LfARr2VIOW0vsV19kEKp/sWQvZnGobA8JHui/XJoY= go4.org v0.0.0-20190218023631-ce4c26f7be8e/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20190313082347-94abd6928b1d h1:JkRdGP3zvTtTbabWSAC6n67ka30y7gOzWAah4XYJSfw= go4.org v0.0.0-20190313082347-94abd6928b1d/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1104,6 +1237,7 @@ golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1111,8 +1245,6 @@ golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc h1:ZGI/fILM2+ueot/UixBSoj9188jCAxVHEZEGhqq67I4= -golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1122,6 +1254,7 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1133,8 +1266,10 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1142,13 +1277,17 @@ golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/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-20190603091049-60506f45cf65/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/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1162,9 +1301,12 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1174,7 +1316,9 @@ golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1183,33 +1327,37 @@ golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200427175716-29b57079015a h1:08u6b1caTT9MQY4wSbmsd4Ulm6DmgNYnbImBuZjGJow= -golang.org/x/sys v0.0.0-20200427175716-29b57079015a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f h1:mOhmO9WsBaJCNmaZHPtHs9wOcdqdKCjF6OPJlmDM3KI= golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1231,8 +1379,10 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108195415-316d2f248479/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566 h1:OXjomkWHhzUx4+HldlJ2TsMxJdWgEo5CTtspD1wdhdk= golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1243,38 +1393,50 @@ google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMt google.golang.org/api v0.3.2 h1:iTp+3yyl/KOtxa/d1/JUE0GGSoR6FuW5udver22iwpw= google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2 h1:KlOjjpQjL4dqscfbhtQvAnRMm5PaRTchHHczffkUiq0= -google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= -google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 h1:Ggy3mWN4l3PUFPfSG0YB3n5fVYggzysUmiUQ89SnX6Y= gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1294,3 +1456,5 @@ howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqp howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 218b2b82c1cf0dfd7c690f755002d4c641968b36 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 27 May 2020 14:09:04 +0200 Subject: [PATCH 005/379] Update drand chain info Signed-off-by: Jakub Sztandera --- Makefile | 2 +- build/params_shared.go | 2 +- chain/beacon/drand/drand_test.go | 6 ++---- go.sum | 7 ++++++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1af851082..a189ccca2 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,7 @@ benchmarks: @curl -X POST 'http://benchmark.kittyhawk.wtf/benchmark' -d '@bench.json' -u "${benchmark_http_cred}" .PHONY: benchmarks -pond: build +pond: 2k go build -o pond ./lotuspond (cd lotuspond/front && npm i && CI=false npm run build) .PHONY: pond diff --git a/build/params_shared.go b/build/params_shared.go index 7de5a11d0..06d708444 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -120,4 +120,4 @@ const VerifSigCacheSize = 32000 const BlockMessageLimit = 512 const BlockGasLimit = 100_000_000 -var DrandChain = `{"public_key":"kiouk4KP+DNFuuUz9RcmaaJsAtx21r9ZyAiS4SqxRVwikhGIbzW7Vq9tW+qYECTf","period":25,"genesis_time":1590445175,"hash":"E4oySqZUD5PQ2tACqolFSxvsK26UhoLN5r1NtA9LfJs="}` +var DrandChain = `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}` diff --git a/chain/beacon/drand/drand_test.go b/chain/beacon/drand/drand_test.go index b8b089732..85b80cbe6 100644 --- a/chain/beacon/drand/drand_test.go +++ b/chain/beacon/drand/drand_test.go @@ -1,8 +1,7 @@ package drand import ( - "encoding/json" - "fmt" + "os" "testing" dchain "github.com/drand/drand/chain" @@ -18,7 +17,6 @@ func TestPrintGroupInfo(t *testing.T) { }) chain, err := cg.FetchChainInfo(nil) assert.NoError(t, err) - cbytes, err := json.Marshal(chain.ToProto()) + err = chain.ToJSON(os.Stdout) assert.NoError(t, err) - fmt.Printf("%s\n", cbytes) } diff --git a/go.sum b/go.sum index 155a60127..7134301be 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= @@ -29,6 +30,7 @@ github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -205,7 +207,6 @@ github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= -github.com/filecoin-project/specs-actors v0.4.1-0.20200509020627-3c96f54f3d7d/go.mod h1:UW3ft23q6VS8wQoNqLWjENsu9gu1uh6lxOd+H8cwhT8= github.com/filecoin-project/specs-actors v0.5.2/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461 h1:yyAoJ9dNboljDWj0uBdJEbdaTak/YhkjYUQt0GzlY0A= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= @@ -534,6 +535,7 @@ github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= @@ -963,6 +965,7 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= +github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -1124,7 +1127,9 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= From aa682a377d0c26a631cd362ba473193add046e63 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 27 May 2020 15:16:37 +0200 Subject: [PATCH 006/379] Partially fix pond spawn Signed-off-by: Jakub Sztandera --- lotuspond/spawn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index 4d8b8b9fd..5b0f7f704 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -171,7 +171,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { initArgs := []string{"init", "--nosync"} if fullNodeRepo == api.running[1].meta.Repo { presealPrefix := filepath.Join(fullNodeRepo, "preseal") - initArgs = []string{"init", "--actor=t01000", "--genesis-miner", "--pre-sealed-sectors=" + presealPrefix, "--pre-sealed-metadata=" + filepath.Join(presealPrefix, "pre-seal-t0101.json")} + initArgs = []string{"init", "--actor=t01000", "--genesis-miner", "--pre-sealed-sectors=" + presealPrefix, "--pre-sealed-metadata=" + filepath.Join(presealPrefix, "pre-seal-t01000.json")} } id := atomic.AddInt32(&api.cmds, 1) From 3f9cde28fc95fb8c367ec6e07e376588237953a9 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 27 May 2020 16:16:29 +0200 Subject: [PATCH 007/379] Update go-log, reduce drand entry log level, add TAG env for dev scripts Signed-off-by: Jakub Sztandera --- chain/beacon/drand/drand.go | 2 +- go.mod | 2 +- go.sum | 2 ++ scripts/dev/gen-daemon | 9 +++++---- scripts/dev/sminer-init | 5 ++++- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 39c185ee7..f5d6b2b41 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -106,7 +106,7 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re } go func() { - log.Warnw("fetching randomness", "round", round) + log.Infow("fetching randomness", "round", round) resp, err := db.client.Get(ctx, round) var br beacon.Response diff --git a/go.mod b/go.mod index 3a4912c92..b8fa35330 100644 --- a/go.mod +++ b/go.mod @@ -62,7 +62,7 @@ require ( github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf github.com/ipfs/go-ipld-format v0.2.0 github.com/ipfs/go-log v1.0.4 - github.com/ipfs/go-log/v2 v2.1.0 + github.com/ipfs/go-log/v2 v2.1.1 github.com/ipfs/go-merkledag v0.3.1 github.com/ipfs/go-path v0.0.7 github.com/ipfs/go-unixfs v0.2.4 diff --git a/go.sum b/go.sum index 7134301be..61e846c3d 100644 --- a/go.sum +++ b/go.sum @@ -480,6 +480,8 @@ github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscw github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.0 h1:7l5yjP7aLl5xr7RmqEvPZy9Skq7PP2fIP0Pa7lU/UII= github.com/ipfs/go-log/v2 v2.1.0/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.1 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0= +github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= diff --git a/scripts/dev/gen-daemon b/scripts/dev/gen-daemon index ba896b5d6..62a07595d 100755 --- a/scripts/dev/gen-daemon +++ b/scripts/dev/gen-daemon @@ -3,8 +3,9 @@ set -o xtrace export TRUST_PARAMS=1 +tag=${TAG:-debug} -go run -tags=debug ./cmd/lotus-seed pre-seal --sector-size 2048 --num-sectors 2 -go run -tags=debug ./cmd/lotus-seed genesis new localnet.json -go run -tags=debug ./cmd/lotus-seed genesis add-miner localnet.json ~/.genesis-sectors/pre-seal-t01000.json -go run -tags=debug ./cmd/lotus daemon --lotus-make-genesis=devel.gen --genesis-template=localnet.json --bootstrap=false +go run -tags=$tag ./cmd/lotus-seed pre-seal --sector-size 2048 --num-sectors 2 +go run -tags=$tag ./cmd/lotus-seed genesis new localnet.json +go run -tags=$tag ./cmd/lotus-seed genesis add-miner localnet.json ~/.genesis-sectors/pre-seal-t01000.json +go run -tags=$tag ./cmd/lotus daemon --lotus-make-genesis=devel.gen --genesis-template=localnet.json --bootstrap=false diff --git a/scripts/dev/sminer-init b/scripts/dev/sminer-init index ce38d5ba2..2f4a3f7af 100755 --- a/scripts/dev/sminer-init +++ b/scripts/dev/sminer-init @@ -4,4 +4,7 @@ set -o xtrace export TRUST_PARAMS=1 -go run -tags=debug ./cmd/lotus-storage-miner init --actor=t0101 --genesis-miner --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t0101.json +tag=${TAG:-debug} + +go run -tags=$tag ./cmd/lotus wallet import ~/.genesis-sectors/pre-seal-t01000.key +go run -tags=$tag ./cmd/lotus-storage-miner init --actor=t01000 --genesis-miner --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t01000.json From 4604b60fb12a56b7ccddda713a5a0a2e28f89529 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 27 May 2020 20:24:26 +0200 Subject: [PATCH 008/379] Remove drand on miner side, MinerGetBaseInfo provides the same info Signed-off-by: Jakub Sztandera --- chain/beacon/drand/drand.go | 5 +++-- cmd/lotus-storage-miner/init.go | 13 +------------ miner/miner.go | 13 +++---------- miner/testminer.go | 6 ++---- node/modules/storageminer.go | 4 ++-- 5 files changed, 11 insertions(+), 30 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index f5d6b2b41..d8df81f03 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -106,7 +106,8 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re } go func() { - log.Infow("fetching randomness", "round", round) + start := time.Now() + log.Infow("start fetching randomness", "round", round) resp, err := db.client.Get(ctx, round) var br beacon.Response @@ -116,7 +117,7 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re br.Entry.Round = resp.Round() br.Entry.Data = resp.Signature() } - + log.Infow("done fetching randomness", "round", round, "took", time.Since(start)) out <- br close(out) }() diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index f834a09a5..c28e9548c 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -37,7 +37,6 @@ import ( lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/beacon/drand" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/genesis" @@ -446,17 +445,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, return err } - gen, err := api.ChainGetGenesis(ctx) - if err != nil { - return err - } - - beacon, err := drand.NewDrandBeacon(gen.Blocks()[0].Timestamp, build.BlockDelay) - if err != nil { - return err - } - - m := miner.NewMiner(api, epp, beacon, a) + m := miner.NewMiner(api, epp, a) { if err := m.Start(ctx); err != nil { return xerrors.Errorf("failed to start up genesis miner: %w", err) diff --git a/miner/miner.go b/miner/miner.go index cef3518aa..31264ec50 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -15,7 +15,6 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -31,7 +30,7 @@ var log = logging.Logger("miner") // returns a callback reporting whether we mined a blocks in this round type waitFunc func(ctx context.Context, baseTime uint64) (func(bool), error) -func NewMiner(api api.FullNode, epp gen.WinningPoStProver, beacon beacon.RandomBeacon, addr address.Address) *Miner { +func NewMiner(api api.FullNode, epp gen.WinningPoStProver, addr address.Address) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) @@ -40,7 +39,6 @@ func NewMiner(api api.FullNode, epp gen.WinningPoStProver, beacon beacon.RandomB return &Miner{ api: api, epp: epp, - beacon: beacon, address: addr, waitFunc: func(ctx context.Context, baseTime uint64) (func(bool), error) { // Wait around for half the block time in case other parents come in @@ -56,8 +54,7 @@ func NewMiner(api api.FullNode, epp gen.WinningPoStProver, beacon beacon.RandomB type Miner struct { api api.FullNode - epp gen.WinningPoStProver - beacon beacon.RandomBeacon + epp gen.WinningPoStProver lk sync.Mutex address address.Address @@ -267,12 +264,8 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, beaconPrev := mbi.PrevBeaconEntry - bvals, err := beacon.BeaconEntriesForBlock(ctx, m.beacon, round, beaconPrev) - if err != nil { - return nil, xerrors.Errorf("get beacon entries failed: %w", err) - } - tDrand := time.Now() + bvals := mbi.BeaconEntries hasPower, err := m.hasPower(ctx, m.address, base.TipSet) if err != nil { diff --git a/miner/testminer.go b/miner/testminer.go index 3eab836c5..1576f2779 100644 --- a/miner/testminer.go +++ b/miner/testminer.go @@ -5,20 +5,18 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/gen" lru "github.com/hashicorp/golang-lru" ) -func NewTestMiner(nextCh <-chan func(bool), addr address.Address) func(api.FullNode, gen.WinningPoStProver, beacon.RandomBeacon) *Miner { - return func(api api.FullNode, epp gen.WinningPoStProver, b beacon.RandomBeacon) *Miner { +func NewTestMiner(nextCh <-chan func(bool), addr address.Address) func(api.FullNode, gen.WinningPoStProver) *Miner { + return func(api api.FullNode, epp gen.WinningPoStProver) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) } m := &Miner{ - beacon: b, api: api, waitFunc: chanWaiter(nextCh), epp: epp, diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index f54a2672e..ee3fc9a1a 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -263,13 +263,13 @@ func StagingGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.Stagi return gs } -func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.WinningPoStProver, beacon beacon.RandomBeacon) (*miner.Miner, error) { +func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.WinningPoStProver) (*miner.Miner, error) { minerAddr, err := minerAddrFromDS(ds) if err != nil { return nil, err } - m := miner.NewMiner(api, epp, beacon, minerAddr) + m := miner.NewMiner(api, epp, minerAddr) lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { From d6615b6286fe803a0bc6938e800e141cdb66c791 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 27 May 2020 22:53:20 +0200 Subject: [PATCH 009/379] Cleanup many lint warnings Signed-off-by: Jakub Sztandera --- .golangci.yml | 12 +- api/api_worker.go | 2 +- api/apistruct/permissioned.go | 2 +- api/apistruct/struct.go | 2 +- api/client/client.go | 2 +- api/docgen/docgen.go | 1 + api/test/deals.go | 2 +- api/types.go | 1 + build/parameters.go | 2 +- build/version.go | 1 + chain/actors/aerrors/wrap.go | 1 + chain/blocksync/blocksync.go | 4 +- chain/blocksync/blocksync_client.go | 6 +- chain/events/events.go | 2 +- chain/gen/genesis/miners.go | 3 + chain/state/statetree_test.go | 5 +- chain/stmgr/stmgr.go | 4 +- chain/store/store.go | 10 +- chain/sync_test.go | 4 +- chain/types/blockheader_test.go | 7 +- chain/vectors/gen/main.go | 9 +- chain/vm/runtime.go | 11 +- chain/vm/syscalls.go | 2 +- chain/vm/validation_test.go | 2 + chain/vm/vm.go | 4 +- chain/wallet/wallet.go | 4 +- cli/chain.go | 7 +- cli/multisig.go | 5 +- cli/params.go | 2 +- cli/paych.go | 2 +- cmd/chain-noise/main.go | 3 +- cmd/lotus-bench/import.go | 6 +- cmd/lotus-bench/main.go | 19 +- cmd/lotus-chainwatch/main.go | 2 +- cmd/lotus-chainwatch/sync.go | 2 + cmd/lotus-fountain/main.go | 6 +- cmd/lotus-health/main.go | 2 +- cmd/lotus-seal-worker/main.go | 8 +- cmd/lotus-seed/main.go | 1 - cmd/lotus-seed/seed/seed.go | 4 +- cmd/lotus-shed/import-car.go | 2 +- cmd/lotus-shed/params.go | 2 +- cmd/lotus-storage-miner/init.go | 4 +- cmd/lotus/daemon.go | 4 +- cmd/lotus/rpc.go | 4 +- extern/rleplus/internal/bitvector.go | 154 ---------------- extern/rleplus/internal/bitvector_test.go | 136 -------------- extern/rleplus/rleplus.go | 204 --------------------- extern/rleplus/rleplus_test.go | 213 ---------------------- genesis/types.go | 2 +- lib/addrutil/parse.go | 2 +- lib/increadtimeout/incrt.go | 2 +- lib/lotuslog/levels.go | 1 + markets/utils/converters.go | 2 +- node/config/storage.go | 3 +- node/hello/hello.go | 10 +- node/impl/client/client.go | 4 +- node/impl/full/chain.go | 2 +- node/impl/remoteworker.go | 2 +- node/modules/core.go | 2 +- node/modules/lp2p/addrs.go | 2 +- node/modules/storageminer.go | 14 +- node/node_test.go | 6 +- node/repo/fsrepo.go | 3 +- paychmgr/store.go | 4 +- storage/miner.go | 5 +- 66 files changed, 156 insertions(+), 807 deletions(-) delete mode 100644 extern/rleplus/internal/bitvector.go delete mode 100644 extern/rleplus/internal/bitvector_test.go delete mode 100644 extern/rleplus/rleplus.go delete mode 100644 extern/rleplus/rleplus_test.go diff --git a/.golangci.yml b/.golangci.yml index 396a1c2ac..c8805a7a3 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -22,13 +22,23 @@ issues: - "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this" - "Potential file inclusion via variable" - "should have( a package)? comment" + - "Error return value of `logging.SetLogLevel` is not checked" exclude-use-default: false exclude-rules: + - path: lotuspond + linters: + - errcheck + - path: node/modules/lp2p linters: - golint - - path: ".*_test.go" + + - path: build/params_.*\.go + linters: + - golint + + - path: .*_test.go linters: - gosec diff --git a/api/api_worker.go b/api/api_worker.go index dbad20651..d5fea5d6c 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -12,7 +12,7 @@ import ( "github.com/filecoin-project/lotus/build" ) -type WorkerApi interface { +type WorkerAPI interface { Version(context.Context) (build.Version, error) // TODO: Info() (name, ...) ? diff --git a/api/apistruct/permissioned.go b/api/apistruct/permissioned.go index 8ffc49bf9..c93662733 100644 --- a/api/apistruct/permissioned.go +++ b/api/apistruct/permissioned.go @@ -31,7 +31,7 @@ func PermissionedFullAPI(a api.FullNode) api.FullNode { return &out } -func PermissionedWorkerAPI(a api.WorkerApi) api.WorkerApi { +func PermissionedWorkerAPI(a api.WorkerAPI) api.WorkerAPI { var out WorkerStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) return &out diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 368a2b145..8a3237736 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -865,4 +865,4 @@ func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) { var _ api.Common = &CommonStruct{} var _ api.FullNode = &FullNodeStruct{} var _ api.StorageMiner = &StorageMinerStruct{} -var _ api.WorkerApi = &WorkerStruct{} +var _ api.WorkerAPI = &WorkerStruct{} diff --git a/api/client/client.go b/api/client/client.go index d3eceb24a..20bad2048 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -48,7 +48,7 @@ func NewStorageMinerRPC(addr string, requestHeader http.Header) (api.StorageMine return &res, closer, err } -func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerApi, jsonrpc.ClientCloser, error) { +func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) { var res apistruct.WorkerStruct closer, err := jsonrpc.NewMergeClient(addr, "Filecoin", []interface{}{ diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 0ad3b02bb..f2d4d6ce4 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -320,6 +320,7 @@ func main() { }) for _, g := range groupslice { + g := g fmt.Printf("## %s\n", g.GroupName) fmt.Printf("%s\n\n", g.Header) diff --git a/api/test/deals.go b/api/test/deals.go index 2414d3fe2..98edce67a 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -193,7 +193,7 @@ func testRetrieval(t *testing.T, ctx context.Context, err error, client *impl.Fu if err != nil { t.Fatal(err) } - defer os.RemoveAll(rpath) + defer os.RemoveAll(rpath) //nolint:errcheck caddr, err := client.WalletDefaultAddress(ctx) if err != nil { diff --git a/api/types.go b/api/types.go index 732f1f328..26d0695e1 100644 --- a/api/types.go +++ b/api/types.go @@ -7,6 +7,7 @@ import ( ) // TODO: check if this exists anywhere else + type MultiaddrSlice []ma.Multiaddr func (m *MultiaddrSlice) UnmarshalJSON(raw []byte) (err error) { diff --git a/build/parameters.go b/build/parameters.go index b7fac93d1..7d34a7831 100644 --- a/build/parameters.go +++ b/build/parameters.go @@ -2,6 +2,6 @@ package build import rice "github.com/GeertJohan/go.rice" -func ParametersJson() []byte { +func ParametersJSON() []byte { return rice.MustFindBox("proof-params").MustBytes("parameters.json") } diff --git a/build/version.go b/build/version.go index c5d96e9af..e0ddebf36 100644 --- a/build/version.go +++ b/build/version.go @@ -33,6 +33,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool { // APIVersion is a semver version of the rpc api exposed var APIVersion Version = newVer(0, 3, 0) +//nolint:varcheck const ( majorMask = 0xff0000 minorMask = 0xffff00 diff --git a/chain/actors/aerrors/wrap.go b/chain/actors/aerrors/wrap.go index 2e7444101..338659966 100644 --- a/chain/actors/aerrors/wrap.go +++ b/chain/actors/aerrors/wrap.go @@ -50,6 +50,7 @@ func Newf(retCode exitcode.ExitCode, format string, args ...interface{}) ActorEr } // todo: bit hacky + func NewfSkip(skip int, retCode exitcode.ExitCode, format string, args ...interface{}) ActorError { if retCode == 0 { return &actorError{ diff --git a/chain/blocksync/blocksync.go b/chain/blocksync/blocksync.go index ccb7a5498..daca9ce20 100644 --- a/chain/blocksync/blocksync.go +++ b/chain/blocksync/blocksync.go @@ -91,7 +91,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) { ctx, span := trace.StartSpan(context.Background(), "blocksync.HandleStream") defer span.End() - defer s.Close() + defer s.Close() //nolint:errcheck var req BlockSyncRequest if err := cborutil.ReadCborRPC(bufio.NewReader(s), &req); err != nil { @@ -107,7 +107,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) { } writeDeadline := 60 * time.Second - s.SetDeadline(time.Now().Add(writeDeadline)) + _ = s.SetDeadline(time.Now().Add(writeDeadline)) if err := cborutil.WriteCborRPC(s, resp); err != nil { log.Warnw("failed to write back response for handle stream", "err", err, "peer", s.Conn().RemotePeer()) return diff --git a/chain/blocksync/blocksync_client.go b/chain/blocksync/blocksync_client.go index 0790cb128..f6453efde 100644 --- a/chain/blocksync/blocksync_client.go +++ b/chain/blocksync/blocksync_client.go @@ -283,14 +283,14 @@ func (bs *BlockSync) fetchBlocksBlockSync(ctx context.Context, p peer.ID, req *B bs.RemovePeer(p) return nil, xerrors.Errorf("failed to open stream to peer: %w", err) } - s.SetWriteDeadline(time.Now().Add(5 * time.Second)) + _ = s.SetWriteDeadline(time.Now().Add(5 * time.Second)) if err := cborutil.WriteCborRPC(s, req); err != nil { - s.SetWriteDeadline(time.Time{}) + _ = s.SetWriteDeadline(time.Time{}) bs.syncPeers.logFailure(p, time.Since(start)) return nil, err } - s.SetWriteDeadline(time.Time{}) + _ = s.SetWriteDeadline(time.Time{}) var res BlockSyncResponse r := incrt.New(s, 50<<10, 5*time.Second) diff --git a/chain/events/events.go b/chain/events/events.go index 02321235b..c6d54d536 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -67,7 +67,7 @@ func NewEvents(ctx context.Context, api eventApi) *Events { heightEvents: heightEvents{ tsc: tsc, ctx: ctx, - gcConfidence: abi.ChainEpoch(gcConfidence), + gcConfidence: gcConfidence, heightTriggers: map[uint64]*heightHandler{}, htTriggerHeights: map[abi.ChainEpoch][]uint64{}, diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 51a128d54..fa71865b8 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -58,6 +58,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid for i, m := range miners { // Create miner through power actor + i := i + m := m spt, err := ffiwrapper.SealProofTypeFromSectorSize(m.SectorSize) if err != nil { @@ -154,6 +156,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid // Commit sectors for pi, preseal := range m.Sectors { + preseal := preseal // TODO: Maybe check seal (Can just be snark inputs, doesn't go into the genesis file) // check deals, get dealWeight diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 4cdc87d19..3c832f7cc 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -255,12 +255,15 @@ func TestStateTreeConsistency(t *testing.T) { } for i, a := range addrs { - st.SetActor(a, &types.Actor{ + err := st.SetActor(a, &types.Actor{ Code: randomCid, Head: randomCid, Balance: types.NewInt(uint64(10000 + i)), Nonce: uint64(1000 - i), }) + if err != nil { + t.Fatalf("while setting actor: %+v", err) + } } root, err := st.Flush(context.TODO()) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index e291fe623..5a1eb88ea 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -382,8 +382,8 @@ func (sm *StateManager) LoadActorState(ctx context.Context, a address.Address, o cst := cbor.NewCborStore(sm.cs.Blockstore()) if err := cst.Get(ctx, act.Head, out); err != nil { var r cbg.Deferred - cst.Get(ctx, act.Head, &r) - fmt.Printf("badhead %x\n", r.Raw) + _ = cst.Get(ctx, act.Head, &r) + log.Errorw("bad actor head", "error", err, "raw", r.Raw, "address", a) return nil, err } diff --git a/chain/store/store.go b/chain/store/store.go index 1d0668032..e8c04b11b 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -895,11 +895,17 @@ func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.Cha return nil, xerrors.Errorf("deriving randomness: %w", err) } VRFDigest := blake2b.Sum256(rbase) - h.Write(VRFDigest[:]) + _, err := h.Write(VRFDigest[:]) + if err != nil { + return nil, xerrors.Errorf("hashing VRFDigest: %w", err) + } if err := binary.Write(h, binary.BigEndian, round); err != nil { return nil, xerrors.Errorf("deriving randomness: %w", err) } - h.Write(entropy) + _, err = h.Write(entropy) + if err != nil { + return nil, xerrors.Errorf("hashing entropy: %w", err) + } return h.Sum(nil), nil } diff --git a/chain/sync_test.go b/chain/sync_test.go index 9c7d47bc6..e1c846d4e 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -417,7 +417,7 @@ func TestSyncBadTimestamp(t *testing.T) { a1 := tu.mineOnBlock(base, 0, nil, false, true) tu.g.Timestamper = nil - tu.g.ResyncBankerNonce(a1.TipSet()) + require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet())) fmt.Println("After mine bad block!") tu.printHeads() @@ -479,7 +479,7 @@ func TestSyncFork(t *testing.T) { a := tu.mineOnBlock(a1, p1, []int{0}, true, false) a = tu.mineOnBlock(a, p1, []int{0}, true, false) - tu.g.ResyncBankerNonce(a1.TipSet()) + require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet())) // chain B will now be heaviest b := tu.mineOnBlock(base, p2, []int{1}, true, false) b = tu.mineOnBlock(b, p2, []int{1}, true, false) diff --git a/chain/types/blockheader_test.go b/chain/types/blockheader_test.go index e18e4028a..387fe86c2 100644 --- a/chain/types/blockheader_test.go +++ b/chain/types/blockheader_test.go @@ -4,13 +4,14 @@ import ( "bytes" "encoding/hex" "fmt" - "github.com/filecoin-project/specs-actors/actors/abi" "reflect" "testing" - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/crypto" cid "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/crypto" ) func testBlockHeader(t testing.TB) *BlockHeader { diff --git a/chain/vectors/gen/main.go b/chain/vectors/gen/main.go index cf8ebd859..2ebcb9a60 100644 --- a/chain/vectors/gen/main.go +++ b/chain/vectors/gen/main.go @@ -7,6 +7,7 @@ import ( "os" "github.com/filecoin-project/go-address" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" @@ -173,14 +174,18 @@ func WriteJsonToFile(fname string, obj interface{}) error { if err != nil { return err } - defer fi.Close() + defer fi.Close() //nolint:errcheck out, err := json.MarshalIndent(obj, "", " ") if err != nil { return err } - fi.Write(out) + _, err = fi.Write(out) + if err != nil { + return xerrors.Errorf("writing json: %w", err) + } + return nil } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index ebaf48f59..403a92fa7 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -5,6 +5,7 @@ import ( "context" "encoding/binary" "fmt" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/abi/big" @@ -182,7 +183,7 @@ func (rs *Runtime) ValidateImmediateCallerAcceptAny() { func (rs *Runtime) CurrentBalance() abi.TokenAmount { b, err := rs.GetBalance(rs.Message().Receiver()) if err != nil { - rs.Abortf(exitcode.ExitCode(err.RetCode()), "get current balance: %v", err) + rs.Abortf(err.RetCode(), "get current balance: %v", err) } return b } @@ -354,13 +355,13 @@ func (rs *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars params = buf.Bytes() } - ret, err := rs.internalSend(rs.Message().Receiver(), to, method, types.BigInt(value), params) + ret, err := rs.internalSend(rs.Message().Receiver(), to, method, value, params) if err != nil { if err.IsFatal() { panic(err) } log.Warnf("vmctx send failed: to: %s, method: %d: ret: %d, err: %s", to, method, ret, err) - return nil, exitcode.ExitCode(err.RetCode()) + return nil, err.RetCode() } return &dumbWrapperType{ret}, 0 } @@ -399,7 +400,7 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, } mr := types.MessageReceipt{ - ExitCode: exitcode.ExitCode(aerrors.RetCode(errSend)), + ExitCode: aerrors.RetCode(errSend), Return: ret, GasUsed: 0, } @@ -431,6 +432,7 @@ type shimStateHandle struct { func (ssh *shimStateHandle) Create(obj vmr.CBORMarshaler) { c := ssh.rs.Put(obj) + // TODO: handle error below ssh.rs.stateCommit(EmptyObjectCid, c) } @@ -460,6 +462,7 @@ func (ssh *shimStateHandle) Transaction(obj vmr.CBORer, f func() interface{}) in c := ssh.rs.Put(obj) + // TODO: handle error below ssh.rs.stateCommit(baseState, c) return out diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index c3fe4375f..8039d2b2a 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -225,7 +225,7 @@ func (ss *syscallShim) VerifySeal(info abi.SealVerifyInfo) error { } ticket := []byte(info.Randomness) - proof := []byte(info.Proof) + proof := info.Proof seed := []byte(info.InteractiveRandomness) log.Debugf("Verif r:%x; d:%x; m:%s; t:%x; s:%x; N:%d; p:%x", info.SealedCID, info.UnsealedCID, miner, ticket, seed, info.SectorID.Number, proof) diff --git a/chain/vm/validation_test.go b/chain/vm/validation_test.go index c84cb4adc..880b33401 100644 --- a/chain/vm/validation_test.go +++ b/chain/vm/validation_test.go @@ -41,6 +41,7 @@ func init() { func TestChainValidationMessageSuite(t *testing.T) { f := factory.NewFactories() for _, testCase := range suites.MessageTestCases() { + testCase := testCase if TestSuiteSkipper.Skip(testCase) { continue } @@ -53,6 +54,7 @@ func TestChainValidationMessageSuite(t *testing.T) { func TestChainValidationTipSetSuite(t *testing.T) { f := factory.NewFactories() for _, testCase := range suites.TipSetTestCases() { + testCase := testCase if TestSuiteSkipper.Skip(testCase) { continue } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index dd96f3928..49294e9cf 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -246,7 +246,7 @@ func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*Ap ret, actorErr, rt := vm.send(ctx, msg, nil, 0) return &ApplyRet{ MessageReceipt: types.MessageReceipt{ - ExitCode: exitcode.ExitCode(aerrors.RetCode(actorErr)), + ExitCode: aerrors.RetCode(actorErr), Return: ret, GasUsed: 0, }, @@ -415,7 +415,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, return &ApplyRet{ MessageReceipt: types.MessageReceipt{ - ExitCode: exitcode.ExitCode(errcode), + ExitCode: errcode, Return: ret, GasUsed: gasUsed, }, diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index 54587e1b5..7ad37a205 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -12,8 +12,8 @@ import ( "github.com/filecoin-project/go-address" - _ "github.com/filecoin-project/lotus/lib/sigs/bls" - _ "github.com/filecoin-project/lotus/lib/sigs/secp" + _ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures + _ "github.com/filecoin-project/lotus/lib/sigs/secp" // enable secp signatures "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" diff --git a/cli/chain.go b/cli/chain.go index 033c7b234..9e245c875 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -804,7 +804,12 @@ var chainExportCmd = &cli.Command{ if err != nil { return err } - defer fi.Close() + defer func() { + err := fi.Close() + if err != nil { + fmt.Printf("error closing output file: %+v", err) + } + }() ts, err := LoadTipSet(ctx, cctx, api) if err != nil { diff --git a/cli/multisig.go b/cli/multisig.go index ff2ff2fce..9acf1af08 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -206,7 +206,10 @@ var msigInspectCmd = &cli.Command{ tx := pending[txid] fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%d\t%x\n", txid, state(tx), tx.To, types.FIL(tx.Value), tx.Method, tx.Params) } - w.Flush() + if err := w.Flush(); err != nil { + return xerrors.Errorf("flushing ouput: %+v", err) + } + } return nil diff --git a/cli/params.go b/cli/params.go index 518add665..f6acbaad7 100644 --- a/cli/params.go +++ b/cli/params.go @@ -24,7 +24,7 @@ var fetchParamCmd = &cli.Command{ return err } sectorSize := uint64(sectorSizeInt) - err = paramfetch.GetParams(build.ParametersJson(), sectorSize) + err = paramfetch.GetParams(build.ParametersJSON(), sectorSize) if err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } diff --git a/cli/paych.go b/cli/paych.go index e150d6769..5fe5fac0c 100644 --- a/cli/paych.go +++ b/cli/paych.go @@ -370,7 +370,7 @@ var paychVoucherSubmitCmd = &cli.Command{ return fmt.Errorf("message execution failed (exit code %d)", mwait.Receipt.ExitCode) } - fmt.Println("channel updated succesfully") + fmt.Println("channel updated successfully") return nil }, diff --git a/cmd/chain-noise/main.go b/cmd/chain-noise/main.go index dc64b70ed..e152ccf75 100644 --- a/cmd/chain-noise/main.go +++ b/cmd/chain-noise/main.go @@ -53,8 +53,7 @@ var runCmd = &cli.Command{ defer closer() ctx := lcli.ReqContext(cctx) - sendSmallFundsTxs(ctx, api, addr, 5) - return nil + return sendSmallFundsTxs(ctx, api, addr, 5) }, } diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 6306cd18c..f33cc1d9d 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -55,7 +55,7 @@ var importBenchCmd = &cli.Command{ if err != nil { return err } - defer cfi.Close() + defer cfi.Close() //nolint:errcheck // read only file tdir, err := ioutil.TempDir("", "lotus-import-bench") if err != nil { @@ -80,7 +80,7 @@ var importBenchCmd = &cli.Command{ if err != nil { return err } - defer prof.Close() + defer prof.Close() //nolint:errcheck if err := pprof.StartCPUProfile(prof); err != nil { return err @@ -146,7 +146,7 @@ var importBenchCmd = &cli.Command{ if err != nil { return err } - defer ibj.Close() + defer ibj.Close() //nolint:errcheck if err := json.NewEncoder(ibj).Encode(out); err != nil { return err diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 23471500d..b8740f2f3 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -141,7 +141,10 @@ var sealBenchCmd = &cli.Command{ }, Action: func(c *cli.Context) error { if c.Bool("no-gpu") { - os.Setenv("BELLMAN_NO_GPU", "1") + err := os.Setenv("BELLMAN_NO_GPU", "1") + if err != nil { + return xerrors.Errorf("setting no-gpu flag: %w", err) + } } robench := c.String("benchmark-existing-sectorbuilder") @@ -154,7 +157,10 @@ var sealBenchCmd = &cli.Command{ return err } - os.MkdirAll(sdir, 0775) + err = os.MkdirAll(sdir, 0775) + if err != nil { + return xerrors.Errorf("creating sectorbuilder dir: %w", err) + } tsdir, err := ioutil.TempDir(sdir, "bench") if err != nil { @@ -209,7 +215,7 @@ var sealBenchCmd = &cli.Command{ // Only fetch parameters if actually needed if !c.Bool("skip-commit2") { - if err := paramfetch.GetParams(build.ParametersJson(), uint64(sectorSize)); err != nil { + if err := paramfetch.GetParams(build.ParametersJSON(), uint64(sectorSize)); err != nil { return xerrors.Errorf("getting params: %w", err) } } @@ -599,7 +605,10 @@ var proveCmd = &cli.Command{ }, Action: func(c *cli.Context) error { if c.Bool("no-gpu") { - os.Setenv("BELLMAN_NO_GPU", "1") + err := os.Setenv("BELLMAN_NO_GPU", "1") + if err != nil { + return xerrors.Errorf("setting no-gpu flag: %w", err) + } } if !c.Args().Present() { @@ -616,7 +625,7 @@ var proveCmd = &cli.Command{ return xerrors.Errorf("unmarshalling input file: %w", err) } - if err := paramfetch.GetParams(build.ParametersJson(), c2in.SectorSize); err != nil { + if err := paramfetch.GetParams(build.ParametersJSON(), c2in.SectorSize); err != nil { return xerrors.Errorf("getting params: %w", err) } diff --git a/cmd/lotus-chainwatch/main.go b/cmd/lotus-chainwatch/main.go index 71722486d..a3114d8d0 100644 --- a/cmd/lotus-chainwatch/main.go +++ b/cmd/lotus-chainwatch/main.go @@ -86,7 +86,7 @@ var runCmd = &cli.Command{ if err != nil { return err } - defer st.close() + defer st.close() //nolint:errcheck runSyncer(ctx, api, st, maxBatch) diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 8fa903097..a62136ca8 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -198,6 +198,8 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS } for a, act := range changes { + act := act + addr, err := address.NewFromString(a) if err != nil { log.Error(err) diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index b2275b9ca..8fc1804d7 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -157,7 +157,7 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) { to, err := address.NewFromString(r.FormValue("address")) if err != nil { w.WriteHeader(400) - w.Write([]byte(err.Error())) + _, _ = w.Write([]byte(err.Error())) return } @@ -204,11 +204,11 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) { }) if err != nil { w.WriteHeader(400) - w.Write([]byte(err.Error())) + _, _ = w.Write([]byte(err.Error())) return } - w.Write([]byte(smsg.Cid().String())) + _, _ = w.Write([]byte(smsg.Cid().String())) } func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index 99b5b0129..6f5ce8e90 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -79,7 +79,7 @@ var watchHeadCmd = &cli.Command{ &cli.IntFlag{ Name: "api-retries", Value: 8, - Usage: "number of API retry attemps", + Usage: "number of API retry attempts", }, }, Action: func(c *cli.Context) error { diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index a2e14a1e6..b43b7267f 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -26,7 +26,7 @@ import ( lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/sector-storage" + sectorstorage "github.com/filecoin-project/sector-storage" "github.com/filecoin-project/sector-storage/sealtasks" "github.com/filecoin-project/sector-storage/stores" ) @@ -107,7 +107,9 @@ var runCmd = &cli.Command{ }, Action: func(cctx *cli.Context) error { if !cctx.Bool("enable-gpu-proving") { - os.Setenv("BELLMAN_NO_GPU", "true") + if err := os.Setenv("BELLMAN_NO_GPU", "true"); err != nil { + return xerrors.Errorf("could not set no-gpu env: %+v", err) + } } if cctx.String("address") == "" { @@ -146,7 +148,7 @@ var runCmd = &cli.Command{ } if cctx.Bool("commit") { - if err := paramfetch.GetParams(build.ParametersJson(), uint64(ssize)); err != nil { + if err := paramfetch.GetParams(build.ParametersJSON(), uint64(ssize)); err != nil { return xerrors.Errorf("get params: %w", err) } } diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index 4eaeca291..7b80a0479 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -145,7 +145,6 @@ var aggregateManifestsCmd = &cli.Command{ if err != nil { return err } - defer fi.Close() var val map[string]genesis.Miner if err := json.NewDecoder(fi).Decode(&val); err != nil { return err diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 6e5271f33..0f6539563 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/minio/blake2b-simd" "io/ioutil" "os" "path/filepath" @@ -15,6 +14,7 @@ import ( logging "github.com/ipfs/go-log/v2" ic "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" + "github.com/minio/blake2b-simd" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -48,7 +48,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum SealProofType: spt, } - if err := os.MkdirAll(sbroot, 0775); err != nil { + if err := os.MkdirAll(sbroot, 0775); err != nil { //golint:gosec return nil, nil, err } diff --git a/cmd/lotus-shed/import-car.go b/cmd/lotus-shed/import-car.go index 8933f8890..f2f517a7f 100644 --- a/cmd/lotus-shed/import-car.go +++ b/cmd/lotus-shed/import-car.go @@ -34,7 +34,7 @@ var importCarCmd = &cli.Command{ if err != nil { return err } - defer lr.Close() + defer lr.Close() //nolint:errcheck cf := cctx.Args().Get(0) f, err := os.OpenFile(cf, os.O_RDONLY, 0664) diff --git a/cmd/lotus-shed/params.go b/cmd/lotus-shed/params.go index ff00f2b4f..210711b91 100644 --- a/cmd/lotus-shed/params.go +++ b/cmd/lotus-shed/params.go @@ -24,7 +24,7 @@ var fetchParamCmd = &cli.Command{ return err } sectorSize := uint64(sectorSizeInt) - err = paramfetch.GetParams(build.ParametersJson(), sectorSize) + err = paramfetch.GetParams(build.ParametersJSON(), sectorSize) if err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index f834a09a5..7a6ac8257 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -127,7 +127,7 @@ var initCmd = &cli.Command{ } log.Info("Checking proof parameters") - if err := paramfetch.GetParams(build.ParametersJson(), uint64(ssize)); err != nil { + if err := paramfetch.GetParams(build.ParametersJSON(), uint64(ssize)); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } @@ -389,7 +389,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, if err != nil { return err } - defer lr.Close() + defer lr.Close() //notlint:errcheck log.Info("Initializing libp2p identity") diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 91af88a4e..9e4e7d1a3 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -134,7 +134,7 @@ var DaemonCmd = &cli.Command{ return xerrors.Errorf("repo init error: %w", err) } - if err := paramfetch.GetParams(build.ParametersJson(), 0); err != nil { + if err := paramfetch.GetParams(build.ParametersJSON(), 0); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } @@ -269,7 +269,7 @@ func ImportChain(r repo.Repo, fname string) error { if err != nil { return err } - defer lr.Close() + defer lr.Close() //nolint:errcheck ds, err := lr.Datastore("/blocks") if err != nil { diff --git a/cmd/lotus/rpc.go b/cmd/lotus/rpc.go index 7b1fc7286..d053e2a2e 100644 --- a/cmd/lotus/rpc.go +++ b/cmd/lotus/rpc.go @@ -85,14 +85,14 @@ func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Reque } if !auth.HasPerm(r.Context(), nil, apistruct.PermWrite) { w.WriteHeader(401) - json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) + _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) return } c, err := a.ClientImportLocal(r.Context(), r.Body) if err != nil { w.WriteHeader(500) - json.NewEncoder(w).Encode(struct{ Error string }{err.Error()}) + _ = json.NewEncoder(w).Encode(struct{ Error string }{err.Error()}) return } w.WriteHeader(200) diff --git a/extern/rleplus/internal/bitvector.go b/extern/rleplus/internal/bitvector.go deleted file mode 100644 index 65bae074e..000000000 --- a/extern/rleplus/internal/bitvector.go +++ /dev/null @@ -1,154 +0,0 @@ -package bitvector - -import ( - "errors" - "log" -) - -var ( - // ErrOutOfRange - the index passed is out of range for the BitVector - ErrOutOfRange = errors.New("index out of range") -) - -// BitNumbering indicates the ordering of bits, either -// least-significant bit in position 0, or most-significant bit -// in position 0. -// -// It it used in 3 ways with BitVector: -// 1. Ordering of bits within the Buf []byte structure -// 2. What order to add bits when using Extend() -// 3. What order to read bits when using Take() -// -// https://en.wikipedia.org/wiki/Bit_numbering -type BitNumbering int - -const ( - // LSB0 - bit ordering starts with the low-order bit - LSB0 BitNumbering = iota - - // MSB0 - bit ordering starts with the high-order bit - MSB0 -) - -// BitVector is used to manipulate ordered collections of bits -type BitVector struct { - Buf []byte - - // BytePacking is the bit ordering within bytes - BytePacking BitNumbering - - // Len is the logical number of bits in the vector. - // The last byte in Buf may have undefined bits if Len is not a multiple of 8 - Len uint -} - -// NewBitVector constructs a new BitVector from a slice of bytes. -// -// The bytePacking parameter is required to know how to interpret the bit ordering within the bytes. -func NewBitVector(buf []byte, bytePacking BitNumbering) *BitVector { - return &BitVector{ - BytePacking: bytePacking, - Buf: buf, - Len: uint(len(buf) * 8), - } -} - -// Push adds a single bit to the BitVector. -// -// Although it takes a byte, only the low-order bit is used, so just use 0 or 1. -func (v *BitVector) Push(val byte) { - if v.Len%8 == 0 { - v.Buf = append(v.Buf, 0) - } - lastIdx := v.Len / 8 - - switch v.BytePacking { - case LSB0: - v.Buf[lastIdx] |= (val & 1) << (v.Len % 8) - default: - v.Buf[lastIdx] |= (val & 1) << (7 - (v.Len % 8)) - } - - v.Len++ -} - -// Get returns a single bit as a byte -- either 0 or 1 -func (v *BitVector) Get(idx uint) (byte, error) { - if idx >= v.Len { - return 0, ErrOutOfRange - } - blockIdx := idx / 8 - - switch v.BytePacking { - case LSB0: - return v.Buf[blockIdx] >> (idx % 8) & 1, nil - default: - return v.Buf[blockIdx] >> (7 - idx%8) & 1, nil - } -} - -// Extend adds up to 8 bits to the receiver -// -// Given a byte b == 0b11010101 -// v.Extend(b, 4, LSB0) would add < 1, 0, 1, 0 > -// v.Extend(b, 4, MSB0) would add < 1, 1, 0, 1 > -// -// Panics if count is out of range -func (v *BitVector) Extend(val byte, count uint, order BitNumbering) { - if count > 8 { - log.Panicf("invalid count") - } - - for i := uint(0); i < count; i++ { - switch order { - case LSB0: - v.Push((val >> i) & 1) - default: - v.Push((val >> (7 - i)) & 1) - } - } -} - -// Take reads up to 8 bits at the given index. -// -// Given a BitVector < 1, 1, 0, 1, 0, 1, 0, 1 > -// v.Take(0, 4, LSB0) would return 0b00001011 -// v.Take(0, 4, MSB0) would return 0b11010000 -// -// Panics if count is out of range -func (v *BitVector) Take(index uint, count uint, order BitNumbering) (out byte) { - if count > 8 { - log.Panicf("invalid count") - } - - for i := uint(0); i < count; i++ { - val, _ := v.Get(index + i) - - switch order { - case LSB0: - out |= val << i - default: - out |= val << (7 - i) - } - } - return -} - -// Iterator returns a function, which when invoked, returns the number -// of bits requested, and increments an internal cursor. -// -// When the end of the BitVector is reached, it returns zeroes indefinitely -// -// Panics if count is out of range -func (v *BitVector) Iterator(order BitNumbering) func(uint) byte { - cursor := uint(0) - return func(count uint) (out byte) { - if count > 8 { - log.Panicf("invalid count") - } - - out = v.Take(cursor, count, order) - cursor += count - return - } -} diff --git a/extern/rleplus/internal/bitvector_test.go b/extern/rleplus/internal/bitvector_test.go deleted file mode 100644 index 2895db3a3..000000000 --- a/extern/rleplus/internal/bitvector_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package bitvector_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - bitvector "github.com/filecoin-project/lotus/extern/rleplus/internal" -) - -func TestBitVector(t *testing.T) { - t.Run("zero value", func(t *testing.T) { - var v bitvector.BitVector - - assert.Equal(t, bitvector.LSB0, v.BytePacking) - }) - - t.Run("Push", func(t *testing.T) { - // MSB0 bit numbering - v := bitvector.BitVector{BytePacking: bitvector.MSB0} - v.Push(1) - v.Push(0) - v.Push(1) - v.Push(1) - - assert.Equal(t, byte(176), v.Buf[0]) - - // LSB0 bit numbering - v = bitvector.BitVector{BytePacking: bitvector.LSB0} - v.Push(1) - v.Push(0) - v.Push(1) - v.Push(1) - - assert.Equal(t, byte(13), v.Buf[0]) - }) - - t.Run("Get", func(t *testing.T) { - bits := []byte{1, 0, 1, 1, 0, 0, 1, 0} - - for _, numbering := range []bitvector.BitNumbering{bitvector.MSB0, bitvector.LSB0} { - v := bitvector.BitVector{BytePacking: numbering} - - for _, bit := range bits { - v.Push(bit) - } - - for idx, expected := range bits { - actual, _ := v.Get(uint(idx)) - assert.Equal(t, expected, actual) - } - } - }) - - t.Run("Extend", func(t *testing.T) { - val := byte(171) // 0b10101011 - - var v bitvector.BitVector - - // MSB0 bit numbering - v = bitvector.BitVector{} - v.Extend(val, 4, bitvector.MSB0) - assertBitVector(t, []byte{1, 0, 1, 0}, v) - v.Extend(val, 5, bitvector.MSB0) - assertBitVector(t, []byte{1, 0, 1, 0, 1, 0, 1, 0, 1}, v) - - // LSB0 bit numbering - v = bitvector.BitVector{} - v.Extend(val, 4, bitvector.LSB0) - assertBitVector(t, []byte{1, 1, 0, 1}, v) - v.Extend(val, 5, bitvector.LSB0) - assertBitVector(t, []byte{1, 1, 0, 1, 1, 1, 0, 1, 0}, v) - }) - - t.Run("invalid counts to Take/Extend/Iterator cause panics", func(t *testing.T) { - v := bitvector.BitVector{BytePacking: bitvector.LSB0} - - assert.Panics(t, func() { v.Extend(0xff, 9, bitvector.LSB0) }) - - assert.Panics(t, func() { v.Take(0, 9, bitvector.LSB0) }) - - next := v.Iterator(bitvector.LSB0) - assert.Panics(t, func() { next(9) }) - }) - - t.Run("Take", func(t *testing.T) { - var v bitvector.BitVector - - bits := []byte{1, 0, 1, 0, 1, 0, 1, 1} - for _, bit := range bits { - v.Push(bit) - } - - assert.Equal(t, byte(176), v.Take(4, 4, bitvector.MSB0)) - assert.Equal(t, byte(13), v.Take(4, 4, bitvector.LSB0)) - }) - - t.Run("Iterator", func(t *testing.T) { - var buf []byte - - // make a bitvector of 256 sample bits - for i := 0; i < 32; i++ { - buf = append(buf, 128+32) - } - - v := bitvector.NewBitVector(buf, bitvector.LSB0) - - next := v.Iterator(bitvector.LSB0) - - // compare to Get() - for i := uint(0); i < v.Len; i++ { - expected, _ := v.Get(i) - assert.Equal(t, expected, next(1)) - } - - // out of range should return zero - assert.Equal(t, byte(0), next(1)) - assert.Equal(t, byte(0), next(8)) - - // compare to Take() - next = v.Iterator(bitvector.LSB0) - assert.Equal(t, next(5), v.Take(0, 5, bitvector.LSB0)) - assert.Equal(t, next(8), v.Take(5, 8, bitvector.LSB0)) - }) -} - -// Note: When using this helper assertion, expectedBits should *only* be 0s and 1s. -func assertBitVector(t *testing.T, expectedBits []byte, actual bitvector.BitVector) { - assert.Equal(t, uint(len(expectedBits)), actual.Len) - - for idx, bit := range expectedBits { - actualBit, err := actual.Get(uint(idx)) - assert.NoError(t, err) - assert.Equal(t, bit, actualBit) - } -} diff --git a/extern/rleplus/rleplus.go b/extern/rleplus/rleplus.go deleted file mode 100644 index 5d09c2e18..000000000 --- a/extern/rleplus/rleplus.go +++ /dev/null @@ -1,204 +0,0 @@ -package rleplus - -import ( - "encoding/binary" - "errors" - "fmt" - "sort" - - bitvector "github.com/filecoin-project/lotus/extern/rleplus/internal" -) - -// Version is the 2 lowest bits of this constant -const Version = 0 - -var ( - // ErrRunLengthTooLarge - data implies a run-length which isn't supported - ErrRunLengthTooLarge = fmt.Errorf("run length too large for RLE+ version %d", Version) - - // ErrDecode - invalid encoding for this version - ErrDecode = fmt.Errorf("invalid encoding for RLE+ version %d", Version) - - // ErrWrongVersion - wrong version of RLE+ - ErrWrongVersion = errors.New("invalid RLE+ version") -) - -// Encode returns the RLE+ representation of the provided integers. -// Also returned is the number of bits required by this encoding, -// which is not necessarily on a byte boundary. -// -// The RLE+ spec is here: https://github.com/filecoin-project/specs/blob/master/data-structures.md#rle-bitset-encoding -// and is described by the BNF Grammar: -// -// ::=
-//
::= -// ::= "00" -// ::= | "" -// ::= | | -// ::= "1" -// ::= "01" -// ::= "00" -// ::= "0" | "1" -// -// Filecoin specific: -// The encoding is returned as a []byte, each byte packed starting with the low-order bit (LSB0) -func Encode(ints []uint64) ([]byte, uint, error) { - v := bitvector.BitVector{BytePacking: bitvector.LSB0} - firstBit, runs := RunLengths(ints) - - // Add version header - v.Extend(Version, 2, bitvector.LSB0) - - v.Push(firstBit) - - for _, run := range runs { - switch { - case run == 1: - v.Push(1) - case run < 16: - v.Push(0) - v.Push(1) - v.Extend(byte(run), 4, bitvector.LSB0) - case run >= 16: - v.Push(0) - v.Push(0) - // 10 bytes needed to encode MaxUint64 - buf := make([]byte, 10) - numBytes := binary.PutUvarint(buf, run) - for i := 0; i < numBytes; i++ { - v.Extend(buf[i], 8, bitvector.LSB0) - } - default: - return nil, 0, ErrRunLengthTooLarge - } - } - - return v.Buf, v.Len, nil -} - -// Decode returns integers represented by the given RLE+ encoding -// -// The length of the encoding is not specified. It is inferred by -// reading zeroes from the (possibly depleted) BitVector, by virtue -// of the behavior of BitVector.Take() returning 0 when the end of -// the BitVector has been reached. This has the downside of not -// being able to detect corrupt encodings. -// -// The passed []byte should be packed in LSB0 bit numbering -func Decode(buf []byte) (ints []uint64, err error) { - if len(buf) == 0 { - return - } - - v := bitvector.NewBitVector(buf, bitvector.LSB0) - take := v.Iterator(bitvector.LSB0) - - // Read version and check - // Version check - ver := take(2) - if ver != Version { - return nil, ErrWrongVersion - } - - curIdx := uint64(0) - curBit := take(1) - var runLength int - done := false - - for done == false { - y := take(1) - switch y { - case 1: - runLength = 1 - case 0: - val := take(1) - - if val == 1 { - // short block - runLength = int(take(4)) - } else { - // long block - var buf []byte - for { - b := take(8) - buf = append(buf, b) - - if b&0x80 == 0 { - break - } - - // 10 bytes is required to store math.MaxUint64 in a uvarint - if len(buf) > 10 { - return nil, ErrDecode - } - } - x, _ := binary.Uvarint(buf) - - if x == 0 { - done = true - } - runLength = int(x) - } - } - - if curBit == 1 { - for j := 0; j < runLength; j++ { - ints = append(ints, curIdx+uint64(j)) - } - } - curIdx += uint64(runLength) - curBit = 1 - curBit - } - - return -} - -// RunLengths transforms integers into its bit-set-run-length representation. -// -// A set of unsigned integers { 0, 2, 4, 5, 6 } can be thought of as -// indices into a bitset { 1, 0, 1, 0, 1, 1, 1 } where bitset[index] == 1. -// -// The bit set run lengths of this set would then be { 1, 1, 1, 1, 3 }, -// representing lengths of runs alternating between 1 and 0, starting -// with a first bit of 1. -// -// Duplicated numbers are ignored. -// -// This is a helper function for Encode() -func RunLengths(ints []uint64) (firstBit byte, runs []uint64) { - if len(ints) == 0 { - return - } - - // Sort our incoming numbers - sort.Slice(ints, func(i, j int) bool { return ints[i] < ints[j] }) - - prev := ints[0] - - // Initialize our return value - if prev == 0 { - firstBit = 1 - } - - if firstBit == 0 { - // first run of zeroes - runs = append(runs, prev) - } - runs = append(runs, 1) - - for _, cur := range ints[1:] { - delta := cur - prev - switch { - case delta == 1: - runs[len(runs)-1]++ - case delta > 1: - // add run of zeroes if there is a gap - runs = append(runs, delta-1) - runs = append(runs, 1) - default: - // repeated number? - } - prev = cur - } - return -} diff --git a/extern/rleplus/rleplus_test.go b/extern/rleplus/rleplus_test.go deleted file mode 100644 index ecb2259e6..000000000 --- a/extern/rleplus/rleplus_test.go +++ /dev/null @@ -1,213 +0,0 @@ -package rleplus_test - -import ( - "fmt" - "math" - "sort" - "testing" - - "github.com/filecoin-project/lotus/extern/rleplus" - bitvector "github.com/filecoin-project/lotus/extern/rleplus/internal" - "gotest.tools/assert" -) - -func TestRleplus(t *testing.T) { - - t.Run("Encode", func(t *testing.T) { - // Encode an intset - ints := []uint64{ - // run of 1 - 0, - // gap of 1 - // run of 1 - 2, - // gap of 1 - // run of 3 - 4, 5, 6, - // gap of 4 - // run of 17 - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - } - - expectedBits := []byte{ - 0, 0, // version - 1, // first bit - 1, // run of 1 - 1, // gap of 1 - 1, // run of 1 - 1, // gap of 1 - 0, 1, 1, 1, 0, 0, // run of 3 - 0, 1, 0, 0, 1, 0, // gap of 4 - - // run of 17 < 0 0 (varint) > - 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, - } - - v := bitvector.BitVector{} - for _, bit := range expectedBits { - v.Push(bit) - } - actualBytes, _, err := rleplus.Encode(ints) - assert.NilError(t, err) - - assert.Equal(t, len(v.Buf), len(actualBytes)) - for idx, expected := range v.Buf { - assert.Equal( - t, - fmt.Sprintf("%08b", expected), - fmt.Sprintf("%08b", actualBytes[idx]), - ) - } - }) - - t.Run("Encode allows all runs sizes possible uint64", func(t *testing.T) { - // create a run of math.MaxUint64 - ints := []uint64{math.MaxUint64} - - // There would be 64 bits(1) for the UvarInt, totally 9 bytes. - expected := []byte{0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x20} - encodeBytes, _, err := rleplus.Encode(ints) - assert.NilError(t, err) - for idx, v := range encodeBytes { - assert.Equal( - t, - fmt.Sprintf("%8b", v), - fmt.Sprintf("%8b", expected[idx]), - ) - } - }) - - t.Run("Encode for some big numbers", func(t *testing.T) { - // create a run of math.MaxUint64 - ints := make([]uint64, 1024) - - // ints {2^63 .. 2^63+1023} - for i := uint64(0); i < 1024; i++ { - ints[i] = uint64(1)<<63 + i - } - - expected := []byte{0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x40, 0x04} - encodeBytes, _, err := rleplus.Encode(ints) - assert.NilError(t, err) - for idx, v := range encodeBytes { - // fmt.Println(v, expected[idx]) - assert.Equal( - t, - fmt.Sprintf("%8b", v), - fmt.Sprintf("%8b", expected[idx]), - ) - } - }) - - t.Run("Decode", func(t *testing.T) { - testCases := [][]uint64{ - {}, - {1}, - {0}, - {0, 1, 2, 3}, - { - // run of 1 - 0, - // gap of 1 - // run of 1 - 2, - // gap of 1 - // run of 3 - 4, 5, 6, - // gap of 4 - // run of 17 - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - }, - } - - for _, tc := range testCases { - encoded, _, err := rleplus.Encode(tc) - assert.NilError(t, err) - - result, err := rleplus.Decode(encoded) - assert.NilError(t, err) - - sort.Slice(tc, func(i, j int) bool { return tc[i] < tc[j] }) - sort.Slice(result, func(i, j int) bool { return result[i] < result[j] }) - - assert.Equal(t, len(tc), len(result)) - - for idx, expected := range tc { - assert.Equal(t, expected, result[idx]) - } - } - }) - - t.Run("Decode version check", func(t *testing.T) { - _, err := rleplus.Decode([]byte{0xff}) - assert.Error(t, err, "invalid RLE+ version") - }) - - t.Run("Decode returns an error with a bad encoding", func(t *testing.T) { - // create an encoding with a buffer with a run which is too long - _, err := rleplus.Decode([]byte{0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) - assert.Error(t, err, "invalid encoding for RLE+ version 0") - }) - - t.Run("outputs same as reference implementation", func(t *testing.T) { - // Encoding bitvec![LittleEndian; 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - // in the Rust reference implementation gives an encoding of [223, 145, 136, 0] (without version field) - // The bit vector is equivalent to the integer set { 0, 2, 4, 5, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 } - - // This is the above reference output with a version header "00" manually added - referenceEncoding := []byte{124, 71, 34, 2} - - expectedNumbers := []uint64{0, 2, 4, 5, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27} - - encoded, _, err := rleplus.Encode(expectedNumbers) - assert.NilError(t, err) - - // Our encoded bytes are the same as the ref bytes - assert.Equal(t, len(referenceEncoding), len(encoded)) - for idx, expected := range referenceEncoding { - assert.Equal(t, expected, encoded[idx]) - } - - decoded, err := rleplus.Decode(referenceEncoding) - assert.NilError(t, err) - - // Our decoded integers are the same as expected - sort.Slice(decoded, func(i, j int) bool { return decoded[i] < decoded[j] }) - assert.Equal(t, len(expectedNumbers), len(decoded)) - for idx, expected := range expectedNumbers { - assert.Equal(t, expected, decoded[idx]) - } - }) - - t.Run("RunLengths", func(t *testing.T) { - testCases := []struct { - ints []uint64 - first byte - runs []uint64 - }{ - // empty - {}, - - // leading with ones - {[]uint64{0}, 1, []uint64{1}}, - {[]uint64{0, 1}, 1, []uint64{2}}, - {[]uint64{0, 0xffffffff, 0xffffffff + 1}, 1, []uint64{1, 0xffffffff - 1, 2}}, - - // leading with zeroes - {[]uint64{1}, 0, []uint64{1, 1}}, - {[]uint64{2}, 0, []uint64{2, 1}}, - {[]uint64{10, 11, 13, 20}, 0, []uint64{10, 2, 1, 1, 6, 1}}, - {[]uint64{10, 11, 11, 13, 20, 10, 11, 13, 20}, 0, []uint64{10, 2, 1, 1, 6, 1}}, - } - - for _, testCase := range testCases { - first, runs := rleplus.RunLengths(testCase.ints) - assert.Equal(t, testCase.first, first) - assert.Equal(t, len(testCase.runs), len(runs)) - for idx, runLength := range testCase.runs { - assert.Equal(t, runLength, runs[idx]) - } - } - }) -} diff --git a/genesis/types.go b/genesis/types.go index ce690d3d0..4b95d3311 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -28,7 +28,7 @@ type PreSeal struct { type Miner struct { Owner address.Address Worker address.Address - PeerId peer.ID + PeerId peer.ID //nolint:golint MarketBalance abi.TokenAmount PowerBalance abi.TokenAmount diff --git a/lib/addrutil/parse.go b/lib/addrutil/parse.go index fad389e33..f9ee04c3f 100644 --- a/lib/addrutil/parse.go +++ b/lib/addrutil/parse.go @@ -11,7 +11,7 @@ import ( madns "github.com/multiformats/go-multiaddr-dns" ) -// parseAddresses is a function that takes in a slice of string peer addresses +// ParseAddresses is a function that takes in a slice of string peer addresses // (multiaddr + peerid) and returns a slice of properly constructed peers func ParseAddresses(ctx context.Context, addrs []string) ([]peer.AddrInfo, error) { // resolve addresses diff --git a/lib/increadtimeout/incrt.go b/lib/increadtimeout/incrt.go index 95e6c0e42..0b9c65d4d 100644 --- a/lib/increadtimeout/incrt.go +++ b/lib/increadtimeout/incrt.go @@ -57,7 +57,7 @@ func (crt *incrt) Read(buf []byte) (int, error) { n, err := crt.rd.Read(buf) - crt.rd.SetReadDeadline(time.Time{}) + _ = crt.rd.SetReadDeadline(time.Time{}) if err == nil { dur := now().Sub(start) crt.wait -= dur diff --git a/lib/lotuslog/levels.go b/lib/lotuslog/levels.go index faf8fb137..c72d5a9c7 100644 --- a/lib/lotuslog/levels.go +++ b/lib/lotuslog/levels.go @@ -6,6 +6,7 @@ import ( logging "github.com/ipfs/go-log/v2" ) +//nolint:gosec func SetupLogLevels() { if _, set := os.LookupEnv("GOLOG_LOG_LEVEL"); !set { logging.SetLogLevel("*", "INFO") diff --git a/markets/utils/converters.go b/markets/utils/converters.go index 91a1ff8fc..d6316839b 100644 --- a/markets/utils/converters.go +++ b/markets/utils/converters.go @@ -5,7 +5,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin/market" - peer "github.com/libp2p/go-libp2p-peer" + peer "github.com/libp2p/go-libp2p-core/peer" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/storagemarket" diff --git a/node/config/storage.go b/node/config/storage.go index 2d07565cc..2c603df03 100644 --- a/node/config/storage.go +++ b/node/config/storage.go @@ -2,12 +2,13 @@ package config import ( "encoding/json" - "github.com/filecoin-project/sector-storage/stores" "io" "io/ioutil" "os" "golang.org/x/xerrors" + + "github.com/filecoin-project/sector-storage/stores" ) func StorageFromFile(path string, def *stores.StorageConfig) (*stores.StorageConfig, error) { diff --git a/node/hello/hello.go b/node/hello/hello.go index f4e8d421b..a2a5fbd4e 100644 --- a/node/hello/hello.go +++ b/node/hello/hello.go @@ -64,7 +64,7 @@ func (hs *Service) HandleStream(s inet.Stream) { var hmsg HelloMessage if err := cborutil.ReadCborRPC(s, &hmsg); err != nil { log.Infow("failed to read hello message, disconnecting", "error", err) - s.Conn().Close() + _ = s.Conn().Close() return } arrived := time.Now() @@ -76,11 +76,11 @@ func (hs *Service) HandleStream(s inet.Stream) { if hmsg.GenesisHash != hs.syncer.Genesis.Cids()[0] { log.Warnf("other peer has different genesis! (%s)", hmsg.GenesisHash) - s.Conn().Close() + _ = s.Conn().Close() return } go func() { - defer s.Close() + defer s.Close() //nolint:errcheck sent := time.Now() msg := &LatencyMessage{ @@ -152,10 +152,10 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error { } go func() { - defer s.Close() + defer s.Close() //nolint:errcheck lmsg := &LatencyMessage{} - s.SetReadDeadline(time.Now().Add(10 * time.Second)) + _ = s.SetReadDeadline(time.Now().Add(10 * time.Second)) err := cborutil.ReadCborRPC(s, lmsg) if err != nil { log.Infow("reading latency message", "error", err) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 320579ce1..01526fec2 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -427,7 +427,7 @@ func (a *API) ClientGenCar(ctx context.Context, ref api.FileRef, outputPath stri return err } - defer bufferedDS.Remove(ctx, c) + defer bufferedDS.Remove(ctx, c) //nolint:errcheck ssb := builder.NewSelectorSpecBuilder(basicnode.Style.Any) // entire DAG selector @@ -435,7 +435,7 @@ func (a *API) ClientGenCar(ctx context.Context, ref api.FileRef, outputPath stri ssb.ExploreAll(ssb.ExploreRecursiveEdge())).Node() f, err := os.Create(outputPath) - defer f.Close() + defer f.Close() //nolint:errcheck if err != nil { return err } diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 8b00cfb34..f6553fa54 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -425,7 +425,7 @@ func (a *ChainAPI) ChainExport(ctx context.Context, tsk types.TipSetKey) (<-chan r, w := io.Pipe() out := make(chan []byte) go func() { - defer w.Close() + defer w.Close() //nolint:errcheck // it is a pipe if err := a.Chain.Export(ctx, ts, w); err != nil { log.Errorf("chain export call failed: %s", err) return diff --git a/node/impl/remoteworker.go b/node/impl/remoteworker.go index e93ef7d5c..b7cee83ef 100644 --- a/node/impl/remoteworker.go +++ b/node/impl/remoteworker.go @@ -17,7 +17,7 @@ import ( ) type remoteWorker struct { - api.WorkerApi + api.WorkerAPI closer jsonrpc.ClientCloser } diff --git a/node/modules/core.go b/node/modules/core.go index 426705b34..6521b60df 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -34,7 +34,7 @@ func RecordValidator(ps peerstore.Peerstore) record.Validator { } } -const JWTSecretName = "auth-jwt-private" +const JWTSecretName = "auth-jwt-private" //nolint:gosec type jwtPayload struct { Allow []auth.Permission diff --git a/node/modules/lp2p/addrs.go b/node/modules/lp2p/addrs.go index 95971449d..da0de9ad9 100644 --- a/node/modules/lp2p/addrs.go +++ b/node/modules/lp2p/addrs.go @@ -18,7 +18,7 @@ func AddrFilters(filters []string) func() (opts Libp2pOpts, err error) { if err != nil { return opts, fmt.Errorf("incorrectly formatted address filter in config: %s", s) } - opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f)) + opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f)) //golint:staticcheck } return opts, nil } diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index f54a2672e..32002c7c4 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -72,7 +72,7 @@ func GetParams(sbc *ffiwrapper.Config) error { return err } - if err := paramfetch.GetParams(build.ParametersJson(), uint64(ssize)); err != nil { + if err := paramfetch.GetParams(build.ParametersJSON(), uint64(ssize)); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } @@ -167,12 +167,10 @@ func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api lapi.FullNode, h func HandleRetrieval(host host.Host, lc fx.Lifecycle, m retrievalmarket.RetrievalProvider) { lc.Append(fx.Hook{ OnStart: func(context.Context) error { - m.Start() - return nil + return m.Start() }, OnStop: func(context.Context) error { - m.Stop() - return nil + return m.Stop() }, }) } @@ -182,12 +180,10 @@ func HandleDeals(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, h sto lc.Append(fx.Hook{ OnStart: func(context.Context) error { - h.Start(ctx) - return nil + return h.Start(ctx) }, OnStop: func(context.Context) error { - h.Stop() - return nil + return h.Stop() }, }) } diff --git a/node/node_test.go b/node/node_test.go index 0b0af0bcf..a31b4162b 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -84,9 +84,11 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a nic := storedcounter.New(ds, datastore.NewKey(modules.StorageCounterDSPrefix)) for i := 0; i < nGenesisPreseals; i++ { - nic.Next() + _, err := nic.Next() + require.NoError(t, err) } - nic.Next() + _, err = nic.Next() + require.NoError(t, err) err = lr.Close() require.NoError(t, err) diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 322adbdef..b03a6bf37 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -3,7 +3,6 @@ package repo import ( "encoding/json" "fmt" - "github.com/filecoin-project/sector-storage/stores" "io" "io/ioutil" "os" @@ -21,6 +20,8 @@ import ( "github.com/multiformats/go-multiaddr" "golang.org/x/xerrors" + "github.com/filecoin-project/sector-storage/stores" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/config" ) diff --git a/paychmgr/store.go b/paychmgr/store.go index 3a425c4fc..66a514feb 100644 --- a/paychmgr/store.go +++ b/paychmgr/store.go @@ -115,7 +115,7 @@ func (ps *Store) ListChannels() ([]address.Address, error) { if err != nil { return nil, err } - defer res.Close() + defer res.Close() //nolint:errcheck var out []address.Address for { @@ -144,7 +144,7 @@ func (ps *Store) findChan(filter func(*ChannelInfo) bool) (address.Address, erro if err != nil { return address.Undef, err } - defer res.Close() + defer res.Close() //nolint:errcheck var ci ChannelInfo diff --git a/storage/miner.go b/storage/miner.go index 779f981e9..57b162622 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -107,14 +107,13 @@ func (m *Miner) Run(ctx context.Context) error { pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, 10000000, md.PeriodStart%miner.WPoStProvingPeriod) m.sealing = sealing.New(adaptedAPI, NewEventsAdapter(evts), m.maddr, m.ds, m.sealer, m.sc, m.verif, &pcp) - go m.sealing.Run(ctx) + go m.sealing.Run(ctx) //nolint:errcheck // logged intside the function return nil } func (m *Miner) Stop(ctx context.Context) error { - defer m.sealing.Stop(ctx) - return nil + return m.sealing.Stop(ctx) } func (m *Miner) runPreflightChecks(ctx context.Context) error { From f26a336afb77ffa75775b38de86b4497f96e32bd Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 28 May 2020 00:45:17 +0200 Subject: [PATCH 010/379] Use git.base_revision Signed-off-by: Jakub Sztandera --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ddcbd5481..be4ab11ce 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -331,7 +331,7 @@ workflows: ci: jobs: - lint-changes: - args: "--new-from-rev origin/master" + args: "--new-from-rev << pipeline.git.base_revision >>" - test: codecov-upload: true - mod-tidy-check From 7232e5481c9edb65a87fdffab420455b3a94ed1d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 28 May 2020 00:49:52 +0200 Subject: [PATCH 011/379] Use origin/next for linting Signed-off-by: Jakub Sztandera --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index be4ab11ce..312aa42ca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -331,7 +331,7 @@ workflows: ci: jobs: - lint-changes: - args: "--new-from-rev << pipeline.git.base_revision >>" + args: "--new-from-rev origin/next" - test: codecov-upload: true - mod-tidy-check From b372881e91b9059fa317a335371991bfa524e619 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 28 May 2020 01:15:19 +0200 Subject: [PATCH 012/379] Fix more lint warnings Signed-off-by: Jakub Sztandera --- cli/multisig.go | 2 +- cmd/lotus-bench/main.go | 2 +- cmd/lotus-seed/seed/seed.go | 2 +- cmd/lotus-storage-miner/init.go | 2 +- lib/lotuslog/levels.go | 19 +++++++++---------- node/impl/client/client.go | 3 +-- node/modules/lp2p/addrs.go | 2 +- 7 files changed, 15 insertions(+), 17 deletions(-) diff --git a/cli/multisig.go b/cli/multisig.go index 9acf1af08..37106dff5 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -207,7 +207,7 @@ var msigInspectCmd = &cli.Command{ fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%d\t%x\n", txid, state(tx), tx.To, types.FIL(tx.Value), tx.Method, tx.Params) } if err := w.Flush(); err != nil { - return xerrors.Errorf("flushing ouput: %+v", err) + return xerrors.Errorf("flushing output: %+v", err) } } diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index b8740f2f3..cbb59309d 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -157,7 +157,7 @@ var sealBenchCmd = &cli.Command{ return err } - err = os.MkdirAll(sdir, 0775) + err = os.MkdirAll(sdir, 0775) //nolint:gosec if err != nil { return xerrors.Errorf("creating sectorbuilder dir: %w", err) } diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 0f6539563..06cb011b4 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -48,7 +48,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum SealProofType: spt, } - if err := os.MkdirAll(sbroot, 0775); err != nil { //golint:gosec + if err := os.MkdirAll(sbroot, 0775); err != nil { //nolint:gosec return nil, nil, err } diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 7a6ac8257..0dcc9563b 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -389,7 +389,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, if err != nil { return err } - defer lr.Close() //notlint:errcheck + defer lr.Close() //nolint:errcheck log.Info("Initializing libp2p identity") diff --git a/lib/lotuslog/levels.go b/lib/lotuslog/levels.go index c72d5a9c7..ae3959568 100644 --- a/lib/lotuslog/levels.go +++ b/lib/lotuslog/levels.go @@ -6,17 +6,16 @@ import ( logging "github.com/ipfs/go-log/v2" ) -//nolint:gosec func SetupLogLevels() { if _, set := os.LookupEnv("GOLOG_LOG_LEVEL"); !set { - logging.SetLogLevel("*", "INFO") - logging.SetLogLevel("dht", "ERROR") - logging.SetLogLevel("swarm2", "WARN") - logging.SetLogLevel("bitswap", "WARN") - //logging.SetLogLevel("pubsub", "WARN") - logging.SetLogLevel("connmgr", "WARN") - logging.SetLogLevel("advmgr", "DEBUG") - logging.SetLogLevel("stores", "DEBUG") - logging.SetLogLevel("nat", "INFO") + _ = logging.SetLogLevel("*", "INFO") + _ = logging.SetLogLevel("dht", "ERROR") + _ = logging.SetLogLevel("swarm2", "WARN") + _ = logging.SetLogLevel("bitswap", "WARN") + //_ = logging.SetLogLevel("pubsub", "WARN") + _ = logging.SetLogLevel("connmgr", "WARN") + _ = logging.SetLogLevel("advmgr", "DEBUG") + _ = logging.SetLogLevel("stores", "DEBUG") + _ = logging.SetLogLevel("nat", "INFO") } } diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 01526fec2..7d6d5369b 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -435,7 +435,6 @@ func (a *API) ClientGenCar(ctx context.Context, ref api.FileRef, outputPath stri ssb.ExploreAll(ssb.ExploreRecursiveEdge())).Node() f, err := os.Create(outputPath) - defer f.Close() //nolint:errcheck if err != nil { return err } @@ -445,7 +444,7 @@ func (a *API) ClientGenCar(ctx context.Context, ref api.FileRef, outputPath stri return err } - return nil + return f.Close() } func (a *API) clientImport(ref api.FileRef, bufferedDS *ipld.BufferedDAG) (cid.Cid, error) { diff --git a/node/modules/lp2p/addrs.go b/node/modules/lp2p/addrs.go index da0de9ad9..afb8ce910 100644 --- a/node/modules/lp2p/addrs.go +++ b/node/modules/lp2p/addrs.go @@ -18,7 +18,7 @@ func AddrFilters(filters []string) func() (opts Libp2pOpts, err error) { if err != nil { return opts, fmt.Errorf("incorrectly formatted address filter in config: %s", s) } - opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f)) //golint:staticcheck + opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f)) //nolint:staticcheck } return opts, nil } From 8639409f740855ae92454c8e77afa76ed55db00d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 28 May 2020 01:16:01 +0200 Subject: [PATCH 013/379] go mod tidy , Signed-off-by: Jakub Sztandera --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index b8fa35330..63a3a07dd 100644 --- a/go.mod +++ b/go.mod @@ -113,7 +113,6 @@ require ( golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 - gotest.tools v2.2.0+incompatible launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect ) From de3edc2ec7657cd8c1227f5239ecdf115c11fcaf Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Fri, 22 May 2020 11:51:18 -0300 Subject: [PATCH 014/379] remote ipfs support & automatic env Signed-off-by: Ignacio Hagopian --- go.mod | 1 + go.sum | 2 ++ lib/ipfsbstore/ipfsbstore.go | 13 +++++++++++++ node/builder.go | 6 ++++++ node/config/def.go | 3 ++- node/config/load.go | 7 +++++++ node/modules/ipfsclient.go | 19 +++++++++++++++++++ node/repo/fsrepo.go | 5 +++-- 8 files changed, 53 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b8fa35330..aae4a9bbb 100644 --- a/go.mod +++ b/go.mod @@ -69,6 +69,7 @@ require ( github.com/ipfs/interface-go-ipfs-core v0.2.3 github.com/ipld/go-car v0.1.1-0.20200430185908-8ff2e52a4c88 github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e + github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.2.0 github.com/libp2p/go-eventbus v0.1.0 github.com/libp2p/go-libp2p v0.9.2 diff --git a/go.sum b/go.sum index 61e846c3d..dc9608cc9 100644 --- a/go.sum +++ b/go.sum @@ -560,6 +560,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3 h1:Iy7Ifq2ysilWU4QlCx/97OoI4xT1IV7i8byT/EyIT/M= github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3/go.mod h1:BYpt4ufZiIGv2nXn4gMxnfKV306n3mWXgNu/d2TqdTU= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= diff --git a/lib/ipfsbstore/ipfsbstore.go b/lib/ipfsbstore/ipfsbstore.go index a79407f5a..33110e295 100644 --- a/lib/ipfsbstore/ipfsbstore.go +++ b/lib/ipfsbstore/ipfsbstore.go @@ -7,6 +7,7 @@ import ( "golang.org/x/xerrors" + "github.com/multiformats/go-multiaddr" "github.com/multiformats/go-multihash" blocks "github.com/ipfs/go-block-format" @@ -35,6 +36,18 @@ func NewIpfsBstore(ctx context.Context) (*IpfsBstore, error) { }, nil } +func NewRemoteIpfsBstore(ctx context.Context, maddr multiaddr.Multiaddr) (*IpfsBstore, error) { + api, err := httpapi.NewApi(maddr) + if err != nil { + return nil, xerrors.Errorf("getting remote ipfs api: %w", err) + } + + return &IpfsBstore{ + ctx: ctx, + api: api, + }, nil +} + func (i *IpfsBstore) DeleteBlock(cid cid.Cid) error { return xerrors.Errorf("not supported") } diff --git a/node/builder.go b/node/builder.go index 0154f1494..5fe1e4346 100644 --- a/node/builder.go +++ b/node/builder.go @@ -378,11 +378,17 @@ func ConfigFullNode(c interface{}) Option { return Error(xerrors.Errorf("invalid config from repo, got: %T", c)) } + remoteIpfsMaddrNotEmpty := func(s *Settings) bool { + return len(cfg.Client.RemoteIpfsMAddr) > 0 + } + return Options( ConfigCommon(&cfg.Common), If(cfg.Client.UseIpfs, Override(new(dtypes.ClientBlockstore), modules.IpfsClientBlockstore), ), + ApplyIf(remoteIpfsMaddrNotEmpty, + Override(new(dtypes.ClientBlockstore), modules.IpfsRemoteClientBlockstore(cfg.Client.RemoteIpfsMAddr))), If(cfg.Metrics.HeadNotifs, Override(HeadMetricsKey, metrics.SendHeadNotifs(cfg.Metrics.Nickname)), diff --git a/node/config/def.go b/node/config/def.go index 72fdde4ff..eea38965b 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -62,7 +62,8 @@ type Metrics struct { } type Client struct { - UseIpfs bool + UseIpfs bool + RemoteIpfsMAddr string } func defCommon() Common { diff --git a/node/config/load.go b/node/config/load.go index 352d17197..1590efedb 100644 --- a/node/config/load.go +++ b/node/config/load.go @@ -2,10 +2,12 @@ package config import ( "bytes" + "fmt" "io" "os" "github.com/BurntSushi/toml" + "github.com/kelseyhightower/envconfig" "golang.org/x/xerrors" ) @@ -32,6 +34,11 @@ func FromReader(reader io.Reader, def interface{}) (interface{}, error) { return nil, err } + err = envconfig.Process("LOTUS", cfg) + if err != nil { + return nil, fmt.Errorf("processing env vars overrides: %s", err) + } + return cfg, nil } diff --git a/node/modules/ipfsclient.go b/node/modules/ipfsclient.go index 8898e4cd1..373f8531f 100644 --- a/node/modules/ipfsclient.go +++ b/node/modules/ipfsclient.go @@ -6,6 +6,7 @@ import ( "github.com/ipfs/go-filestore" blockstore "github.com/ipfs/go-ipfs-blockstore" + "github.com/multiformats/go-multiaddr" "github.com/filecoin-project/lotus/lib/bufbstore" "github.com/filecoin-project/lotus/lib/ipfsbstore" @@ -24,3 +25,21 @@ func IpfsClientBlockstore(mctx helpers.MetricsCtx, lc fx.Lifecycle, fstore dtype blockstore.NewIdStore((*filestore.Filestore)(fstore)), ), nil } + +func IpfsRemoteClientBlockstore(ipfsMaddr string) func(helpers.MetricsCtx, fx.Lifecycle, dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, fstore dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { + ma, err := multiaddr.NewMultiaddr(ipfsMaddr) + if err != nil { + return nil, xerrors.Errorf("parsing ipfs multiaddr: %w", err) + } + ipfsbs, err := ipfsbstore.NewRemoteIpfsBstore(helpers.LifecycleCtx(mctx, lc), ma) + if err != nil { + return nil, xerrors.Errorf("constructing ipfs blockstore: %w", err) + } + + return bufbstore.NewTieredBstore( + ipfsbs, + blockstore.NewIdStore((*filestore.Filestore)(fstore)), + ), nil + } +} diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 322adbdef..830de3b24 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -3,7 +3,6 @@ package repo import ( "encoding/json" "fmt" - "github.com/filecoin-project/sector-storage/stores" "io" "io/ioutil" "os" @@ -11,6 +10,8 @@ import ( "strings" "sync" + "github.com/filecoin-project/sector-storage/stores" + "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" badger "github.com/ipfs/go-ds-badger2" @@ -276,7 +277,7 @@ func (fsr *fsLockedRepo) Datastore(ns string) (datastore.Batching, error) { return namespace.Wrap(fsr.ds, datastore.NewKey(ns)), nil } -func (fsr *fsLockedRepo) Config() (interface{}, error) { +func (fsr *fsLockedRepo) Config() (df interface{}, err error) { if err := fsr.stillValid(); err != nil { return nil, err } From 0af7cd14483bbc6481fc642c99dd211aaddb0611 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 26 May 2020 09:50:35 -0300 Subject: [PATCH 015/379] allow using ipfs for retrieval Signed-off-by: Ignacio Hagopian --- node/builder.go | 11 +++-------- node/config/def.go | 5 +++-- node/modules/ipfsclient.go | 36 +++++++++++++++++------------------- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/node/builder.go b/node/builder.go index 5fe1e4346..d054be7a5 100644 --- a/node/builder.go +++ b/node/builder.go @@ -378,18 +378,13 @@ func ConfigFullNode(c interface{}) Option { return Error(xerrors.Errorf("invalid config from repo, got: %T", c)) } - remoteIpfsMaddrNotEmpty := func(s *Settings) bool { - return len(cfg.Client.RemoteIpfsMAddr) > 0 - } - + ipfsMaddr := cfg.Client.IpfsMAddr + useForRetrieval := cfg.Client.IpfsUseForRetrieval return Options( ConfigCommon(&cfg.Common), If(cfg.Client.UseIpfs, - Override(new(dtypes.ClientBlockstore), modules.IpfsClientBlockstore), + Override(new(dtypes.ClientBlockstore), modules.IpfsClientBlockstore(ipfsMaddr, useForRetrieval)), ), - ApplyIf(remoteIpfsMaddrNotEmpty, - Override(new(dtypes.ClientBlockstore), modules.IpfsRemoteClientBlockstore(cfg.Client.RemoteIpfsMAddr))), - If(cfg.Metrics.HeadNotifs, Override(HeadMetricsKey, metrics.SendHeadNotifs(cfg.Metrics.Nickname)), ), diff --git a/node/config/def.go b/node/config/def.go index eea38965b..d5c64d40d 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -62,8 +62,9 @@ type Metrics struct { } type Client struct { - UseIpfs bool - RemoteIpfsMAddr string + UseIpfs bool + IpfsMAddr string + IpfsUseForRetrieval bool } func defCommon() Common { diff --git a/node/modules/ipfsclient.go b/node/modules/ipfsclient.go index 373f8531f..c3710de1c 100644 --- a/node/modules/ipfsclient.go +++ b/node/modules/ipfsclient.go @@ -14,32 +14,30 @@ import ( "github.com/filecoin-project/lotus/node/modules/helpers" ) -func IpfsClientBlockstore(mctx helpers.MetricsCtx, lc fx.Lifecycle, fstore dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { - ipfsbs, err := ipfsbstore.NewIpfsBstore(helpers.LifecycleCtx(mctx, lc)) - if err != nil { - return nil, xerrors.Errorf("constructing ipfs blockstore: %w", err) - } - - return bufbstore.NewTieredBstore( - ipfsbs, - blockstore.NewIdStore((*filestore.Filestore)(fstore)), - ), nil -} - -func IpfsRemoteClientBlockstore(ipfsMaddr string) func(helpers.MetricsCtx, fx.Lifecycle, dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { +// IpfsClientBlockstore returns a ClientBlockstore implementation backed by an IPFS node. +// If ipfsMaddr is empty, a local IPFS node is assumed considering IPFS_PATH configuration. +// If ipfsMaddr is not empty, it will connect to the remote IPFS node with the provided multiaddress. +// The flag useForRetrieval indicates if the IPFS node will also be used for storing retrieving deals. +func IpfsClientBlockstore(ipfsMaddr string, useForRetrieval bool) func(helpers.MetricsCtx, fx.Lifecycle, dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, fstore dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { ma, err := multiaddr.NewMultiaddr(ipfsMaddr) if err != nil { return nil, xerrors.Errorf("parsing ipfs multiaddr: %w", err) } - ipfsbs, err := ipfsbstore.NewRemoteIpfsBstore(helpers.LifecycleCtx(mctx, lc), ma) + var ipfsbs *ipfsbstore.IpfsBstore + if ipfsMaddr != "" { + ipfsbs, err = ipfsbstore.NewRemoteIpfsBstore(helpers.LifecycleCtx(mctx, lc), ma) + } else { + ipfsbs, err = ipfsbstore.NewIpfsBstore(helpers.LifecycleCtx(mctx, lc)) + } if err != nil { return nil, xerrors.Errorf("constructing ipfs blockstore: %w", err) } - - return bufbstore.NewTieredBstore( - ipfsbs, - blockstore.NewIdStore((*filestore.Filestore)(fstore)), - ), nil + var ws blockstore.Blockstore + ws = ipfsbs + if !useForRetrieval { + ws = blockstore.NewIdStore((*filestore.Filestore)(fstore)) + } + return bufbstore.NewTieredBstore(ipfsbs, ws), nil } } From 10753f14d0ea156da12ed9a748b34ebd8749e7e3 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 26 May 2020 12:36:21 -0300 Subject: [PATCH 016/379] retrieve: make fileref optional Signed-off-by: Ignacio Hagopian --- api/api_full.go | 2 +- api/apistruct/struct.go | 4 ++-- api/test/deals.go | 2 +- cli/client.go | 2 +- node/impl/client/client.go | 7 ++++++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 9026bf2d5..c6d442e2b 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -117,7 +117,7 @@ type FullNode interface { ClientListDeals(ctx context.Context) ([]DealInfo, error) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) - ClientRetrieve(ctx context.Context, order RetrievalOrder, ref FileRef) error + ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*CommPRet, error) ClientGenCar(ctx context.Context, ref FileRef, outpath string) error diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 368a2b145..f0be44070 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -110,7 +110,7 @@ type FullNodeStruct struct { ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"` - ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref api.FileRef) error `perm:"admin"` + ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"` ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"` ClientCalcCommP func(ctx context.Context, inpath string, miner address.Address) (*api.CommPRet, error) `perm:"read"` ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"` @@ -321,7 +321,7 @@ func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]api.DealInfo, e return c.Internal.ClientListDeals(ctx) } -func (c *FullNodeStruct) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref api.FileRef) error { +func (c *FullNodeStruct) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error { return c.Internal.ClientRetrieve(ctx, order, ref) } diff --git a/api/test/deals.go b/api/test/deals.go index 2414d3fe2..625be4583 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -200,7 +200,7 @@ func testRetrieval(t *testing.T, ctx context.Context, err error, client *impl.Fu t.Fatal(err) } - ref := api.FileRef{ + ref := &api.FileRef{ Path: filepath.Join(rpath, "ret"), IsCAR: carExport, } diff --git a/cli/client.go b/cli/client.go index 7f7e5e6c4..3bfc5de70 100644 --- a/cli/client.go +++ b/cli/client.go @@ -384,7 +384,7 @@ var clientRetrieveCmd = &cli.Command{ return nil } - ref := lapi.FileRef{ + ref := &lapi.FileRef{ Path: cctx.Args().Get(1), IsCAR: cctx.Bool("car"), } diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 320579ce1..ff974e8b2 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -302,7 +302,7 @@ func (a *API) ClientListImports(ctx context.Context) ([]api.Import, error) { } } -func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref api.FileRef) error { +func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error { if order.MinerPeerID == "" { mi, err := a.StateMinerInfo(ctx, order.Miner, types.EmptyTSK) if err != nil { @@ -353,6 +353,11 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref unsubscribe() + // If ref is nil, it only fetches the data into the configured blockstore. + if ref == nil { + return nil + } + if ref.IsCAR { f, err := os.OpenFile(ref.Path, os.O_CREATE|os.O_WRONLY, 0644) if err != nil { From 6e63ea6cce527ce14c9be36f3a0e428472fe7ec8 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 26 May 2020 15:35:20 -0300 Subject: [PATCH 017/379] revert file Signed-off-by: Ignacio Hagopian --- node/repo/fsrepo.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 830de3b24..322adbdef 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -3,6 +3,7 @@ package repo import ( "encoding/json" "fmt" + "github.com/filecoin-project/sector-storage/stores" "io" "io/ioutil" "os" @@ -10,8 +11,6 @@ import ( "strings" "sync" - "github.com/filecoin-project/sector-storage/stores" - "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" badger "github.com/ipfs/go-ds-badger2" @@ -277,7 +276,7 @@ func (fsr *fsLockedRepo) Datastore(ns string) (datastore.Batching, error) { return namespace.Wrap(fsr.ds, datastore.NewKey(ns)), nil } -func (fsr *fsLockedRepo) Config() (df interface{}, err error) { +func (fsr *fsLockedRepo) Config() (interface{}, error) { if err := fsr.stillValid(); err != nil { return nil, err } From 17c378c18af7755e335f38e96d5fb0f66818f720 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Wed, 27 May 2020 09:50:32 -0300 Subject: [PATCH 018/379] fix Signed-off-by: Ignacio Hagopian --- node/modules/ipfsclient.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/node/modules/ipfsclient.go b/node/modules/ipfsclient.go index c3710de1c..f405cb4c6 100644 --- a/node/modules/ipfsclient.go +++ b/node/modules/ipfsclient.go @@ -20,12 +20,14 @@ import ( // The flag useForRetrieval indicates if the IPFS node will also be used for storing retrieving deals. func IpfsClientBlockstore(ipfsMaddr string, useForRetrieval bool) func(helpers.MetricsCtx, fx.Lifecycle, dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, fstore dtypes.ClientFilestore) (dtypes.ClientBlockstore, error) { - ma, err := multiaddr.NewMultiaddr(ipfsMaddr) - if err != nil { - return nil, xerrors.Errorf("parsing ipfs multiaddr: %w", err) - } + var err error var ipfsbs *ipfsbstore.IpfsBstore if ipfsMaddr != "" { + var ma multiaddr.Multiaddr + ma, err = multiaddr.NewMultiaddr(ipfsMaddr) + if err != nil { + return nil, xerrors.Errorf("parsing ipfs multiaddr: %w", err) + } ipfsbs, err = ipfsbstore.NewRemoteIpfsBstore(helpers.LifecycleCtx(mctx, lc), ma) } else { ipfsbs, err = ipfsbstore.NewIpfsBstore(helpers.LifecycleCtx(mctx, lc)) From 495554e565c4f74391c100ad6ae93d2be827bb1a Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 26 May 2020 20:47:00 +0300 Subject: [PATCH 019/379] gomod: update go-libp2p-pubsub@v0.3.1 --- go.mod | 2 +- go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index aae4a9bbb..b587919c2 100644 --- a/go.mod +++ b/go.mod @@ -80,7 +80,7 @@ require ( github.com/libp2p/go-libp2p-mplex v0.2.3 github.com/libp2p/go-libp2p-peer v0.2.0 github.com/libp2p/go-libp2p-peerstore v0.2.4 - github.com/libp2p/go-libp2p-pubsub v0.3.0 + github.com/libp2p/go-libp2p-pubsub v0.3.1 github.com/libp2p/go-libp2p-quic-transport v0.1.1 github.com/libp2p/go-libp2p-record v0.1.2 github.com/libp2p/go-libp2p-routing-helpers v0.2.1 diff --git a/go.sum b/go.sum index dc9608cc9..29cd94e09 100644 --- a/go.sum +++ b/go.sum @@ -206,6 +206,7 @@ github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95 h1 github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go.mod h1:1UpuWCUC7XNfgyufyQQq+/40JSzhfGdgcwauK55C8gk= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= +github.com/filecoin-project/specs-actors v0.2.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.5.2/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461 h1:yyAoJ9dNboljDWj0uBdJEbdaTak/YhkjYUQt0GzlY0A= @@ -726,8 +727,8 @@ github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYc github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= -github.com/libp2p/go-libp2p-pubsub v0.3.0 h1:K5FSYyfcSrJWrGExgdbogCLMqwC3pQaXEVt2CaUy1SA= -github.com/libp2p/go-libp2p-pubsub v0.3.0/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= +github.com/libp2p/go-libp2p-pubsub v0.3.1 h1:7Hyv2d8BK/x1HGRJTZ8X++VQEP+WqDTSwpUSZGTVLYA= +github.com/libp2p/go-libp2p-pubsub v0.3.1/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-quic-transport v0.1.1 h1:MFMJzvsxIEDEVKzO89BnB/FgvMj9WI4GDGUW2ArDPUA= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= From f1ccbe496a74ce18d42f8e10c77cad2978698e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 27 May 2020 10:13:06 +0200 Subject: [PATCH 020/379] cli: Trim spaces from token file --- node/repo/fsrepo.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 322adbdef..396fbf67e 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -1,9 +1,9 @@ package repo import ( + "bytes" "encoding/json" "fmt" - "github.com/filecoin-project/sector-storage/stores" "io" "io/ioutil" "os" @@ -21,6 +21,8 @@ import ( "github.com/multiformats/go-multiaddr" "golang.org/x/xerrors" + "github.com/filecoin-project/sector-storage/stores" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/config" ) @@ -191,7 +193,12 @@ func (fsr *FsRepo) APIToken() ([]byte, error) { } defer f.Close() //nolint: errcheck // Read only op - return ioutil.ReadAll(f) + tb, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + + return bytes.TrimSpace(tb), nil } // Lock acquires exclusive lock on this repo From be1bbe88b0408ad3dcb24053721a7ca52bf8d2d5 Mon Sep 17 00:00:00 2001 From: frrist Date: Thu, 21 May 2020 11:17:34 -0700 Subject: [PATCH 021/379] update chain-val syscalls interface --- chain/validation/applier.go | 8 +++++--- chain/validation/factories.go | 19 +++---------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/chain/validation/applier.go b/chain/validation/applier.go index 5289f840b..f30c543bb 100644 --- a/chain/validation/applier.go +++ b/chain/validation/applier.go @@ -9,6 +9,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/specs-actors/actors/puppet" + "github.com/filecoin-project/specs-actors/actors/runtime" "github.com/ipfs/go-cid" vtypes "github.com/filecoin-project/chain-validation/chain/types" @@ -24,12 +25,13 @@ import ( // Applier applies messages to state trees and storage. type Applier struct { stateWrapper *StateWrapper + syscalls runtime.Syscalls } var _ vstate.Applier = &Applier{} -func NewApplier(sw *StateWrapper) *Applier { - return &Applier{sw} +func NewApplier(sw *StateWrapper, syscalls runtime.Syscalls) *Applier { + return &Applier{sw, syscalls} } func (a *Applier) ApplyMessage(epoch abi.ChainEpoch, message *vtypes.Message) (vtypes.ApplyMessageResult, error) { @@ -65,7 +67,7 @@ func (a *Applier) ApplySignedMessage(epoch abi.ChainEpoch, msg *vtypes.SignedMes } func (a *Applier) ApplyTipSetMessages(epoch abi.ChainEpoch, blocks []vtypes.BlockMessagesInfo, rnd vstate.RandomnessSource) (vtypes.ApplyTipSetResult, error) { - cs := store.NewChainStore(a.stateWrapper.bs, a.stateWrapper.ds, vdrivers.NewChainValidationSyscalls()) + cs := store.NewChainStore(a.stateWrapper.bs, a.stateWrapper.ds, a.syscalls) sm := stmgr.NewStateManager(cs) var bms []stmgr.BlockMessages diff --git a/chain/validation/factories.go b/chain/validation/factories.go index 223382538..d3771d87d 100644 --- a/chain/validation/factories.go +++ b/chain/validation/factories.go @@ -1,11 +1,9 @@ package validation import ( - "context" + "github.com/filecoin-project/specs-actors/actors/runtime" vstate "github.com/filecoin-project/chain-validation/state" - "github.com/filecoin-project/specs-actors/actors/abi" - acrypto "github.com/filecoin-project/specs-actors/actors/crypto" ) type Factories struct { @@ -18,26 +16,15 @@ func NewFactories() *Factories { return &Factories{} } -func (f *Factories) NewStateAndApplier() (vstate.VMWrapper, vstate.Applier) { +func (f *Factories) NewStateAndApplier(syscalls runtime.Syscalls) (vstate.VMWrapper, vstate.Applier) { st := NewState() - return st, NewApplier(st) + return st, NewApplier(st, syscalls) } func (f *Factories) NewKeyManager() vstate.KeyManager { return newKeyManager() } -type fakeRandSrc struct { -} - -func (r fakeRandSrc) Randomness(_ context.Context, _ acrypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) (abi.Randomness, error) { - return abi.Randomness("sausages"), nil -} - -func (f *Factories) NewRandomnessSource() vstate.RandomnessSource { - return &fakeRandSrc{} -} - func (f *Factories) NewValidationConfig() vstate.ValidationConfig { trackGas := true checkExit := true From 9f8ecb0ac4d499b263caa0580af78b4e8f1e136e Mon Sep 17 00:00:00 2001 From: frrist Date: Tue, 26 May 2020 10:32:21 -0700 Subject: [PATCH 022/379] update chain-validation - has new syscalls --- chain/validation/applier.go | 3 +-- go.mod | 4 ++-- go.sum | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/chain/validation/applier.go b/chain/validation/applier.go index f30c543bb..6c1629104 100644 --- a/chain/validation/applier.go +++ b/chain/validation/applier.go @@ -13,7 +13,6 @@ import ( "github.com/ipfs/go-cid" vtypes "github.com/filecoin-project/chain-validation/chain/types" - vdrivers "github.com/filecoin-project/chain-validation/drivers" vstate "github.com/filecoin-project/chain-validation/state" "github.com/filecoin-project/lotus/chain/stmgr" @@ -136,7 +135,7 @@ func (a *Applier) applyMessage(epoch abi.ChainEpoch, lm types.ChainMsg) (vtypes. ctx := context.TODO() base := a.stateWrapper.Root() - lotusVM, err := vm.NewVM(base, epoch, &vmRand{}, a.stateWrapper.bs, vdrivers.NewChainValidationSyscalls()) + lotusVM, err := vm.NewVM(base, epoch, &vmRand{}, a.stateWrapper.bs, a.syscalls) // need to modify the VM invoker to add the puppet actor chainValInvoker := vm.NewInvoker() chainValInvoker.Register(puppet.PuppetActorCodeID, puppet.Actor{}, puppet.State{}) diff --git a/go.mod b/go.mod index b587919c2..642b3576c 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,8 @@ require ( github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 - github.com/filecoin-project/chain-validation v0.0.6-0.20200518190139-483332336e8e - github.com/filecoin-project/filecoin-ffi v0.0.0-20200427223233-a0014b17f124 + github.com/filecoin-project/chain-validation v0.0.6-0.20200526171800-c56c1882dc99 + github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 github.com/filecoin-project/go-bitfield v0.0.1 diff --git a/go.sum b/go.sum index 29cd94e09..f25e4f97e 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= -github.com/filecoin-project/chain-validation v0.0.6-0.20200518190139-483332336e8e h1:3x2eL2t3ZkMOHt1b5WS5aVWyJeo5+WjWCT77QdPGSwk= -github.com/filecoin-project/chain-validation v0.0.6-0.20200518190139-483332336e8e/go.mod h1:6B3uenDcH8n+PKqgzUtZmgyCzKy4qpiLwJ5aw7Rj2xQ= +github.com/filecoin-project/chain-validation v0.0.6-0.20200526171800-c56c1882dc99 h1:jVuyHbsCX/w4vZ+3pO0cqzOyqvwfo8tB94wzmcwaD2k= +github.com/filecoin-project/chain-validation v0.0.6-0.20200526171800-c56c1882dc99/go.mod h1:hMqMCTt3z+wZ+GL74uy7X4NptnucZTTrb5SUTt1L/0g= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= From 514339e855a20df8c09e0d6ac0d66705b0374640 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Wed, 27 May 2020 17:12:45 -0400 Subject: [PATCH 023/379] update systemd services; include make directives and docs for use --- Makefile | 12 ++++++++ documentation/en/install-systemd-services.md | 29 ++++++++++++++++++++ scripts/lotus-daemon.service | 4 +++ 3 files changed, 45 insertions(+) create mode 100644 documentation/en/install-systemd-services.md diff --git a/Makefile b/Makefile index a189ccca2..37f07b0b6 100644 --- a/Makefile +++ b/Makefile @@ -103,6 +103,18 @@ install: install -C ./lotus-storage-miner /usr/local/bin/lotus-storage-miner install -C ./lotus-seal-worker /usr/local/bin/lotus-seal-worker +install-services: + install -C -m 0644 ./scripts/lotus-daemon.service /etc/systemd/system/lotus-daemon.service + install -C -m 0644 ./scripts/lotus-miner.service /etc/systemd/system/lotus-miner.service + systemctl daemon-reload + @echo + @echo "lotus and lotus-miner services installed. Don't forget to 'systemctl enable lotus|lotus-miner' for it to be enabled on startup." + +clean-services: + rm -f /etc/systemd/system/lotus-daemon.service + rm -f /etc/systemd/system/lotus-miner.service + systemctl daemon-reload + # TOOLS lotus-seed: $(BUILD_DEPS) diff --git a/documentation/en/install-systemd-services.md b/documentation/en/install-systemd-services.md new file mode 100644 index 000000000..8c83d56a1 --- /dev/null +++ b/documentation/en/install-systemd-services.md @@ -0,0 +1,29 @@ +# Lotus and Miner as a systemd service + +Lotus is capable of running as a systemd service daemon. You can find installable service files for systemd in the [lotus repo](https://github.com/filecoin-project/lotus/tree/master/scripts) as files with `.service` extension. In order to install these service files, you can copy these `.service` files to the default systemd service path. + +## Installing via `make` + +NOTE: Before using lotus and lotus-miner as systemd services, don't forget to `sudo make install` to ensure the binaries are accessible by the root user. + +If your host uses the default systemd service path, it can be installed with `sudo make install-services`: + +```sh +$ sudo make install-services +``` + +## Interacting with service logs + +Logs from the services can be reviewed using `journalctl`. + +### Follow logs from a specific service unit + +```sh +$ sudo journalctl -u lotus-daemon -f +``` + +### View logs in reverse order + +```sh +$ sudo journalctl -u lotus-miner -r +``` diff --git a/scripts/lotus-daemon.service b/scripts/lotus-daemon.service index 44b2058b0..86f0dff27 100644 --- a/scripts/lotus-daemon.service +++ b/scripts/lotus-daemon.service @@ -6,6 +6,10 @@ After=network.target ExecStart=/usr/local/bin/lotus daemon Environment=GOLOG_FILE="/var/log/lotus-daemon" Environment=GOLOG_LOG_FMT="json" +MemoryAccounting=true +MemoryHigh=8G +MemoryMax=10G +LimitNOFILE=8192:10240 [Install] WantedBy=multiuser.target From 8e55c91cd232d71a4ec8c134fbf7a01952c13b4b Mon Sep 17 00:00:00 2001 From: Jeromy Date: Thu, 28 May 2020 08:45:34 -0700 Subject: [PATCH 024/379] check neq zero exit code --- storage/wdpost_run.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index cfee3cde3..63109e5f5 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -4,9 +4,10 @@ import ( "bytes" "context" "errors" - "github.com/filecoin-project/go-bitfield" "time" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" @@ -171,7 +172,7 @@ func (s *WindowPoStScheduler) checkRecoveries(ctx context.Context, deadline uint return xerrors.Errorf("declare faults recovered wait error: %w", err) } - if rec.Receipt.ExitCode == 0 { + if rec.Receipt.ExitCode != 0 { return xerrors.Errorf("declare faults recovered wait non-0 exit code: %d", rec.Receipt.ExitCode) } From 91da81c8bc8e9542f1ce5910847056a89ad9a0f5 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Thu, 28 May 2020 13:17:55 -0700 Subject: [PATCH 025/379] mod tidy --- go.sum | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go.sum b/go.sum index f25e4f97e..fb4286856 100644 --- a/go.sum +++ b/go.sum @@ -206,7 +206,6 @@ github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95 h1 github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go.mod h1:1UpuWCUC7XNfgyufyQQq+/40JSzhfGdgcwauK55C8gk= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= -github.com/filecoin-project/specs-actors v0.2.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.5.2/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461 h1:yyAoJ9dNboljDWj0uBdJEbdaTak/YhkjYUQt0GzlY0A= @@ -727,6 +726,7 @@ github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYc github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= +github.com/libp2p/go-libp2p-pubsub v0.3.0/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-pubsub v0.3.1 h1:7Hyv2d8BK/x1HGRJTZ8X++VQEP+WqDTSwpUSZGTVLYA= github.com/libp2p/go-libp2p-pubsub v0.3.1/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-quic-transport v0.1.1 h1:MFMJzvsxIEDEVKzO89BnB/FgvMj9WI4GDGUW2ArDPUA= @@ -1255,6 +1255,7 @@ golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1359,6 +1360,7 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200427175716-29b57079015a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From e2a554c2e68f4e17f09bab3c536961c37c958fe3 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 27 May 2020 17:06:29 -0700 Subject: [PATCH 026/379] update specs actors to version with batch porep verification --- api/api_full.go | 1 + api/apistruct/struct.go | 5 ++++ chain/stmgr/utils.go | 18 +++++++++++++ chain/vm/gas.go | 6 +++++ chain/vm/syscalls.go | 27 +++++++++++++++++++ cmd/lotus-chainwatch/sync.go | 13 ++++----- go.mod | 6 +++++ go.sum | 22 --------------- .../utils.go => lib/parmap/parmap.go | 10 +++---- node/impl/full/state.go | 8 ++++++ storage/adapter_storage_miner.go | 9 +++++++ storage/miner.go | 1 + 12 files changed, 93 insertions(+), 33 deletions(-) rename cmd/lotus-chainwatch/utils.go => lib/parmap/parmap.go (86%) diff --git a/api/api_full.go b/api/api_full.go index c6d442e2b..a1155c206 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -152,6 +152,7 @@ type FullNode interface { StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) + StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error) StateWaitMsg(context.Context, cid.Cid) (*MsgLookup, error) StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index f0be44070..c97c1285a 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -127,6 +127,7 @@ type FullNodeStruct struct { StateMinerInitialPledgeCollateral func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) `perm:"read"` StateMinerAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"` StateSectorPreCommitInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"` + StateSectorGetInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"` StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) `perm:"read"` StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"` StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"` @@ -556,6 +557,10 @@ func (c *FullNodeStruct) StateSectorPreCommitInfo(ctx context.Context, maddr add return c.Internal.StateSectorPreCommitInfo(ctx, maddr, n, tsk) } +func (c *FullNodeStruct) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return c.Internal.StateSectorGetInfo(ctx, maddr, n, tsk) +} + func (c *FullNodeStruct) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.InvocResult, error) { return c.Internal.StateCall(ctx, msg, tsk) } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 0ae7abb4e..001882ec6 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -138,6 +138,24 @@ func PreCommitInfo(ctx context.Context, sm *StateManager, maddr address.Address, return *i, nil } +func MinerSectorInfo(ctx context.Context, sm *StateManager, maddr address.Address, sid abi.SectorNumber, ts *types.TipSet) (*miner.SectorOnChainInfo, error) { + var mas miner.State + _, err := sm.LoadActorState(ctx, maddr, &mas, ts) + if err != nil { + return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) + } + + sectorInfo, ok, err := mas.GetSector(sm.cs.Store(ctx), sid) + if err != nil { + return nil, err + } + if !ok { + return nil, xerrors.New("sector not found") + } + + return sectorInfo, nil +} + func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) { var mas miner.State _, err := sm.LoadActorState(ctx, maddr, &mas, ts) diff --git a/chain/vm/gas.go b/chain/vm/gas.go index a24e54b78..f1cf89845 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -3,6 +3,7 @@ package vm import ( "fmt" + "github.com/filecoin-project/go-address" addr "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/crypto" @@ -143,3 +144,8 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte ps.chargeGas(ps.pl.OnVerifyConsensusFault()) return ps.under.VerifyConsensusFault(h1, h2, extra) } + +func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { + ps.chargeGas(0) // TODO: this is only called by the cron actor. Should we even charge gas? + return ps.under.BatchVerifySeals(inp) +} diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index c3fe4375f..9f9610f4b 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "sync" "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" @@ -252,3 +253,29 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres return sigs.Verify(&sig, kaddr, input) } + +func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { + out := make(map[address.Address][]bool) + + var wg sync.WaitGroup + for addr, seals := range inp { + results := make([]bool, len(seals)) + out[addr] = results + + for i, s := range seals { + wg.Add(1) + go func(ma address.Address, ix int, svi abi.SealVerifyInfo, res []bool) { + defer wg.Done() + if err := ss.VerifySeal(svi); err != nil { + log.Warnw("seal verify in batch failed", "miner", ma, "index", ix, "err", err) + res[ix] = false + } else { + res[ix] = true + } + }(addr, i, s, results) + } + } + wg.Wait() + + return out, nil +} diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 8fa903097..f009e47d9 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -20,6 +20,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" + parmap "github.com/filecoin-project/lotus/lib/parmap" ) func runSyncer(ctx context.Context, api api.FullNode, st *storage, maxBatch int) { @@ -138,7 +139,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS log.Infof("Syncing %d blocks", len(toSync)) paDone := 0 - par(50, maparr(toSync), func(bh *types.BlockHeader) { + parmap.Par(50, parmap.MapArr(toSync), func(bh *types.BlockHeader) { paDone++ if paDone%100 == 0 { log.Infof("pa: %d %d%%", paDone, (paDone*100)/len(toSync)) @@ -152,7 +153,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS return } - par(50, aadrs, func(addr address.Address) { + parmap.Par(50, aadrs, func(addr address.Address) { act, err := api.StateGetActor(ctx, addr, ts.Key()) if err != nil { log.Error(err) @@ -239,7 +240,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS addresses[message.From] = address.Undef } - par(50, kmaparr(addresses), func(addr address.Address) { + parmap.Par(50, parmap.KMapArr(addresses), func(addr address.Address) { raddr, err := api.StateLookupID(ctx, addr, types.EmptyTSK) if err != nil { log.Warn(err) @@ -268,7 +269,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS } } - par(50, kvmaparr(miners), func(it func() (minerKey, *minerInfo)) { + parmap.Par(50, parmap.KVMapArr(miners), func(it func() (minerKey, *minerInfo)) { k, info := it() pow, err := api.StateMinerPower(ctx, k.addr, types.EmptyTSK) @@ -386,7 +387,7 @@ func fetchMessages(ctx context.Context, api api.FullNode, toSync map[cid.Cid]*ty messages := map[cid.Cid]*types.Message{} inclusions := map[cid.Cid][]cid.Cid{} // block -> msgs - par(50, maparr(toSync), func(header *types.BlockHeader) { + parmap.Par(50, parmap.MapArr(toSync), func(header *types.BlockHeader) { msgs, err := api.ChainGetBlockMessages(ctx, header.Cid()) if err != nil { log.Error(err) @@ -423,7 +424,7 @@ func fetchParentReceipts(ctx context.Context, api api.FullNode, toSync map[cid.C var lk sync.Mutex out := map[mrec]*types.MessageReceipt{} - par(50, maparr(toSync), func(header *types.BlockHeader) { + parmap.Par(50, parmap.MapArr(toSync), func(header *types.BlockHeader) { recs, err := api.ChainGetParentReceipts(ctx, header.Cid()) if err != nil { log.Error(err) diff --git a/go.mod b/go.mod index 642b3576c..6d87e15f7 100644 --- a/go.mod +++ b/go.mod @@ -121,3 +121,9 @@ require ( replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi + +replace github.com/filecoin-project/specs-actors => ../specs-actors + +replace github.com/filecoin-project/chain-validation => ../chain-validation + +replace github.com/filecoin-project/storage-fsm => ../storage-fsm diff --git a/go.sum b/go.sum index fb4286856..8925a25f9 100644 --- a/go.sum +++ b/go.sum @@ -10,7 +10,6 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= @@ -30,7 +29,6 @@ github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -164,17 +162,11 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= -github.com/filecoin-project/chain-validation v0.0.6-0.20200526171800-c56c1882dc99 h1:jVuyHbsCX/w4vZ+3pO0cqzOyqvwfo8tB94wzmcwaD2k= -github.com/filecoin-project/chain-validation v0.0.6-0.20200526171800-c56c1882dc99/go.mod h1:hMqMCTt3z+wZ+GL74uy7X4NptnucZTTrb5SUTt1L/0g= -github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef/go.mod h1:SrA+pWVoUivqKOfC+ckVYbx41hWz++HxJcrlmHNnebU= -github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 h1:jamfsxfK0Q9yCMHt8MPWx7Aa/O9k2Lve8eSc6FILYGQ= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= -github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= -github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= github.com/filecoin-project/go-bitfield v0.0.1 h1:Xg/JnrqqE77aJVKdbEyR04n9FZQWhwrN+buDgQCVpZU= github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= @@ -204,16 +196,8 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95 h1:wNpbsUY11P7+3yBfHOXsH+tAyferf1BVSe5S+HRm+7s= github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go.mod h1:1UpuWCUC7XNfgyufyQQq+/40JSzhfGdgcwauK55C8gk= -github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= -github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= -github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= -github.com/filecoin-project/specs-actors v0.5.2/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= -github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461 h1:yyAoJ9dNboljDWj0uBdJEbdaTak/YhkjYUQt0GzlY0A= -github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= -github.com/filecoin-project/storage-fsm v0.0.0-20200522010518-83fd743db8bc h1:6du9HB53x8frk+Cky9ymGYsRbvXZDE91EsaOJoCb5Ok= -github.com/filecoin-project/storage-fsm v0.0.0-20200522010518-83fd743db8bc/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -478,7 +462,6 @@ github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= -github.com/ipfs/go-log/v2 v2.1.0 h1:7l5yjP7aLl5xr7RmqEvPZy9Skq7PP2fIP0Pa7lU/UII= github.com/ipfs/go-log/v2 v2.1.0/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.1 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= @@ -537,7 +520,6 @@ github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= @@ -970,7 +952,6 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= -github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -1132,9 +1113,7 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1151,7 +1130,6 @@ github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CH github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200501014322-5f9941ef88e0/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= diff --git a/cmd/lotus-chainwatch/utils.go b/lib/parmap/parmap.go similarity index 86% rename from cmd/lotus-chainwatch/utils.go rename to lib/parmap/parmap.go index a5c821683..50613509e 100644 --- a/cmd/lotus-chainwatch/utils.go +++ b/lib/parmap/parmap.go @@ -1,11 +1,11 @@ -package main +package parmap import ( "reflect" "sync" ) -func maparr(in interface{}) interface{} { +func MapArr(in interface{}) interface{} { rin := reflect.ValueOf(in) rout := reflect.MakeSlice(reflect.SliceOf(rin.Type().Elem()), rin.Len(), rin.Len()) var i int @@ -19,7 +19,7 @@ func maparr(in interface{}) interface{} { return rout.Interface() } -func kmaparr(in interface{}) interface{} { +func KMapArr(in interface{}) interface{} { rin := reflect.ValueOf(in) rout := reflect.MakeSlice(reflect.SliceOf(rin.Type().Key()), rin.Len(), rin.Len()) var i int @@ -34,7 +34,7 @@ func kmaparr(in interface{}) interface{} { } // map[k]v => []func() (k, v) -func kvmaparr(in interface{}) interface{} { +func KVMapArr(in interface{}) interface{} { rin := reflect.ValueOf(in) t := reflect.FuncOf([]reflect.Type{}, []reflect.Type{ @@ -59,7 +59,7 @@ func kvmaparr(in interface{}) interface{} { return rout.Interface() } -func par(concurrency int, arr interface{}, f interface{}) { +func Par(concurrency int, arr interface{}, f interface{}) { throttle := make(chan struct{}, concurrency) var wg sync.WaitGroup diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 58633b27a..f160efa49 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -539,6 +539,14 @@ func (a *StateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr address.A return stmgr.PreCommitInfo(ctx, a.StateManager, maddr, n, ts) } +func (a *StateAPI) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) { + ts, err := a.Chain.GetTipSetFromKey(tsk) + if err != nil { + return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) + } + return stmgr.MinerSectorInfo(ctx, a.StateManager, maddr, n, ts) +} + func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toheight abi.ChainEpoch) ([]cid.Cid, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 391a38b37..09197e71a 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -170,6 +170,15 @@ func (s SealingAPIAdapter) StateSectorPreCommitInfo(ctx context.Context, maddr a return &pci, nil } +func (s SealingAPIAdapter) StateSectorGetInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok sealing.TipSetToken) (*miner.SectorOnChainInfo, error) { + tsk, err := types.TipSetKeyFromBytes(tok) + if err != nil { + return nil, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err) + } + + return s.delegate.StateSectorGetInfo(ctx, maddr, sectorNumber, tsk) +} + func (s SealingAPIAdapter) StateMarketStorageDeal(ctx context.Context, dealID abi.DealID, tok sealing.TipSetToken) (market.DealProposal, error) { tsk, err := types.TipSetKeyFromBytes(tok) if err != nil { diff --git a/storage/miner.go b/storage/miner.go index 779f981e9..2512a7124 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -50,6 +50,7 @@ type storageMinerApi interface { StateMinerDeadlines(ctx context.Context, maddr address.Address, tok types.TipSetKey) (*miner.Deadlines, error) StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) + StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) From fa04da29953fae9f754030db87a058980ea9ea7f Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 28 May 2020 01:22:25 -0400 Subject: [PATCH 027/379] Update specs-actors and storage-fsm --- go.mod | 8 ++------ go.sum | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 6d87e15f7..84e1705b3 100644 --- a/go.mod +++ b/go.mod @@ -30,9 +30,9 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95 - github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461 + github.com/filecoin-project/specs-actors v0.5.4 github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 - github.com/filecoin-project/storage-fsm v0.0.0-20200522010518-83fd743db8bc + github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-ole/go-ole v1.2.4 // indirect github.com/google/uuid v1.1.1 @@ -122,8 +122,4 @@ replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi -replace github.com/filecoin-project/specs-actors => ../specs-actors - replace github.com/filecoin-project/chain-validation => ../chain-validation - -replace github.com/filecoin-project/storage-fsm => ../storage-fsm diff --git a/go.sum b/go.sum index 8925a25f9..0ed1bae2a 100644 --- a/go.sum +++ b/go.sum @@ -162,11 +162,15 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= +github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef/go.mod h1:SrA+pWVoUivqKOfC+ckVYbx41hWz++HxJcrlmHNnebU= +github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 h1:jamfsxfK0Q9yCMHt8MPWx7Aa/O9k2Lve8eSc6FILYGQ= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= +github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= +github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= github.com/filecoin-project/go-bitfield v0.0.1 h1:Xg/JnrqqE77aJVKdbEyR04n9FZQWhwrN+buDgQCVpZU= github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= @@ -196,8 +200,17 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95 h1:wNpbsUY11P7+3yBfHOXsH+tAyferf1BVSe5S+HRm+7s= github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go.mod h1:1UpuWCUC7XNfgyufyQQq+/40JSzhfGdgcwauK55C8gk= +github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= +github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= +github.com/filecoin-project/specs-actors v0.5.2/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= +github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= +github.com/filecoin-project/specs-actors v0.5.4 h1:Od00SYb/pTXC84oZGz9h2xGBm8GIHo8GXUaRKg1ClZo= +github.com/filecoin-project/specs-actors v0.5.4/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= +github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960 h1:KXkOn1r3lyxKn2rHUcVox6WYtfIEsgyZdBVoIVJARjY= +github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -1130,6 +1143,7 @@ github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CH github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200501014322-5f9941ef88e0/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= From fa69adf45ca80e6d043461846c9ef64c51ae145c Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 28 May 2020 15:58:31 -0400 Subject: [PATCH 028/379] update chain-validation --- go.mod | 4 +--- go.sum | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 84e1705b3..0a5d64d52 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 - github.com/filecoin-project/chain-validation v0.0.6-0.20200526171800-c56c1882dc99 + github.com/filecoin-project/chain-validation v0.0.6-0.20200528194021-3ce40d696ae1 github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 @@ -121,5 +121,3 @@ require ( replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi - -replace github.com/filecoin-project/chain-validation => ../chain-validation diff --git a/go.sum b/go.sum index 0ed1bae2a..7a29003fe 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= +github.com/filecoin-project/chain-validation v0.0.6-0.20200528194021-3ce40d696ae1 h1:cJPPzINJq4oUbdC4gQyMrEzuSiJ95RKxyXsLn6UgfcI= +github.com/filecoin-project/chain-validation v0.0.6-0.20200528194021-3ce40d696ae1/go.mod h1:aV5C4aX+kZwh5OlTHNCHxQ5vTnpTFKUuKiDTk9f/8Es= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= @@ -203,7 +205,6 @@ github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= -github.com/filecoin-project/specs-actors v0.5.2/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.4 h1:Od00SYb/pTXC84oZGz9h2xGBm8GIHo8GXUaRKg1ClZo= github.com/filecoin-project/specs-actors v0.5.4/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= From 21415a98472f3e7f1f5349b1ca3976096aaa2614 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 28 May 2020 16:48:06 -0400 Subject: [PATCH 029/379] add chainwatch systemd svc config; make install-chainwatch-service --- Makefile | 8 ++++++++ scripts/chainwatch.service | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 scripts/chainwatch.service diff --git a/Makefile b/Makefile index 92772ab19..fdf9e7e09 100644 --- a/Makefile +++ b/Makefile @@ -114,6 +114,7 @@ install-services: install clean-services: rm -f /usr/local/lib/systemd/system/lotus-daemon.service rm -f /usr/local/lib/systemd/system/lotus-miner.service + rm -f /usr/local/lib/systemd/system/chainwatch.service systemctl daemon-reload # TOOLS @@ -160,6 +161,13 @@ chainwatch: .PHONY: chainwatch BINS+=chainwatch +install-chainwatch-service: chainwatch + install -C ./chainwatch /usr/local/bin/chainwatch + install -C -m 0644 ./scripts/chainwatch.service /usr/local/lib/systemd/system/chainwatch.service + systemctl daemon-reload + @echo + @echo "chainwatch installed. Don't forget to 'systemctl enable chainwatch' for it to be enabled on startup." + bench: rm -f bench go build -o bench ./cmd/lotus-bench diff --git a/scripts/chainwatch.service b/scripts/chainwatch.service new file mode 100644 index 000000000..47af6b59e --- /dev/null +++ b/scripts/chainwatch.service @@ -0,0 +1,12 @@ +[Unit] +Description=Chainwatch +After=lotus-daemon.service +Requires=lotus-daemon.service + +[Service] +ExecStart=/usr/local/bin/chainwatch run +Environment=LOTUS_DB="postgres://postgres:password@localhost:5432/postgres?sslmode=disable" +Environment=LOTUS_PATH="/root/.lotus" + +[Install] +WantedBy=multiuser.target From 5129fed7c89d2f8017a0524d87086925f6c9a9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 29 May 2020 14:36:56 +0200 Subject: [PATCH 030/379] pond: rerun method-gen --- go.sum | 3 +++ lotuspond/front/src/chain/methods.json | 9 +++++---- lotuspond/spawn.go | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/go.sum b/go.sum index 7a29003fe..87f4f9148 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,8 @@ github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -966,6 +968,7 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= +github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= diff --git a/lotuspond/front/src/chain/methods.json b/lotuspond/front/src/chain/methods.json index 5a2de5d7f..0d0658716 100644 --- a/lotuspond/front/src/chain/methods.json +++ b/lotuspond/front/src/chain/methods.json @@ -44,12 +44,11 @@ "Constructor", "AddBalance", "WithdrawBalance", - "HandleExpiredDeals", "PublishStorageDeals", "VerifyDealsOnSectorProveCommit", "OnMinerSectorsTerminate", "ComputeDataCommitment", - "HandleInitTimeoutDeals" + "CronTick" ], "fil/1/storageminer": [ "Send", @@ -68,7 +67,8 @@ "CheckSectorProven", "AddLockedFund", "ReportConsensusFault", - "WithdrawBalance" + "WithdrawBalance", + "ConfirmSectorProofsValid" ], "fil/1/storagepower": [ "Send", @@ -83,7 +83,8 @@ "EnrollCronEvent", "OnEpochTickEnd", "UpdatePledgeTotal", - "OnConsensusFault" + "OnConsensusFault", + "SubmitPoRepForBulkVerify" ], "fil/1/verifiedregistry": [ "Send", diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index 5b0f7f704..76b3f3aa2 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "github.com/filecoin-project/lotus/chain/types" "io" "io/ioutil" "os" @@ -16,7 +17,6 @@ import ( "github.com/filecoin-project/go-address" genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/lotus/cmd/lotus-seed/seed" @@ -65,7 +65,7 @@ func (api *api) Spawn() (nodeInfo, error) { template.Miners = append(template.Miners, *genm) template.Accounts = append(template.Accounts, genesis.Actor{ Type: genesis.TAccount, - Balance: big.NewInt(100000000000000), + Balance: types.FromFil(5000000), Meta: (&genesis.AccountMeta{Owner: genm.Owner}).ActorMeta(), }) From 71eb41b9aa3deb42a0b6002e219b669b6ca34839 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 29 May 2020 15:46:05 +0200 Subject: [PATCH 031/379] Add pubsub support to drand beacon Signed-off-by: Jakub Sztandera --- chain/beacon/drand/drand.go | 34 ++++++++++++++++++++++++---------- go.mod | 3 ++- go.sum | 8 ++++++-- node/builder.go | 1 - node/modules/services.go | 13 ++++++++++--- node/modules/storageminer.go | 11 ----------- 6 files changed, 42 insertions(+), 28 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index d8df81f03..0de519f1e 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -6,17 +6,22 @@ import ( "sync" "time" + dchain "github.com/drand/drand/chain" + dclient "github.com/drand/drand/client" + gclient "github.com/drand/drand/cmd/relay-gossip/client" + dlog "github.com/drand/drand/log" "github.com/drand/kyber" + kzap "github.com/go-kit/kit/log/zap" + "go.uber.org/zap/zapcore" + "golang.org/x/xerrors" + + logging "github.com/ipfs/go-log" + pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/abi" - "golang.org/x/xerrors" - - logging "github.com/ipfs/go-log" - - dchain "github.com/drand/drand/chain" - dclient "github.com/drand/drand/client" ) var log = logging.Logger("drand") @@ -67,15 +72,24 @@ type DrandBeacon struct { localCache map[uint64]types.BeaconEntry } -func NewDrandBeacon(genesisTs, interval uint64) (*DrandBeacon, error) { +func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon, error) { if genesisTs == 0 { panic("what are you doing this cant be zero") } - client, err := dclient.New( - dclient.WithHTTPEndpoints(drandServers), + opts := []dclient.Option{ dclient.WithChainInfo(drandChain), + dclient.WithHTTPEndpoints(drandServers), dclient.WithCacheSize(1024), - ) + dclient.WithLogger(dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger( + log.SugaredLogger.Desugar(), zapcore.InfoLevel))), + } + if ps != nil { + opts = append(opts, gclient.WithPubsub(ps)) + } else { + log.Info("drand beacon without pubsub") + } + + client, err := dclient.New(opts...) if err != nil { return nil, xerrors.Errorf("creating drand client") } diff --git a/go.mod b/go.mod index 0a5d64d52..a1f550c27 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/coreos/go-systemd/v22 v22.0.0 github.com/docker/go-units v0.4.0 - github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e + github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 github.com/filecoin-project/chain-validation v0.0.6-0.20200528194021-3ce40d696ae1 @@ -34,6 +34,7 @@ require ( github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 + github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.4 diff --git a/go.sum b/go.sum index 7a29003fe..f249f4296 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,7 @@ contrib.go.opencensus.io/exporter/jaeger v0.1.0/go.mod h1:VYianECmuFPwU37O699Vc1 contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg= contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -134,8 +135,8 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE= github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= -github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e h1:e9JEgW+3GaPAqskYoEtL98HueHmUskO5tsRqmPs1ZxE= -github.com/drand/drand v0.9.2-0.20200526173017-9cffec0d074e/go.mod h1:xRGkp/+RCz/BWvF1KjaH2AGJ81hrGFqA6Uml1k1zNto= +github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 h1:IUxiqYU8BM8CyjHqxOTUbjrq7OvSDm8n1v9igaxtapM= +github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2/go.mod h1:UIhZq1vHM1BQbpLa9K2HkxpCtbdsGkCc9MnCdKJxYjk= github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= github.com/drand/kyber v1.0.2 h1:dHjtWJZJdn3zBBZ9pqLsLfcR9ScvDvSqzS1sWA8seao= github.com/drand/kyber v1.0.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= @@ -390,12 +391,14 @@ github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjv github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= +github.com/ipfs/go-ds-badger v0.2.3 h1:J27YvAcpuA5IvZUbeBxOcQgqnYHUPxoygc6QxxkodZ4= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= github.com/ipfs/go-ds-badger2 v0.1.0 h1:784py6lXkwlVF+K6XSuqmdMgy5l8GI6k60ngBokb9Fg= github.com/ipfs/go-ds-badger2 v0.1.0/go.mod h1:pbR1p817OZbdId9EvLOhKBgUVTM3BMCSTan78lDDVaw= github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8= github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ds-leveldb v0.4.2 h1:QmQoAJ9WkPMUfBLnu1sBVy0xWWlJPg0m4kRAiJL9iaw= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= github.com/ipfs/go-filestore v1.0.0 h1:QR7ekKH+q2AGiWDc7W2Q0qHuYSRZGUJqUn0GsegEPb0= github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPiFOdcuu9SM= @@ -1111,6 +1114,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= diff --git a/node/builder.go b/node/builder.go index d054be7a5..3b8e0d62f 100644 --- a/node/builder.go +++ b/node/builder.go @@ -292,7 +292,6 @@ func Online() Option { Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), Override(new(*storage.Miner), modules.StorageMiner), Override(new(dtypes.NetworkName), modules.StorageNetworkName), - Override(new(beacon.RandomBeacon), modules.MinerRandomBeacon), Override(new(dtypes.StagingBlockstore), modules.StagingBlockstore), Override(new(dtypes.StagingDAG), modules.StagingDAG), diff --git a/node/modules/services.go b/node/modules/services.go index 893ebbf73..f4a007c2b 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -123,12 +123,19 @@ func RetrievalResolver(l *discovery.Local) retrievalmarket.PeerResolver { return discovery.Multi(l) } -func RandomBeacon(cs *store.ChainStore, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) { - gen, err := cs.GetGenesis() +type RandomBeaconParams struct { + fx.In + + PubSub *pubsub.PubSub `optional:"true"` + Cs *store.ChainStore +} + +func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) { + gen, err := p.Cs.GetGenesis() if err != nil { return nil, err } //return beacon.NewMockBeacon(build.BlockDelay * time.Second) - return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay) + return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub) } diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index ee3fc9a1a..f50293870 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -43,8 +43,6 @@ import ( lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/beacon" - "github.com/filecoin-project/lotus/chain/beacon/drand" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/markets/retrievaladapter" @@ -364,12 +362,3 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA headers.Add("Authorization", "Bearer "+string(token)) return sectorstorage.StorageAuth(headers), nil } - -func MinerRandomBeacon(api lapi.FullNode) (beacon.RandomBeacon, error) { - gents, err := api.ChainGetGenesis(context.TODO()) - if err != nil { - return nil, err - } - - return drand.NewDrandBeacon(gents.Blocks()[0].Timestamp, build.BlockDelay) -} From 002d021eb741e49a9e1e4b6a131e007598db6360 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 29 May 2020 16:20:09 +0200 Subject: [PATCH 032/379] Enable HashMsgId Signed-off-by: Jakub Sztandera --- node/modules/lp2p/pubsub.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/modules/lp2p/pubsub.go b/node/modules/lp2p/pubsub.go index 9af2be346..35285f5c1 100644 --- a/node/modules/lp2p/pubsub.go +++ b/node/modules/lp2p/pubsub.go @@ -38,6 +38,7 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp options := []pubsub.Option{ // Gossipsubv1.1 configuration pubsub.WithFloodPublish(true), + pubsub.WithMessageIdFn(HashMsgId), pubsub.WithPeerScore( &pubsub.PeerScoreParams{ AppSpecificScore: func(p peer.ID) float64 { From 30d82ba9629bf262dee5d6947cfce09829edfc1d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 29 May 2020 17:21:10 +0200 Subject: [PATCH 033/379] Explicity Watch for randomness Signed-off-by: Jakub Sztandera --- chain/beacon/drand/drand.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 0de519f1e..8742350ba 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -76,13 +76,16 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon if genesisTs == 0 { panic("what are you doing this cant be zero") } + + dlogger := dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger( + log.SugaredLogger.Desugar(), zapcore.InfoLevel)) opts := []dclient.Option{ dclient.WithChainInfo(drandChain), dclient.WithHTTPEndpoints(drandServers), dclient.WithCacheSize(1024), - dclient.WithLogger(dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger( - log.SugaredLogger.Desugar(), zapcore.InfoLevel))), + dclient.WithLogger(dlogger), } + if ps != nil { opts = append(opts, gclient.WithPubsub(ps)) } else { @@ -94,6 +97,14 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon return nil, xerrors.Errorf("creating drand client") } + go func() { + // Explicitly Watch until that is fixed in drand + ch := client.Watch(context.Background()) + for range ch { + } + log.Error("dranch Watch bork") + }() + db := &DrandBeacon{ client: client, localCache: make(map[uint64]types.BeaconEntry), From 7dd25c3ac5e1c3e7fb6f20fe41bddd799661664c Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 28 May 2020 13:22:32 -0400 Subject: [PATCH 034/379] Correctly handle transfers with sender = receiver --- chain/vm/vm.go | 22 ++++++++++++++++++---- go.mod | 2 +- go.sum | 8 ++++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 49294e9cf..763708eca 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -607,16 +607,30 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor return nil } + fromId, err := vm.cstate.LookupID(from) + if err != nil { + return aerrors.Fatalf("transfer failed when resolving sender address: %s", err) + } + + toId, err := vm.cstate.LookupID(to) + if err != nil { + return aerrors.Fatalf("transfer failed when resolving receiver address: %s", err) + } + + if fromId == toId { + return nil + } + if amt.LessThan(types.NewInt(0)) { return aerrors.Newf(exitcode.SysErrForbidden, "attempted to transfer negative value: %s", amt) } - f, err := vm.cstate.GetActor(from) + f, err := vm.cstate.GetActor(fromId) if err != nil { return aerrors.Fatalf("transfer failed when retrieving sender actor: %s", err) } - t, err := vm.cstate.GetActor(to) + t, err := vm.cstate.GetActor(toId) if err != nil { return aerrors.Fatalf("transfer failed when retrieving receiver actor: %s", err) } @@ -626,11 +640,11 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor } depositFunds(t, amt) - if err := vm.cstate.SetActor(from, f); err != nil { + if err := vm.cstate.SetActor(fromId, f); err != nil { return aerrors.Fatalf("transfer failed when setting receiver actor: %s", err) } - if err := vm.cstate.SetActor(to, t); err != nil { + if err := vm.cstate.SetActor(toId, t); err != nil { return aerrors.Fatalf("transfer failed when setting sender actor: %s", err) } diff --git a/go.mod b/go.mod index 192e14563..cb793325f 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 - github.com/filecoin-project/chain-validation v0.0.6-0.20200528194021-3ce40d696ae1 + github.com/filecoin-project/chain-validation v0.0.6-0.20200528212128-d4578ae4f874 github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 diff --git a/go.sum b/go.sum index 86cce5aa9..d5e36ae38 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= @@ -165,8 +166,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= -github.com/filecoin-project/chain-validation v0.0.6-0.20200528194021-3ce40d696ae1 h1:cJPPzINJq4oUbdC4gQyMrEzuSiJ95RKxyXsLn6UgfcI= -github.com/filecoin-project/chain-validation v0.0.6-0.20200528194021-3ce40d696ae1/go.mod h1:aV5C4aX+kZwh5OlTHNCHxQ5vTnpTFKUuKiDTk9f/8Es= +github.com/filecoin-project/chain-validation v0.0.6-0.20200528212128-d4578ae4f874 h1:NNzyoQjidcvvoARgaM6zo2jYXC0KwNQkaYuDiBFcAD4= +github.com/filecoin-project/chain-validation v0.0.6-0.20200528212128-d4578ae4f874/go.mod h1:aV5C4aX+kZwh5OlTHNCHxQ5vTnpTFKUuKiDTk9f/8Es= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= @@ -539,6 +540,7 @@ github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= @@ -1134,7 +1136,9 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= From e5c24ff32b54aa0236f7ed53d5fe6f01265d5bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 26 May 2020 10:20:32 +0200 Subject: [PATCH 035/379] Update sector-storage with ReadPiece impl --- api/api_worker.go | 9 +++++- api/apistruct/struct.go | 48 +++++++++++++++++----------- cmd/lotus-bench/main.go | 7 +--- cmd/lotus-storage-miner/init.go | 2 +- cmd/lotus-storage-miner/storage.go | 2 +- go.mod | 6 ++-- go.sum | 16 +++++++--- markets/retrievaladapter/provider.go | 11 +++++-- node/config/def.go | 1 + node/repo/fsrepo.go | 4 +++ node/repo/interface.go | 1 + node/repo/memrepo.go | 4 +++ 12 files changed, 75 insertions(+), 36 deletions(-) diff --git a/api/api_worker.go b/api/api_worker.go index dbad20651..6270e65fb 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -2,6 +2,9 @@ package api import ( "context" + "io" + + "github.com/ipfs/go-cid" "github.com/filecoin-project/sector-storage/sealtasks" "github.com/filecoin-project/sector-storage/stores" @@ -21,7 +24,11 @@ type WorkerApi interface { Info(context.Context) (storiface.WorkerInfo, error) storage.Sealer - Fetch(context.Context, abi.SectorID, stores.SectorFileType, bool) error + + UnsealPiece(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error + ReadPiece(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error + + Fetch(context.Context, abi.SectorID, stores.SectorFileType, bool, stores.AcquireMode) error Closing(context.Context) (<-chan struct{}, error) } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index c97c1285a..8f35044f8 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -2,6 +2,7 @@ package apistruct import ( "context" + "io" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/network" @@ -201,16 +202,16 @@ type StorageMinerStruct struct { WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"` - StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` - StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"` - StorageStat func(context.Context, stores.ID) (stores.FsStat, error) `perm:"admin"` - StorageAttach func(context.Context, stores.StorageInfo, stores.FsStat) error `perm:"admin"` - StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"` - StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"` - StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, bool) ([]stores.StorageInfo, error) `perm:"admin"` - StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` - StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing bool) ([]stores.StorageInfo, error) `perm:"admin"` - StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` + StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` + StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"` + StorageStat func(context.Context, stores.ID) (stores.FsStat, error) `perm:"admin"` + StorageAttach func(context.Context, stores.StorageInfo, stores.FsStat) error `perm:"admin"` + StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"` + StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"` + StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"` + StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` + StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"` + StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` @@ -235,7 +236,10 @@ type WorkerStruct struct { SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"` FinalizeSector func(context.Context, abi.SectorID) error `perm:"admin"` - Fetch func(context.Context, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"` + UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"` + ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error `perm:"admin"` + + Fetch func(context.Context, abi.SectorID, stores.SectorFileType, bool, stores.AcquireMode) error `perm:"admin"` Closing func(context.Context) (<-chan struct{}, error) `perm:"admin"` } @@ -757,15 +761,15 @@ func (c *StorageMinerStruct) StorageAttach(ctx context.Context, si stores.Storag return c.Internal.StorageAttach(ctx, si, st) } -func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType) error { - return c.Internal.StorageDeclareSector(ctx, storageId, s, ft) +func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType, primary bool) error { + return c.Internal.StorageDeclareSector(ctx, storageId, s, ft, primary) } func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType) error { return c.Internal.StorageDropSector(ctx, storageId, s, ft) } -func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, allowFetch bool) ([]stores.StorageInfo, error) { +func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, allowFetch bool) ([]stores.SectorStorageInfo, error) { return c.Internal.StorageFindSector(ctx, si, types, allowFetch) } @@ -785,8 +789,8 @@ func (c *StorageMinerStruct) StorageInfo(ctx context.Context, id stores.ID) (sto return c.Internal.StorageInfo(ctx, id) } -func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing bool) ([]stores.StorageInfo, error) { - return c.Internal.StorageBestAlloc(ctx, allocate, spt, sealing) +func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, pt stores.PathType) ([]stores.StorageInfo, error) { + return c.Internal.StorageBestAlloc(ctx, allocate, spt, pt) } func (c *StorageMinerStruct) StorageReportHealth(ctx context.Context, id stores.ID, report stores.HealthReport) error { @@ -859,8 +863,16 @@ func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID) return w.Internal.FinalizeSector(ctx, sector) } -func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, b bool) error { - return w.Internal.Fetch(ctx, id, fileType, b) +func (w *WorkerStruct) UnsealPiece(ctx context.Context, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error { + return w.Internal.UnsealPiece(ctx, id, index, size, randomness, c) +} + +func (w *WorkerStruct) ReadPiece(ctx context.Context, writer io.Writer, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) error { + return w.Internal.ReadPiece(ctx, writer, id, index, size) +} + +func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, b bool, am stores.AcquireMode) error { + return w.Internal.Fetch(ctx, id, fileType, b, am) } func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) { diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 23471500d..3173b442d 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -562,15 +562,10 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid } } - // TODO: RM unsealed sector first - rc, err := sb.ReadPieceFromSealedSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.UnpaddedPieceSize(sectorSize), ticket, cids.Unsealed) + err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.UnpaddedPieceSize(sectorSize), ticket, cids.Unsealed) if err != nil { return nil, nil, err } - - if err := rc.Close(); err != nil { - return nil, nil, err - } } unseal := time.Now() diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index c28e9548c..b43af23c7 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -436,7 +436,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, smgr, err := sectorstorage.New(ctx, lr, stores.NewIndex(), &ffiwrapper.Config{ SealProofType: spt, - }, sectorstorage.SealerConfig{true, true, true}, nil, sa) + }, sectorstorage.SealerConfig{true, true, true, true}, nil, sa) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/storage.go b/cmd/lotus-storage-miner/storage.go index 18dd80dff..40205531a 100644 --- a/cmd/lotus-storage-miner/storage.go +++ b/cmd/lotus-storage-miner/storage.go @@ -249,7 +249,7 @@ var storageListCmd = &cli.Command{ type storedSector struct { id stores.ID - store stores.StorageInfo + store stores.SectorStorageInfo unsealed, sealed, cache bool } diff --git a/go.mod b/go.mod index 0a5d64d52..607525d8e 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 - github.com/filecoin-project/go-bitfield v0.0.1 + github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200505180321-973f8949ea8e github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95 + github.com/filecoin-project/sector-storage v0.0.0-20200529175241-9df0cdf19326 github.com/filecoin-project/specs-actors v0.5.4 github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960 @@ -67,7 +67,7 @@ require ( github.com/ipfs/go-path v0.0.7 github.com/ipfs/go-unixfs v0.2.4 github.com/ipfs/interface-go-ipfs-core v0.2.3 - github.com/ipld/go-car v0.1.1-0.20200430185908-8ff2e52a4c88 + github.com/ipld/go-car v0.1.1-0.20200526133713-1c7508d55aae github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.2.0 diff --git a/go.sum b/go.sum index 87f4f9148..63ab4a537 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= @@ -118,6 +119,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc= github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= +github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e h1:lj77EKYUpYXTd8CD/+QMIf8b6OIOTsfEBSXiAzuEHTU= +github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e/go.mod h1:3ZQK6DMPSz/QZ73jlWxBtUhNA8xZx7LzUFSq/OfP8vk= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -177,6 +180,8 @@ github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550/go.mo github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= github.com/filecoin-project/go-bitfield v0.0.1 h1:Xg/JnrqqE77aJVKdbEyR04n9FZQWhwrN+buDgQCVpZU= github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= +github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e h1:gkG/7G+iKy4He+IiQNeQn+nndFznb/vCoOR8iRQsm60= +github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= @@ -202,8 +207,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= -github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95 h1:wNpbsUY11P7+3yBfHOXsH+tAyferf1BVSe5S+HRm+7s= -github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95/go.mod h1:1UpuWCUC7XNfgyufyQQq+/40JSzhfGdgcwauK55C8gk= +github.com/filecoin-project/sector-storage v0.0.0-20200529175241-9df0cdf19326 h1:WIIvOzK9KaWMFXhvivUxeg4cdMzQ/5/MW+bNpYj43wU= +github.com/filecoin-project/sector-storage v0.0.0-20200529175241-9df0cdf19326/go.mod h1:hUQo3z/5B8t8Yl+XgIxBqgNfYtIcCYzKjWWY27dHBCk= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= @@ -510,8 +515,8 @@ github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdm github.com/ipfs/iptb-plugins v0.2.1 h1:au4HWn9/pRPbkxA08pDx2oRAs4cnbgQWgV0teYXuuGA= github.com/ipfs/iptb-plugins v0.2.1/go.mod h1:QXMbtIWZ+jRsW8a4h13qAKU7jcM7qaittO8wOsTP0Rs= github.com/ipld/go-car v0.1.1-0.20200429200904-c222d793c339/go.mod h1:eajxljm6I8o3LitnFeVEmucwZmz7+yLSiKce9yYMefg= -github.com/ipld/go-car v0.1.1-0.20200430185908-8ff2e52a4c88 h1:kjpIMwbJk/OEKM8hexj+HAVZsOgVr4byKML3s++s1b0= -github.com/ipld/go-car v0.1.1-0.20200430185908-8ff2e52a4c88/go.mod h1:2mvxpu4dKRnuH3mj5u6KW/tmRSCcXvy/KYiJ4nC6h4c= +github.com/ipld/go-car v0.1.1-0.20200526133713-1c7508d55aae h1:OV9dxl8iPMCOD8Vi/hvFwRh3JWPXqmkYSVxWr9JnEzM= +github.com/ipld/go-car v0.1.1-0.20200526133713-1c7508d55aae/go.mod h1:2mvxpu4dKRnuH3mj5u6KW/tmRSCcXvy/KYiJ4nC6h4c= github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e h1:ZISbJlM0urTANR9KRfRaqlBmyOj5uUtxs2r4Up9IXsA= github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8= github.com/ipld/go-ipld-prime-proto v0.0.0-20200428191222-c1ffdadc01e1 h1:K1Ysr7kgIlo7YQkPqdkA6H7BVdIugvuAz7OQUTJxLdE= @@ -536,6 +541,7 @@ github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= @@ -1130,7 +1136,9 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index 1917d8119..6c425ccd8 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -2,13 +2,13 @@ package retrievaladapter import ( "context" + "github.com/filecoin-project/sector-storage/storiface" "io" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/shared" sectorstorage "github.com/filecoin-project/sector-storage" - "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/paych" @@ -54,7 +54,14 @@ func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID uin Miner: abi.ActorID(mid), Number: abi.SectorNumber(sectorID), } - return rpn.sealer.ReadPieceFromSealedSector(ctx, sid, ffiwrapper.UnpaddedByteIndex(offset), abi.UnpaddedPieceSize(length), si.TicketValue, *si.CommD) + + r, w := io.Pipe() + go func() { + err := rpn.sealer.ReadPiece(ctx, w, sid, storiface.UnpaddedByteIndex(offset), abi.UnpaddedPieceSize(length), si.TicketValue, *si.CommD) + _ = w.CloseWithError(err) + }() + + return r, nil } func (rpn *retrievalProviderNode) SavePaymentVoucher(ctx context.Context, paymentChannel address.Address, voucher *paych.SignedVoucher, proof []byte, expectedAmount abi.TokenAmount, tok shared.TipSetToken) (abi.TokenAmount, error) { diff --git a/node/config/def.go b/node/config/def.go index d5c64d40d..9ca97bb47 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -107,6 +107,7 @@ func DefaultStorageMiner() *StorageMiner { AllowPreCommit1: true, AllowPreCommit2: true, AllowCommit: true, + AllowUnseal: true, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 396fbf67e..a1cc9a6ec 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -319,6 +319,10 @@ func (fsr *fsLockedRepo) SetStorage(c func(*stores.StorageConfig)) error { return config.WriteStorageFile(fsr.join(fsStorageConfig), sc) } +func (fsr *fsLockedRepo) Stat(path string) (stores.FsStat, error) { + return stores.Stat(path) +} + func (fsr *fsLockedRepo) SetAPIEndpoint(ma multiaddr.Multiaddr) error { if err := fsr.stillValid(); err != nil { return err diff --git a/node/repo/interface.go b/node/repo/interface.go index 5ce414479..c87274449 100644 --- a/node/repo/interface.go +++ b/node/repo/interface.go @@ -40,6 +40,7 @@ type LockedRepo interface { GetStorage() (stores.StorageConfig, error) SetStorage(func(*stores.StorageConfig)) error + Stat(path string) (stores.FsStat, error) // SetAPIEndpoint sets the endpoint of the current API // so it can be read by API clients diff --git a/node/repo/memrepo.go b/node/repo/memrepo.go index 59dbecda7..17eeb0253 100644 --- a/node/repo/memrepo.go +++ b/node/repo/memrepo.go @@ -61,6 +61,10 @@ func (lmem *lockedMemRepo) SetStorage(c func(*stores.StorageConfig)) error { return nil } +func (lmem *lockedMemRepo) Stat(path string) (stores.FsStat, error) { + return stores.Stat(path) +} + func (lmem *lockedMemRepo) Path() string { lmem.Lock() defer lmem.Unlock() From cd2bf04a6bec4e46cd781f4de12896c8698bfe8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 29 May 2020 21:36:04 +0200 Subject: [PATCH 036/379] wdpost: Better fault handling --- storage/wdpost_run.go | 264 ++++++++++++++++++++++++++++-------------- 1 file changed, 174 insertions(+), 90 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 63109e5f5..08f5def30 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -62,7 +62,56 @@ func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *miner.Deadli }() } -func (s *WindowPoStScheduler) checkRecoveries(ctx context.Context, deadline uint64, ts *types.TipSet) error { +func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check *abi.BitField) (*abi.BitField, error) { + spt, err := s.proofType.RegisteredSealProof() + if err != nil { + return nil, xerrors.Errorf("getting seal proof type: %w", err) + } + + mid, err := address.IDFromAddress(s.actor) + if err != nil { + return nil, err + } + + sectors := make(map[abi.SectorID]struct{}) + var tocheck []abi.SectorID + err = check.ForEach(func(snum uint64) error { + s := abi.SectorID{ + Miner: abi.ActorID(mid), + Number: abi.SectorNumber(snum), + } + + tocheck = append(tocheck, s) + sectors[s] = struct{}{} + return nil + }) + if err != nil { + return nil, xerrors.Errorf("iterating over bitfield: %w", err) + } + + bad, err := s.faultTracker.CheckProvable(ctx, spt, tocheck) + if err != nil { + return nil, xerrors.Errorf("checking provable sectors: %w", err) + } + for _, id := range bad { + delete(sectors, id) + } + + log.Warnw("Checked sectors", "checked", len(tocheck), "good", len(sectors)) + + if len(sectors) == 0 { // nothing to recover + return nil, nil + } + + sbf := bitfield.New() + for s := range sectors { + (&sbf).Set(uint64(s.Number)) + } + + return &sbf, nil +} + +func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, deadline uint64, ts *types.TipSet) error { faults, err := s.api.StateMinerFaults(ctx, s.actor, ts.Key()) if err != nil { return xerrors.Errorf("getting on-chain faults: %w", err) @@ -96,53 +145,13 @@ func (s *WindowPoStScheduler) checkRecoveries(ctx context.Context, deadline uint return nil } - spt, err := s.proofType.RegisteredSealProof() + sbf, err := s.checkSectors(ctx, unrecovered) if err != nil { - return xerrors.Errorf("getting seal proof type: %w", err) - } - - mid, err := address.IDFromAddress(s.actor) - if err != nil { - return err - } - - sectors := make(map[abi.SectorID]struct{}) - var tocheck []abi.SectorID - err = unrecovered.ForEach(func(snum uint64) error { - s := abi.SectorID{ - Miner: abi.ActorID(mid), - Number: abi.SectorNumber(snum), - } - - tocheck = append(tocheck, s) - sectors[s] = struct{}{} - return nil - }) - if err != nil { - return xerrors.Errorf("iterating over unrecovered bitfield: %w", err) - } - - bad, err := s.faultTracker.CheckProvable(ctx, spt, tocheck) - if err != nil { - return xerrors.Errorf("checking provable sectors: %w", err) - } - for _, id := range bad { - delete(sectors, id) - } - - log.Warnw("Recoverable sectors", "faulty", len(tocheck), "recoverable", len(sectors)) - - if len(sectors) == 0 { // nothing to recover - return nil - } - - sbf := bitfield.New() - for s := range sectors { - (&sbf).Set(uint64(s.Number)) + return xerrors.Errorf("checking unrecovered sectors: %w", err) } params := &miner.DeclareFaultsRecoveredParams{ - Recoveries: []miner.RecoveryDeclaration{{Deadline: deadline, Sectors: &sbf}}, + Recoveries: []miner.RecoveryDeclaration{{Deadline: deadline, Sectors: sbf}}, } enc, aerr := actors.SerializeParams(params) @@ -179,34 +188,84 @@ func (s *WindowPoStScheduler) checkRecoveries(ctx context.Context, deadline uint return nil } -func (s *WindowPoStScheduler) checkFaults(ctx context.Context, ssi []abi.SectorNumber) ([]abi.SectorNumber, error) { - //faults := s.prover.Scrub(ssi) - log.Warnf("Stub checkFaults") +func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, deadline uint64, deadlineSectors *abi.BitField, ts *types.TipSet) error { + toCheck, err := s.getSectorsToProve(ctx, deadlineSectors, true, ts) + if err != nil { + return xerrors.Errorf("getting next sectors to prove: %w", err) + } - /*declaredFaults := map[abi.SectorNumber]struct{}{} + good, err := s.checkSectors(ctx, deadlineSectors) + if err != nil { + return xerrors.Errorf("checking sectors: %w", err) + } - { - chainFaults, err := s.api.StateMinerFaults(ctx, s.actor, types.EmptyTSK) - if err != nil { - return nil, xerrors.Errorf("checking on-chain faults: %w", err) - } + faulty, err := bitfield.SubtractBitField(toCheck, good) + if err != nil { + return xerrors.Errorf("calculating faulty sector set: %w", err) + } - for _, fault := range chainFaults { - declaredFaults[fault] = struct{}{} - } - }*/ + c, err := faulty.Count() + if err != nil { + return xerrors.Errorf("counting faulty sectors: %w", err) + } - return nil, nil + if c == 0 { + return nil + } + + log.Errorw("DETECTED FAULTY SECTORS, declaring faults", "count", c) + + params := &miner.DeclareFaultsParams{ + Faults: []miner.FaultDeclaration{ + { + Deadline: deadline, + Sectors: faulty, + }, + }, + } + + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return xerrors.Errorf("could not serialize declare faults parameters: %w", aerr) + } + + msg := &types.Message{ + To: s.actor, + From: s.worker, + Method: builtin.MethodsMiner.DeclareFaults, + Params: enc, + Value: types.NewInt(0), // TODO: Is there a fee? + GasLimit: 10000000, // i dont know help + GasPrice: types.NewInt(2), + } + + sm, err := s.api.MpoolPushMessage(ctx, msg) + if err != nil { + return xerrors.Errorf("pushing message to mpool: %w", err) + } + + log.Warnw("declare faults Message CID", "cid", sm.Cid()) + + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid()) + if err != nil { + return xerrors.Errorf("declare faults wait error: %w", err) + } + + if rec.Receipt.ExitCode != 0 { + return xerrors.Errorf("declare faults wait non-0 exit code: %d", rec.Receipt.ExitCode) + } + + return nil } // the input sectors must match with the miner actor -func (s *WindowPoStScheduler) getNeedProveSectors(ctx context.Context, deadlineSectors *abi.BitField, ts *types.TipSet) (*abi.BitField, error) { - faults, err := s.api.StateMinerFaults(ctx, s.actor, ts.Key()) +func (s *WindowPoStScheduler) getSectorsToProve(ctx context.Context, deadlineSectors *abi.BitField, ignoreRecoveries bool, ts *types.TipSet) (*abi.BitField, error) { + stateFaults, err := s.api.StateMinerFaults(ctx, s.actor, ts.Key()) if err != nil { return nil, xerrors.Errorf("getting on-chain faults: %w", err) } - declaredFaults, err := bitfield.IntersectBitField(deadlineSectors, faults) + faults, err := bitfield.IntersectBitField(deadlineSectors, stateFaults) if err != nil { return nil, xerrors.Errorf("failed to intersect proof sectors with faults: %w", err) } @@ -216,17 +275,19 @@ func (s *WindowPoStScheduler) getNeedProveSectors(ctx context.Context, deadlineS return nil, xerrors.Errorf("getting on-chain recoveries: %w", err) } - expectedRecoveries, err := bitfield.IntersectBitField(declaredFaults, recoveries) - if err != nil { - return nil, xerrors.Errorf("failed to intersect recoveries with faults: %w", err) + if !ignoreRecoveries { + expectedRecoveries, err := bitfield.IntersectBitField(faults, recoveries) + if err != nil { + return nil, xerrors.Errorf("failed to intersect recoveries with faults: %w", err) + } + + faults, err = bitfield.SubtractBitField(faults, expectedRecoveries) + if err != nil { + return nil, xerrors.Errorf("failed to subtract recoveries from faults: %w", err) + } } - expectedFaults, err := bitfield.SubtractBitField(declaredFaults, expectedRecoveries) - if err != nil { - return nil, xerrors.Errorf("failed to subtract recoveries from faults: %w", err) - } - - nonFaults, err := bitfield.SubtractBitField(deadlineSectors, expectedFaults) + nonFaults, err := bitfield.SubtractBitField(deadlineSectors, faults) if err != nil { return nil, xerrors.Errorf("failed to diff bitfields: %w", err) } @@ -246,11 +307,26 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo ctx, span := trace.StartSpan(ctx, "storage.runPost") defer span.End() - // check recoveries for the *next* deadline. It's already too late to - // declare them for this deadline - if err := s.checkRecoveries(ctx, (di.Index+1)%miner.WPoStPeriodDeadlines, ts); err != nil { - // TODO: This is potentially quite bad, but not even trying to post when this fails is objectively worse - log.Errorf("checking sector recoveries: %v", err) + deadlines, err := s.api.StateMinerDeadlines(ctx, s.actor, ts.Key()) + if err != nil { + return nil, xerrors.Errorf("getting miner deadlines: %w", err) + } + + { + // check faults / recoveries for the *next* deadline. It's already too + // late to declare them for this deadline + declDeadline := (di.Index + 1) % miner.WPoStPeriodDeadlines + + if err := s.checkNextRecoveries(ctx, declDeadline, ts); err != nil { + // TODO: This is potentially quite bad, but not even trying to post when this fails is objectively worse + log.Errorf("checking sector recoveries: %v", err) + } + + if err := s.checkNextFaults(ctx, declDeadline, deadlines.Due[declDeadline], ts); err != nil { + // TODO: This is also potentially really bad, but we try to post anyways + log.Errorf("checking sector faults: %v", err) + } + } buf := new(bytes.Buffer) @@ -262,11 +338,6 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), di, err) } - deadlines, err := s.api.StateMinerDeadlines(ctx, s.actor, ts.Key()) - if err != nil { - return nil, err - } - firstPartition, _, err := miner.PartitionsForDeadline(deadlines, s.partitionSectors, di.Index) if err != nil { return nil, xerrors.Errorf("getting partitions for deadline: %w", err) @@ -297,11 +368,29 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo partitions[i] = firstPartition + uint64(i) } - nps, err := s.getNeedProveSectors(ctx, deadlines.Due[di.Index], ts) + nps, err := s.getSectorsToProve(ctx, deadlines.Due[di.Index], false, ts) if err != nil { return nil, xerrors.Errorf("get need prove sectors: %w", err) } + var skipped *abi.BitField + { + good, err := s.checkSectors(ctx, nps) + if err != nil { + return nil, xerrors.Errorf("checking sectors to skip: %w", err) + } + + skipped, err = bitfield.SubtractBitField(nps, good) + if err != nil { + return nil, xerrors.Errorf("nps - good: %w", err) + } + } + + skipCount, err := skipped.Count() + if err != nil { + return nil, xerrors.Errorf("getting skipped sector count: %w", err) + } + ssi, err := s.sortedSectorInfo(ctx, nps, ts) if err != nil { return nil, xerrors.Errorf("getting sorted sector info: %w", err) @@ -315,23 +404,18 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo log.Infow("running windowPost", "chain-random", rand, "deadline", di, - "height", ts.Height()) + "height", ts.Height(), + "skipped", skipCount) var snums []abi.SectorNumber for _, si := range ssi { snums = append(snums, si.SectorNumber) } - faults, err := s.checkFaults(ctx, snums) - if err != nil { - log.Errorf("Failed to declare faults: %+v", err) - } - tsStart := time.Now() log.Infow("generating windowPost", - "sectors", len(ssi), - "faults", len(faults)) + "sectors", len(ssi)) mid, err := address.IDFromAddress(s.actor) if err != nil { @@ -355,7 +439,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo Deadline: di.Index, Partitions: partitions, Proofs: postOut, - Skipped: *abi.NewBitField(), // TODO: Faults here? + Skipped: *skipped, }, nil } From ee29a92021dba9ce38b0be4d225c94205fa6cd15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 1 Jun 2020 14:49:48 +0200 Subject: [PATCH 037/379] Add a test for Window Post --- api/api_storage.go | 3 +- api/test/test.go | 1 + api/test/window_post.go | 168 ++++++++++++++++++++++++++++++++++++++++ node/node_test.go | 48 ++++++++++-- storage/wdpost_run.go | 9 +++ 5 files changed, 222 insertions(+), 7 deletions(-) create mode 100644 api/test/window_post.go diff --git a/api/api_storage.go b/api/api_storage.go index ab75e8058..d6004dcf3 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -11,6 +11,7 @@ import ( "github.com/filecoin-project/sector-storage/stores" "github.com/filecoin-project/sector-storage/storiface" "github.com/filecoin-project/specs-actors/actors/abi" + sealing "github.com/filecoin-project/storage-fsm" "github.com/filecoin-project/lotus/chain/types" ) @@ -119,4 +120,4 @@ func (st *SealSeed) Equals(ost *SealSeed) bool { return bytes.Equal(st.Value, ost.Value) && st.Epoch == ost.Epoch } -type SectorState string +type SectorState = sealing.SectorState diff --git a/api/test/test.go b/api/test/test.go index 43dc7a25e..06f0584fd 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -20,6 +20,7 @@ type TestStorageNode struct { } var PresealGenesis = -1 +const GenesisPreseals = 2 type StorageMiner struct { Full int diff --git a/api/test/window_post.go b/api/test/window_post.go new file mode 100644 index 000000000..b67b3e498 --- /dev/null +++ b/api/test/window_post.go @@ -0,0 +1,168 @@ +package test + +import ( + "context" + "fmt" + "os" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/specs-actors/actors/abi" + miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + sealing "github.com/filecoin-project/storage-fsm" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/impl" +) + +func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { + os.Setenv("BELLMAN_NO_GPU", "1") + + ctx := context.Background() + n, sn := b(t, 1, oneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + time.Sleep(time.Second) + + mine := true + done := make(chan struct{}) + go func() { + defer close(done) + for mine { + time.Sleep(blocktime) + if err := sn[0].MineOne(ctx, func(bool) {}); err != nil { + t.Error(err) + } + } + }() + + pledgeSectors(t, ctx, miner, nSectors) + + mine = false + <-done +} + +func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n int) { + for i := 0; i < n; i++ { + err := miner.PledgeSector(ctx) + require.NoError(t, err) + } + + for { + s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM + require.NoError(t, err) + fmt.Printf("Sectors: %d\n", len(s)) + if len(s) >= n { + break + } + + time.Sleep(100 * time.Millisecond) + } + + fmt.Printf("All sectors is fsm\n") + + s, err := miner.SectorsList(ctx) + require.NoError(t, err) + + toCheck := map[abi.SectorNumber]struct{}{} + for _, number := range s { + toCheck[number] = struct{}{} + } + + for len(toCheck) > 0 { + for n := range toCheck { + st, err := miner.SectorsStatus(ctx, n) + require.NoError(t, err) + if st.State == sealing.Proving { + delete(toCheck, n) + } + if strings.Contains(string(st.State), "Fail") { + t.Fatal("sector in a failed state", st.State) + } + } + + time.Sleep(100 * time.Millisecond) + fmt.Printf("WaitSeal: %d\n", len(s)) + } +} + +func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { + os.Setenv("BELLMAN_NO_GPU", "1") + + ctx := context.Background() + n, sn := b(t, 1, oneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + time.Sleep(time.Second) + + mine := true + done := make(chan struct{}) + go func() { + defer close(done) + for mine { + time.Sleep(blocktime) + if err := sn[0].MineOne(ctx, func(bool) {}); err != nil { + t.Error(err) + } + } + }() + + pledgeSectors(t, ctx, miner, nSectors) + + maddr, err := miner.ActorAddress(ctx) + require.NoError(t, err) + + di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + fmt.Printf("Running one proving periods\n") + + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > di.PeriodStart + (miner2.WPoStProvingPeriod) + 2 { + break + } + + if head.Height() % 100 == 0 { + fmt.Printf("@%d\n", head.Height()) + } + time.Sleep(blocktime) + } + + p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + ssz, err := miner.ActorSectorSize(ctx, maddr) + require.NoError(t, err) + + require.Equal(t, p.MinerPower, p.TotalPower) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz) * uint64(nSectors + GenesisPreseals))) + + // TODO: Inject faults here + + mine = false + <-done +} diff --git a/node/node_test.go b/node/node_test.go index a31b4162b..9b543ee7a 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -83,7 +83,7 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a require.NoError(t, err) nic := storedcounter.New(ds, datastore.NewKey(modules.StorageCounterDSPrefix)) - for i := 0; i < nGenesisPreseals; i++ { + for i := 0; i < test.GenesisPreseals; i++ { _, err := nic.Next() require.NoError(t, err) } @@ -188,7 +188,7 @@ func builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestN if err != nil { t.Fatal(err) } - genm, k, err := seed.PreSeal(maddr, abi.RegisteredProof_StackedDRG2KiBPoSt, 0, nGenesisPreseals, tdir, []byte("make genesis mem random"), nil) + genm, k, err := seed.PreSeal(maddr, abi.RegisteredProof_StackedDRG2KiBPoSt, 0, test.GenesisPreseals, tdir, []byte("make genesis mem random"), nil) if err != nil { t.Fatal(err) } @@ -282,8 +282,6 @@ func builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestN return fulls, storers } -const nGenesisPreseals = 2 - func mockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { ctx := context.Background() mn := mocknet.New(ctx) @@ -314,7 +312,7 @@ func mockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test preseals := storage[i].Preseal if preseals == test.PresealGenesis { - preseals = nGenesisPreseals + preseals = test.GenesisPreseals } genm, k, err := mockstorage.PreSeal(2048, maddr, preseals) @@ -350,7 +348,7 @@ func mockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test templ := &genesis.Template{ Accounts: genaccs, Miners: genms, - Timestamp: uint64(time.Now().Unix() - 10000), + Timestamp: uint64(time.Now().Unix() - (build.BlockDelay * 20000)), } // END PRESEAL SECTION @@ -493,3 +491,41 @@ func TestDealMining(t *testing.T) { test.TestDealMining(t, mockSbBuilder, 50*time.Millisecond, false) } + +func TestPledgeSectors(t *testing.T) { + logging.SetLogLevel("miner", "ERROR") + logging.SetLogLevel("chainstore", "ERROR") + logging.SetLogLevel("chain", "ERROR") + logging.SetLogLevel("sub", "ERROR") + logging.SetLogLevel("storageminer", "ERROR") + + t.Run("1", func(t *testing.T) { + test.TestPledgeSector(t, mockSbBuilder, 50*time.Millisecond, 1) + }) + + t.Run("100", func(t *testing.T) { + test.TestPledgeSector(t, mockSbBuilder, 50*time.Millisecond, 100) + }) + + t.Run("1000", func(t *testing.T) { + if testing.Short() { // takes ~16s + t.Skip("skipping test in short mode") + } + + test.TestPledgeSector(t, mockSbBuilder, 50*time.Millisecond, 1000) + }) +} + +func TestWindowedPost(t *testing.T) { + if testing.Short() { + t.Skip("this takes a while") + } + + logging.SetLogLevel("miner", "ERROR") + logging.SetLogLevel("chainstore", "ERROR") + logging.SetLogLevel("chain", "ERROR") + logging.SetLogLevel("sub", "ERROR") + logging.SetLogLevel("storageminer", "ERROR") + + test.TestWindowPost(t, mockSbBuilder, 3*time.Millisecond, 10) +} diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 08f5def30..fbdae5199 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -189,6 +189,15 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, deadline } func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, deadline uint64, deadlineSectors *abi.BitField, ts *types.TipSet) error { + dc, err := deadlineSectors.Count() + if err != nil { + return xerrors.Errorf("counting deadline sectors: %w", err) + } + if dc == 0 { + // nothing can become faulty + return nil + } + toCheck, err := s.getSectorsToProve(ctx, deadlineSectors, true, ts) if err != nil { return xerrors.Errorf("getting next sectors to prove: %w", err) From b753cd450330c3a601107eb9c65b65bf579c887e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 1 Jun 2020 14:59:51 +0200 Subject: [PATCH 038/379] Run window post test on circle --- .circleci/config.yml | 13 +++++++++++-- api/api_storage.go | 6 ++---- api/test/window_post.go | 3 ++- node/node_test.go | 7 ++++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 312aa42ca..700f1fbc9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -134,6 +134,9 @@ jobs: type: string default: "./..." description: Import paths of packages to be tested. + winpost-test: + type: string + default: "0" test-suite-name: type: string default: unit @@ -171,6 +174,7 @@ jobs: environment: GOTESTSUM_JUNITFILE: /tmp/test-reports/<< parameters.test-suite-name >>/junit.xml GOTESTSUM_FORMAT: << parameters.gotestsum-format >> + LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >> command: | mkdir -p /tmp/test-reports/<< parameters.test-suite-name >> gotestsum -- \ @@ -199,6 +203,8 @@ jobs: test-short: <<: *test + test-window-post: + <<: *test build-macos: description: build darwin lotus binary @@ -332,10 +338,13 @@ workflows: jobs: - lint-changes: args: "--new-from-rev origin/next" - - test: - codecov-upload: true - mod-tidy-check - gofmt + - test: + codecov-upload: true + - test-window-post: + go-test-flags: "-run=TestWindowedPost" + winpost-test: "1" - test-short: go-test-flags: "--timeout 10m --short" filters: diff --git a/api/api_storage.go b/api/api_storage.go index d6004dcf3..7d3c78b48 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -8,12 +8,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/sector-storage/stores" "github.com/filecoin-project/sector-storage/storiface" "github.com/filecoin-project/specs-actors/actors/abi" - sealing "github.com/filecoin-project/storage-fsm" - - "github.com/filecoin-project/lotus/chain/types" ) // StorageMiner is a low-level interface to the Filecoin network storage miner node @@ -120,4 +118,4 @@ func (st *SealSeed) Equals(ost *SealSeed) bool { return bytes.Equal(st.Value, ost.Value) && st.Epoch == ost.Epoch } -type SectorState = sealing.SectorState +type SectorState string diff --git a/api/test/window_post.go b/api/test/window_post.go index b67b3e498..b821df2a7 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -3,6 +3,7 @@ package test import ( "context" "fmt" + "github.com/filecoin-project/lotus/api" "os" "strings" "testing" @@ -85,7 +86,7 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n i for n := range toCheck { st, err := miner.SectorsStatus(ctx, n) require.NoError(t, err) - if st.State == sealing.Proving { + if st.State == api.SectorState(sealing.Proving) { delete(toCheck, n) } if strings.Contains(string(st.State), "Fail") { diff --git a/node/node_test.go b/node/node_test.go index 9b543ee7a..6258fa943 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -6,6 +6,7 @@ import ( "crypto/rand" "io/ioutil" "net/http/httptest" + "os" "testing" "time" @@ -517,8 +518,8 @@ func TestPledgeSectors(t *testing.T) { } func TestWindowedPost(t *testing.T) { - if testing.Short() { - t.Skip("this takes a while") + if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" { + t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") } logging.SetLogLevel("miner", "ERROR") @@ -527,5 +528,5 @@ func TestWindowedPost(t *testing.T) { logging.SetLogLevel("sub", "ERROR") logging.SetLogLevel("storageminer", "ERROR") - test.TestWindowPost(t, mockSbBuilder, 3*time.Millisecond, 10) + test.TestWindowPost(t, mockSbBuilder, 5*time.Millisecond, 10) } From c73326e96dc8a032e8b8b76533ab14789846874f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 1 Jun 2020 20:11:55 +0200 Subject: [PATCH 039/379] fsrepo: Use LevelDB for metadata datastore --- api/test/test.go | 1 + api/test/window_post.go | 6 +-- chain/gen/gen.go | 2 +- chain/store/store_test.go | 2 +- cmd/lotus-shed/import-car.go | 2 +- cmd/lotus/daemon.go | 2 +- go.mod | 3 ++ go.sum | 3 ++ node/modules/chain.go | 2 +- node/repo/fsrepo.go | 18 --------- node/repo/fsrepo_ds.go | 74 ++++++++++++++++++++++++++++++++++++ 11 files changed, 89 insertions(+), 26 deletions(-) create mode 100644 node/repo/fsrepo_ds.go diff --git a/api/test/test.go b/api/test/test.go index 06f0584fd..5972ca757 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -20,6 +20,7 @@ type TestStorageNode struct { } var PresealGenesis = -1 + const GenesisPreseals = 2 type StorageMiner struct { diff --git a/api/test/window_post.go b/api/test/window_post.go index b821df2a7..1239d5424 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -143,11 +143,11 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector head, err := client.ChainHead(ctx) require.NoError(t, err) - if head.Height() > di.PeriodStart + (miner2.WPoStProvingPeriod) + 2 { + if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 { break } - if head.Height() % 100 == 0 { + if head.Height()%100 == 0 { fmt.Printf("@%d\n", head.Height()) } time.Sleep(blocktime) @@ -160,7 +160,7 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector require.NoError(t, err) require.Equal(t, p.MinerPower, p.TotalPower) - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz) * uint64(nSectors + GenesisPreseals))) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+GenesisPreseals))) // TODO: Inject faults here diff --git a/chain/gen/gen.go b/chain/gen/gen.go index b0c4cc044..de2ad9226 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -104,7 +104,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { return nil, xerrors.Errorf("failed to get metadata datastore: %w", err) } - bds, err := lr.Datastore("/blocks") + bds, err := lr.Datastore("/chain") if err != nil { return nil, xerrors.Errorf("failed to get blocks datastore: %w", err) } diff --git a/chain/store/store_test.go b/chain/store/store_test.go index 495b91b61..41b875916 100644 --- a/chain/store/store_test.go +++ b/chain/store/store_test.go @@ -55,7 +55,7 @@ func BenchmarkGetRandomness(b *testing.B) { b.Fatal(err) } - bds, err := lr.Datastore("/blocks") + bds, err := lr.Datastore("/chain") if err != nil { b.Fatal(err) } diff --git a/cmd/lotus-shed/import-car.go b/cmd/lotus-shed/import-car.go index f2f517a7f..970341a3a 100644 --- a/cmd/lotus-shed/import-car.go +++ b/cmd/lotus-shed/import-car.go @@ -42,7 +42,7 @@ var importCarCmd = &cli.Command{ return xerrors.Errorf("opening the car file: %w", err) } - ds, err := lr.Datastore("/blocks") + ds, err := lr.Datastore("/chain") if err != nil { return err } diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 9e4e7d1a3..2894e0eea 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -271,7 +271,7 @@ func ImportChain(r repo.Repo, fname string) error { } defer lr.Close() //nolint:errcheck - ds, err := lr.Datastore("/blocks") + ds, err := lr.Datastore("/chain") if err != nil { return err } diff --git a/go.mod b/go.mod index d8659f350..e4a4a9993 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,8 @@ require ( github.com/ipfs/go-cid v0.0.6-0.20200501230655-7c82f3b81c00 github.com/ipfs/go-datastore v0.4.4 github.com/ipfs/go-ds-badger2 v0.1.0 + github.com/ipfs/go-ds-leveldb v0.4.2 + github.com/ipfs/go-ds-measure v0.1.0 github.com/ipfs/go-filestore v1.0.0 github.com/ipfs/go-fs-lock v0.0.1 github.com/ipfs/go-graphsync v0.0.6-0.20200504202014-9d5f2c26a103 @@ -101,6 +103,7 @@ require ( github.com/opentracing/opentracing-go v1.1.0 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 + github.com/syndtr/goleveldb v1.0.0 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 diff --git a/go.sum b/go.sum index c68604e6d..57da8c1ce 100644 --- a/go.sum +++ b/go.sum @@ -387,6 +387,7 @@ github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAK github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= +github.com/ipfs/go-datastore v0.3.0/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= @@ -407,6 +408,8 @@ github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZ github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= github.com/ipfs/go-ds-leveldb v0.4.2 h1:QmQoAJ9WkPMUfBLnu1sBVy0xWWlJPg0m4kRAiJL9iaw= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ds-measure v0.1.0 h1:vE4TyY4aeLeVgnnPBC5QzKIjKrqzha0NCujTfgvVbVQ= +github.com/ipfs/go-ds-measure v0.1.0/go.mod h1:1nDiFrhLlwArTME1Ees2XaBOl49OoCgd2A3f8EchMSY= github.com/ipfs/go-filestore v1.0.0 h1:QR7ekKH+q2AGiWDc7W2Q0qHuYSRZGUJqUn0GsegEPb0= github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPiFOdcuu9SM= github.com/ipfs/go-fs-lock v0.0.1 h1:XHX8uW4jQBYWHj59XXcjg7BHlHxV9ZOYs6Y43yb7/l0= diff --git a/node/modules/chain.go b/node/modules/chain.go index ca0281acf..229a97cc4 100644 --- a/node/modules/chain.go +++ b/node/modules/chain.go @@ -61,7 +61,7 @@ func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub, ds } func ChainBlockstore(lc fx.Lifecycle, mctx helpers.MetricsCtx, r repo.LockedRepo) (dtypes.ChainBlockstore, error) { - blocks, err := r.Datastore("/blocks") + blocks, err := r.Datastore("/chain") if err != nil { return nil, err } diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index a1cc9a6ec..75b560d65 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -12,8 +12,6 @@ import ( "sync" "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/namespace" - badger "github.com/ipfs/go-ds-badger2" fslock "github.com/ipfs/go-fs-lock" logging "github.com/ipfs/go-log/v2" "github.com/mitchellh/go-homedir" @@ -267,22 +265,6 @@ func (fsr *fsLockedRepo) stillValid() error { return nil } -func (fsr *fsLockedRepo) Datastore(ns string) (datastore.Batching, error) { - fsr.dsOnce.Do(func() { - opts := badger.DefaultOptions - opts.Truncate = true - - fsr.ds, fsr.dsErr = badger.NewDatastore(fsr.join(fsDatastore), &opts) - /*if fsr.dsErr == nil { - fsr.ds = datastore.NewLogDatastore(fsr.ds, "fsrepo") - }*/ - }) - if fsr.dsErr != nil { - return nil, fsr.dsErr - } - return namespace.Wrap(fsr.ds, datastore.NewKey(ns)), nil -} - func (fsr *fsLockedRepo) Config() (interface{}, error) { if err := fsr.stillValid(); err != nil { return nil, err diff --git a/node/repo/fsrepo_ds.go b/node/repo/fsrepo_ds.go new file mode 100644 index 000000000..034635c4f --- /dev/null +++ b/node/repo/fsrepo_ds.go @@ -0,0 +1,74 @@ +package repo + +import ( + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/mount" + "github.com/ipfs/go-datastore/namespace" + "golang.org/x/xerrors" + "os" + "path/filepath" + + badger "github.com/ipfs/go-ds-badger2" + levelds "github.com/ipfs/go-ds-leveldb" + "github.com/ipfs/go-ds-measure" + ldbopts "github.com/syndtr/goleveldb/leveldb/opt" +) + +var fsDatastores = map[string]func(path string) (datastore.Batching, error){ + "chain": badgerDs, + "metadata": levelDs, + + // Those need to be fast for large writes... but also need a really good GC :c + "staging": badgerDs, // miner specific + "client": badgerDs, // client specific +} + +func badgerDs(path string) (datastore.Batching, error) { + opts := badger.DefaultOptions + opts.Truncate = true + + return badger.NewDatastore(path, &opts) +} + +func levelDs(path string) (datastore.Batching, error) { + return levelds.NewDatastore(path, &levelds.Options{ + Compression: ldbopts.NoCompression, + }) +} + +func (fsr *fsLockedRepo) openDatastore() (datastore.Batching, error) { + if err := os.MkdirAll(fsr.join(fsDatastore), 0755); err != nil { + return nil, xerrors.Errorf("mkdir %s: %w", fsr.join(fsDatastore), err) + } + + var mounts []mount.Mount + + for p, ctor := range fsDatastores { + prefix := datastore.NewKey(p) + + // TODO: optimization: don't init datastores we don't need + ds, err := ctor(fsr.join(filepath.Join(fsDatastore, p))) + if err != nil { + return nil, xerrors.Errorf("opening datastore %s: %w", prefix, err) + } + + ds = measure.New("fsrepo."+p, ds) + + mounts = append(mounts, mount.Mount{ + Prefix: prefix, + Datastore: ds, + }) + } + + return mount.New(mounts), nil +} + +func (fsr *fsLockedRepo) Datastore(ns string) (datastore.Batching, error) { + fsr.dsOnce.Do(func() { + fsr.ds, fsr.dsErr = fsr.openDatastore() + }) + if fsr.dsErr != nil { + return nil, fsr.dsErr + } + return namespace.Wrap(fsr.ds, datastore.NewKey(ns)), nil +} From 64f4e804467ac01863b1f39b7cdfc639117349b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 1 Jun 2020 20:43:51 +0200 Subject: [PATCH 040/379] Include build type in version --- Makefile | 2 +- build/params_2k.go | 2 ++ build/params_debug.go | 1 + build/version.go | 24 +++++++++++++++++++++++- cli/version.go | 4 +++- cmd/lotus-bench/main.go | 2 +- cmd/lotus-chainwatch/main.go | 2 +- cmd/lotus-fountain/main.go | 2 +- cmd/lotus-health/main.go | 2 +- cmd/lotus-seal-worker/main.go | 2 +- cmd/lotus-seed/main.go | 2 +- cmd/lotus-storage-miner/main.go | 2 +- cmd/lotus/main.go | 2 +- node/impl/common/common.go | 2 +- node/modules/lp2p/host.go | 2 +- 15 files changed, 40 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 7ffead022..99900e310 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ MODULES:= CLEAN:= BINS:= -ldflags=-X=github.com/filecoin-project/lotus/build.CurrentCommit='+git$(subst -,.,$(shell git describe --always --match=NeVeRmAtCh --dirty 2>/dev/null || git rev-parse --short HEAD 2>/dev/null))' +ldflags=-X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.$(subst -,.,$(shell git describe --always --match=NeVeRmAtCh --dirty 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)) ifneq ($(strip $(LDFLAGS)),) ldflags+=-extldflags=$(LDFLAGS) endif diff --git a/build/params_2k.go b/build/params_2k.go index ef1f2ac31..56e1ca2f8 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -16,6 +16,8 @@ func init() { abi.RegisteredProof_StackedDRG2KiBSeal: {}, } verifreg.MinVerifiedDealSize = big.NewInt(256) + + BuildType |= Build2k } // Seconds diff --git a/build/params_debug.go b/build/params_debug.go index e7c6d2e9e..f679c9178 100644 --- a/build/params_debug.go +++ b/build/params_debug.go @@ -4,6 +4,7 @@ package build func init() { InsecurePoStValidation = true + BuildType |= BuildDebug } // NOTE: Also includes settings from params_2k diff --git a/build/version.go b/build/version.go index e0ddebf36..7ee2afe65 100644 --- a/build/version.go +++ b/build/version.go @@ -3,11 +3,33 @@ package build import "fmt" var CurrentCommit string +var BuildType int + +const ( + BuildDefault = 0 + Build2k = 0x1 + BuildDebug = 0x3 +) + +func buildType() string { + switch BuildType { + case BuildDefault: + return "+default" + case BuildDebug: + return "+debug" + case Build2k: + return "+2k" + default: + return "+huh?" + } +} // BuildVersion is the local build version, set by build system const BuildVersion = "0.4.0" -var UserVersion = BuildVersion + CurrentCommit +func UserVersion() string { + return BuildVersion + buildType() + CurrentCommit +} type Version uint32 diff --git a/cli/version.go b/cli/version.go index cf4ad2932..50bc0d259 100644 --- a/cli/version.go +++ b/cli/version.go @@ -23,7 +23,9 @@ var versionCmd = &cli.Command{ if err != nil { return err } - fmt.Println(v) + fmt.Println("Daemon: ", v) + + fmt.Print("Local: ") cli.VersionPrinter(cctx) return nil }, diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 67fc1a43c..4ac52b497 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -78,7 +78,7 @@ func main() { app := &cli.App{ Name: "lotus-bench", Usage: "Benchmark performance of lotus on your hardware", - Version: build.UserVersion, + Version: build.UserVersion(), Commands: []*cli.Command{ proveCmd, sealBenchCmd, diff --git a/cmd/lotus-chainwatch/main.go b/cmd/lotus-chainwatch/main.go index a3114d8d0..4896cb366 100644 --- a/cmd/lotus-chainwatch/main.go +++ b/cmd/lotus-chainwatch/main.go @@ -29,7 +29,7 @@ func main() { app := &cli.App{ Name: "lotus-chainwatch", Usage: "Devnet token distribution utility", - Version: build.UserVersion, + Version: build.UserVersion(), Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 8fc1804d7..8882ba3f1 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -46,7 +46,7 @@ func main() { app := &cli.App{ Name: "lotus-fountain", Usage: "Devnet token distribution utility", - Version: build.UserVersion, + Version: build.UserVersion(), Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index 6f5ce8e90..264b3b84e 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -36,7 +36,7 @@ func main() { app := &cli.App{ Name: "lotus-health", Usage: "Tools for monitoring lotus daemon health", - Version: build.UserVersion, + Version: build.UserVersion(), Commands: local, Flags: []cli.Flag{ &cli.StringFlag{ diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index b43b7267f..e9721e9dd 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -47,7 +47,7 @@ func main() { app := &cli.App{ Name: "lotus-seal-worker", Usage: "Remote storage miner worker", - Version: build.UserVersion, + Version: build.UserVersion(), Flags: []cli.Flag{ &cli.StringFlag{ Name: FlagStorageRepo, diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index 7b80a0479..47dd850c0 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -39,7 +39,7 @@ func main() { app := &cli.App{ Name: "lotus-seed", Usage: "Seal sectors for genesis miner", - Version: build.UserVersion, + Version: build.UserVersion(), Flags: []cli.Flag{ &cli.StringFlag{ Name: "sector-dir", diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index 1186cbc28..e3e908fd1 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -57,7 +57,7 @@ func main() { app := &cli.App{ Name: "lotus-storage-miner", Usage: "Filecoin decentralized storage network storage miner", - Version: build.UserVersion, + Version: build.UserVersion(), EnableShellCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ diff --git a/cmd/lotus/main.go b/cmd/lotus/main.go index 33ff56ac3..4bc13d6fe 100644 --- a/cmd/lotus/main.go +++ b/cmd/lotus/main.go @@ -52,7 +52,7 @@ func main() { app := &cli.App{ Name: "lotus", Usage: "Filecoin decentralized storage network client", - Version: build.UserVersion, + Version: build.UserVersion(), EnableShellCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 5042d2ede..505466a8e 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -100,7 +100,7 @@ func (a *CommonAPI) ID(context.Context) (peer.ID, error) { func (a *CommonAPI) Version(context.Context) (api.Version, error) { return api.Version{ - Version: build.UserVersion, + Version: build.UserVersion(), APIVersion: build.APIVersion, BlockDelay: build.BlockDelay, diff --git a/node/modules/lp2p/host.go b/node/modules/lp2p/host.go index 2799dc8c3..b0436e9c9 100644 --- a/node/modules/lp2p/host.go +++ b/node/modules/lp2p/host.go @@ -46,7 +46,7 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost, libp2p.Peerstore(params.Peerstore), libp2p.NoListenAddrs, libp2p.Ping(true), - libp2p.UserAgent("lotus-" + build.UserVersion), + libp2p.UserAgent("lotus-" + build.UserVersion()), } for _, o := range params.Opts { opts = append(opts, o...) From a49dc90386d80bb963e1af24a4f5bd9983385be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 1 Jun 2020 21:11:37 +0200 Subject: [PATCH 041/379] Fix version test --- api/test/test.go | 8 ++++---- build/version.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/test/test.go b/api/test/test.go index 5972ca757..d28f2e0ee 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -4,9 +4,11 @@ import ( "context" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/stretchr/testify/assert" ) type TestNode struct { @@ -62,9 +64,7 @@ func (ts *testSuite) testVersion(t *testing.T) { if err != nil { t.Fatal(err) } - if v.Version != build.BuildVersion { - t.Error("Version didn't work properly") - } + require.Equal(t, v.Version, build.BuildVersion) } func (ts *testSuite) testID(t *testing.T) { diff --git a/build/version.go b/build/version.go index 7ee2afe65..51ef3e79d 100644 --- a/build/version.go +++ b/build/version.go @@ -14,7 +14,7 @@ const ( func buildType() string { switch BuildType { case BuildDefault: - return "+default" + return "" case BuildDebug: return "+debug" case Build2k: From 5605aae2694a419f32349fffd9566f901f782738 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 16:29:39 +0200 Subject: [PATCH 042/379] Fix even more lint warnings Signed-off-by: Jakub Sztandera --- .golangci.yml | 4 ++ api/docgen/docgen.go | 3 +- api/test/deals.go | 4 +- api/test/mining.go | 2 +- build/version.go | 2 +- chain/blocksync/blocksync_client.go | 22 +++--- chain/events/events.go | 14 ++-- chain/events/events_called.go | 27 +++---- chain/events/events_height.go | 8 +-- chain/events/events_test.go | 2 +- chain/gen/gen.go | 9 +-- chain/messagepool/messagepool_test.go | 30 ++++---- chain/state/statetree.go | 4 +- chain/stmgr/stmgr.go | 6 +- chain/stmgr/utils.go | 6 +- chain/store/store.go | 5 +- chain/sub/incoming.go | 5 +- chain/sync.go | 4 +- chain/types/blockheader.go | 8 +-- chain/types/message.go | 16 ++--- chain/types/signedmessage.go | 16 ++--- chain/types/tipset.go | 4 +- chain/types/tipset_key_test.go | 6 +- chain/vm/invoker.go | 14 ++-- chain/vm/invoker_test.go | 2 +- chain/vm/mkactor.go | 3 +- chain/vm/runtime.go | 100 +++++++++++++------------- chain/vm/syscalls.go | 16 +---- chain/vm/vm.go | 20 +++--- cmd/lotus-chainwatch/blockssub.go | 2 +- cmd/lotus-chainwatch/dot.go | 6 ++ cmd/lotus-chainwatch/main.go | 2 +- cmd/lotus-chainwatch/sync.go | 2 +- cmd/lotus-fountain/main.go | 6 +- lib/parmap/parmap.go | 5 +- lib/sigs/doc.go | 2 +- lib/sigs/sigs.go | 4 +- lotuspond/api.go | 2 +- lotuspond/main.go | 6 +- lotuspond/spawn.go | 7 +- node/impl/full/state.go | 2 +- node/impl/storminer.go | 6 +- node/repo/fsrepo.go | 3 +- tools/stats/metrics.go | 3 +- 44 files changed, 204 insertions(+), 216 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index c8805a7a3..76bbc1949 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -37,6 +37,10 @@ issues: - path: build/params_.*\.go linters: - golint + + - path: api/apistruct/struct.go + linters: + - golint - path: .*_test.go linters: diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index f2d4d6ce4..eb4ab5fd9 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -193,8 +193,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { const noComment = "There are not yet any comments for this method." -func parseApiASTInfo() (map[string]string, map[string]string) { - +func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint fset := token.NewFileSet() pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments) if err != nil { diff --git a/api/test/deals.go b/api/test/deals.go index c35f0af07..0150a1315 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -35,7 +35,7 @@ func init() { } func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) { - os.Setenv("BELLMAN_NO_GPU", "1") + _ = os.Setenv("BELLMAN_NO_GPU", "1") ctx := context.Background() n, sn := b(t, 1, oneMiner) @@ -72,7 +72,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport } func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) { - os.Setenv("BELLMAN_NO_GPU", "1") + _ = os.Setenv("BELLMAN_NO_GPU", "1") ctx := context.Background() n, sn := b(t, 1, oneMiner) diff --git a/api/test/mining.go b/api/test/mining.go index 374999df1..b19095450 100644 --- a/api/test/mining.go +++ b/api/test/mining.go @@ -82,7 +82,7 @@ func (ts *testSuite) testMiningReal(t *testing.T) { } func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) { - os.Setenv("BELLMAN_NO_GPU", "1") + _ = os.Setenv("BELLMAN_NO_GPU", "1") // test making a deal with a fresh miner, and see if it starts to mine diff --git a/build/version.go b/build/version.go index 51ef3e79d..d5766ce6e 100644 --- a/build/version.go +++ b/build/version.go @@ -55,7 +55,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool { // APIVersion is a semver version of the rpc api exposed var APIVersion Version = newVer(0, 3, 0) -//nolint:varcheck +//nolint:varcheck,deadcode const ( majorMask = 0xff0000 minorMask = 0xffff00 diff --git a/chain/blocksync/blocksync_client.go b/chain/blocksync/blocksync_client.go index f6453efde..129e8d332 100644 --- a/chain/blocksync/blocksync_client.go +++ b/chain/blocksync/blocksync_client.go @@ -561,26 +561,30 @@ func (bpt *bsPeerTracker) logSuccess(p peer.ID, dur time.Duration) { bpt.lk.Lock() defer bpt.lk.Unlock() - if pi, ok := bpt.peers[p]; !ok { + var pi *peerStats + var ok bool + if pi, ok = bpt.peers[p]; !ok { log.Warnw("log success called on peer not in tracker", "peerid", p.String()) return - } else { - pi.successes++ - - logTime(pi, dur) } + + pi.successes++ + logTime(pi, dur) } func (bpt *bsPeerTracker) logFailure(p peer.ID, dur time.Duration) { bpt.lk.Lock() defer bpt.lk.Unlock() - if pi, ok := bpt.peers[p]; !ok { + + var pi *peerStats + var ok bool + if pi, ok = bpt.peers[p]; !ok { log.Warn("log failure called on peer not in tracker", "peerid", p.String()) return - } else { - pi.failures++ - logTime(pi, dur) } + + pi.failures++ + logTime(pi, dur) } func (bpt *bsPeerTracker) removePeer(p peer.ID) { diff --git a/chain/events/events.go b/chain/events/events.go index c6d54d536..a325b5410 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -19,7 +19,7 @@ import ( var log = logging.Logger("events") -// `curH`-`ts.Height` = `confidence` +// HeightHandler `curH`-`ts.Height` = `confidence` type HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error type RevertHandler func(ctx context.Context, ts *types.TipSet) error @@ -31,7 +31,7 @@ type heightHandler struct { revert RevertHandler } -type eventApi interface { +type eventAPI interface { ChainNotify(context.Context) (<-chan []*api.HeadChange, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) @@ -42,7 +42,7 @@ type eventApi interface { } type Events struct { - api eventApi + api eventAPI tsc *tipSetCache lk sync.Mutex @@ -54,7 +54,7 @@ type Events struct { calledEvents } -func NewEvents(ctx context.Context, api eventApi) *Events { +func NewEvents(ctx context.Context, api eventAPI) *Events { gcConfidence := 2 * build.ForkLengthThreshold tsc := newTSCache(gcConfidence, api.ChainGetTipSetByHeight) @@ -82,9 +82,9 @@ func NewEvents(ctx context.Context, api eventApi) *Events { confQueue: map[triggerH]map[msgH][]*queuedEvent{}, revertQueue: map[msgH][]triggerH{}, - triggers: map[triggerId]*callHandler{}, - matchers: map[triggerId][]MatchFunc{}, - timeouts: map[abi.ChainEpoch]map[triggerId]int{}, + triggers: map[triggerID]*callHandler{}, + matchers: map[triggerID][]MatchFunc{}, + timeouts: map[abi.ChainEpoch]map[triggerID]int{}, }, } diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 0ddb9476a..c43130dac 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -14,7 +14,7 @@ import ( const NoTimeout = math.MaxInt64 -type triggerId = uint64 +type triggerID = uint64 // msgH is the block height at which a message was present / event has happened type msgH = abi.ChainEpoch @@ -23,6 +23,7 @@ type msgH = abi.ChainEpoch // message (msgH+confidence) type triggerH = abi.ChainEpoch +// CalledHandler // `ts` is the tipset, in which the `msg` is included. // `curH`-`ts.Height` = `confidence` type CalledHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) @@ -48,7 +49,7 @@ type callHandler struct { } type queuedEvent struct { - trigger triggerId + trigger triggerID h abi.ChainEpoch msg *types.Message @@ -57,7 +58,7 @@ type queuedEvent struct { } type calledEvents struct { - cs eventApi + cs eventAPI tsc *tipSetCache ctx context.Context gcConfidence uint64 @@ -66,10 +67,10 @@ type calledEvents struct { lk sync.Mutex - ctr triggerId + ctr triggerID - triggers map[triggerId]*callHandler - matchers map[triggerId][]MatchFunc + triggers map[triggerID]*callHandler + matchers map[triggerID][]MatchFunc // maps block heights to events // [triggerH][msgH][event] @@ -78,8 +79,8 @@ type calledEvents struct { // [msgH][triggerH] revertQueue map[msgH][]triggerH - // [timeoutH+confidence][triggerId]{calls} - timeouts map[abi.ChainEpoch]map[triggerId]int + // [timeoutH+confidence][triggerID]{calls} + timeouts map[abi.ChainEpoch]map[triggerID]int } func (e *calledEvents) headChangeCalled(rev, app []*types.TipSet) error { @@ -157,8 +158,8 @@ func (e *calledEvents) checkNewCalls(ts *types.TipSet) { }) } -func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message, ts *types.TipSet) { - trigger := e.triggers[triggerId] +func (e *calledEvents) queueForConfidence(trigID uint64, msg *types.Message, ts *types.TipSet) { + trigger := e.triggers[trigID] appliedH := ts.Height() @@ -171,7 +172,7 @@ func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message, } byOrigH[appliedH] = append(byOrigH[appliedH], &queuedEvent{ - trigger: triggerId, + trigger: trigID, h: appliedH, msg: msg, }) @@ -231,11 +232,11 @@ func (e *calledEvents) applyTimeouts(ts *types.TipSet) { return // nothing to do } - for triggerId, calls := range triggers { + for triggerID, calls := range triggers { if calls > 0 { continue // don't timeout if the method was called } - trigger := e.triggers[triggerId] + trigger := e.triggers[triggerID] if trigger.disabled { continue } diff --git a/chain/events/events_height.go b/chain/events/events_height.go index 1b89e7bd7..cbf756c20 100644 --- a/chain/events/events_height.go +++ b/chain/events/events_height.go @@ -15,12 +15,12 @@ type heightEvents struct { tsc *tipSetCache gcConfidence abi.ChainEpoch - ctr triggerId + ctr triggerID - heightTriggers map[triggerId]*heightHandler + heightTriggers map[triggerID]*heightHandler - htTriggerHeights map[triggerH][]triggerId - htHeights map[msgH][]triggerId + htTriggerHeights map[triggerH][]triggerID + htHeights map[msgH][]triggerID ctx context.Context } diff --git a/chain/events/events_test.go b/chain/events/events_test.go index aaf3908d0..7533494e9 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -219,7 +219,7 @@ func (fcs *fakeCS) notifDone() { fcs.sync.Unlock() } -var _ eventApi = &fakeCS{} +var _ eventAPI = &fakeCS{} func TestAt(t *testing.T) { fcs := &fakeCS{ diff --git a/chain/gen/gen.go b/chain/gen/gen.go index de2ad9226..d58bbc28e 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -431,7 +431,7 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke return fblk, err } -// This function is awkward. It's used to deal with messages made when +// ResyncBankerNonce is used for dealing with messages made when // simulating forks func (cg *ChainGen) ResyncBankerNonce(ts *types.TipSet) error { act, err := cg.sm.GetActor(cg.banker, ts) @@ -538,13 +538,6 @@ func (wpp *wppProvider) ComputeProof(context.Context, []abi.SectorInfo, abi.PoSt }}, nil } -type ProofInput struct { - sectors []abi.SectorInfo - hvrf []byte - challengedSectors []uint64 - vrfout []byte -} - func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, miner address.Address, brand types.BeaconEntry, mbi *api.MiningBaseInfo, a MiningCheckAPI) (*types.ElectionProof, error) { diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index 26d35a361..1667cdc5c 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -16,7 +16,7 @@ import ( "github.com/ipfs/go-datastore" ) -type testMpoolApi struct { +type testMpoolAPI struct { cb func(rev, app []*types.TipSet) error bmsgs map[cid.Cid][]*types.SignedMessage @@ -25,68 +25,68 @@ type testMpoolApi struct { tipsets []*types.TipSet } -func newTestMpoolApi() *testMpoolApi { - return &testMpoolApi{ +func newTestMpoolApi() *testMpoolAPI { + return &testMpoolAPI{ bmsgs: make(map[cid.Cid][]*types.SignedMessage), statenonce: make(map[address.Address]uint64), } } -func (tma *testMpoolApi) applyBlock(t *testing.T, b *types.BlockHeader) { +func (tma *testMpoolAPI) applyBlock(t *testing.T, b *types.BlockHeader) { t.Helper() if err := tma.cb(nil, []*types.TipSet{mock.TipSet(b)}); err != nil { t.Fatal(err) } } -func (tma *testMpoolApi) revertBlock(t *testing.T, b *types.BlockHeader) { +func (tma *testMpoolAPI) revertBlock(t *testing.T, b *types.BlockHeader) { t.Helper() if err := tma.cb([]*types.TipSet{mock.TipSet(b)}, nil); err != nil { t.Fatal(err) } } -func (tma *testMpoolApi) setStateNonce(addr address.Address, v uint64) { +func (tma *testMpoolAPI) setStateNonce(addr address.Address, v uint64) { tma.statenonce[addr] = v } -func (tma *testMpoolApi) setBlockMessages(h *types.BlockHeader, msgs ...*types.SignedMessage) { +func (tma *testMpoolAPI) setBlockMessages(h *types.BlockHeader, msgs ...*types.SignedMessage) { tma.bmsgs[h.Cid()] = msgs tma.tipsets = append(tma.tipsets, mock.TipSet(h)) } -func (tma *testMpoolApi) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet { +func (tma *testMpoolAPI) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet { tma.cb = cb return nil } -func (tma *testMpoolApi) PutMessage(m types.ChainMsg) (cid.Cid, error) { +func (tma *testMpoolAPI) PutMessage(m types.ChainMsg) (cid.Cid, error) { return cid.Undef, nil } -func (tma *testMpoolApi) PubSubPublish(string, []byte) error { +func (tma *testMpoolAPI) PubSubPublish(string, []byte) error { return nil } -func (tma *testMpoolApi) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) { +func (tma *testMpoolAPI) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) { return &types.Actor{ Nonce: tma.statenonce[addr], Balance: types.NewInt(90000000), }, nil } -func (tma *testMpoolApi) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { +func (tma *testMpoolAPI) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { if addr.Protocol() != address.BLS && addr.Protocol() != address.SECP256K1 { return address.Undef, fmt.Errorf("given address was not a key addr") } return addr, nil } -func (tma *testMpoolApi) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { +func (tma *testMpoolAPI) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { return nil, tma.bmsgs[h.Cid()], nil } -func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) { +func (tma *testMpoolAPI) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) { if len(ts.Blocks()) != 1 { panic("cant deal with multiblock tipsets in this test") } @@ -108,7 +108,7 @@ func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, return out, nil } -func (tma *testMpoolApi) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) { +func (tma *testMpoolAPI) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) { for _, ts := range tma.tipsets { if types.CidArrsEqual(tsk.Cids(), ts.Cids()) { return ts, nil diff --git a/chain/state/statetree.go b/chain/state/statetree.go index c93b1c83c..024524835 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -21,7 +21,7 @@ import ( var log = logging.Logger("statetree") -// Stores actors state by their ID. +// StateTree stores actors state by their ID. type StateTree struct { root *hamt.Node Store cbor.IpldStore @@ -149,7 +149,7 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error { return nil } -// `LookupID` gets the ID address of this actor's `addr` stored in the `InitActor`. +// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`. func (st *StateTree) LookupID(addr address.Address) (address.Address, error) { if addr.Protocol() == address.ID { return addr, nil diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 5a1eb88ea..17a9b58c1 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -326,7 +326,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl blkmsgs = append(blkmsgs, bm) } - return sm.ApplyBlocks(ctx, pstate, blkmsgs, abi.ChainEpoch(blks[0].Height), r, cb) + return sm.ApplyBlocks(ctx, pstate, blkmsgs, blks[0].Height, r, cb) } func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid { @@ -405,8 +405,8 @@ func (sm *StateManager) LoadActorStateRaw(ctx context.Context, a address.Address return act, nil } -// Similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses. Uses the `TipSet` `ts` -// to generate the VM state. +// ResolveToKeyAddr is similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses. +// Uses the `TipSet` `ts` to generate the VM state. func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { switch addr.Protocol() { case address.BLS, address.SECP256K1: diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 001882ec6..308c30823 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -286,7 +286,7 @@ func GetMinerRecoveries(ctx context.Context, sm *StateManager, ts *types.TipSet, return mas.Recoveries, nil } -func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) { +func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) { var state market.State if _, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil { return nil, err @@ -298,7 +298,7 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts } var dp market.DealProposal - if err := da.Get(ctx, uint64(dealId), &dp); err != nil { + if err := da.Get(ctx, uint64(dealID), &dp); err != nil { return nil, err } @@ -307,7 +307,7 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts return nil, err } - st, found, err := sa.Get(dealId) + st, found, err := sa.Get(dealID) if err != nil { return nil, err } diff --git a/chain/store/store.go b/chain/store/store.go index e8c04b11b..a9e1eb136 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -387,7 +387,7 @@ func (cs *ChainStore) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) { return ts, nil } -// returns true if 'a' is an ancestor of 'b' +// IsAncestorOf returns true if 'a' is an ancestor of 'b' func (cs *ChainStore) IsAncestorOf(a, b *types.TipSet) (bool, error) { if b.Height() <= a.Height() { return false, nil @@ -1154,7 +1154,6 @@ func (cr *chainRand) GetRandomness(ctx context.Context, pers crypto.DomainSepara func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) { if tsk.IsEmpty() { return cs.GetHeaviestTipSet(), nil - } else { - return cs.LoadTipSet(tsk) } + return cs.LoadTipSet(tsk) } diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index 2ef9c2718..8b5643de7 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -57,8 +57,7 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha return } - //nolint:golint - src := peer.ID(msg.GetFrom()) + src := msg.GetFrom() go func() { log.Infof("New block over pubsub: %s", blk.Cid()) @@ -207,7 +206,7 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub } } - err = sigs.CheckBlockSignature(blk.Header, ctx, key) + err = sigs.CheckBlockSignature(ctx, blk.Header, key) if err != nil { log.Errorf("block signature verification failed: %s", err) recordFailure("signature_verification_failed") diff --git a/chain/sync.go b/chain/sync.go index 23b790a06..f8a73356f 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -526,7 +526,7 @@ func blockSanityChecks(h *types.BlockHeader) error { return nil } -// Should match up with 'Semantical Validation' in validation.md in the spec +// ValidateBlock should match up with 'Semantical Validation' in validation.md in the spec func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { ctx, span := trace.StartSpan(ctx, "validateBlock") defer span.End() @@ -665,7 +665,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err }) blockSigCheck := async.Err(func() error { - if err := sigs.CheckBlockSignature(h, ctx, waddr); err != nil { + if err := sigs.CheckBlockSignature(ctx, h, waddr); err != nil { return xerrors.Errorf("check block signature failed: %w", err) } return nil diff --git a/chain/types/blockheader.go b/chain/types/blockheader.go index a5940d9e6..e238b3e5e 100644 --- a/chain/types/blockheader.go +++ b/chain/types/blockheader.go @@ -74,8 +74,8 @@ type BlockHeader struct { validated bool // true if the signature has been validated } -func (b *BlockHeader) ToStorageBlock() (block.Block, error) { - data, err := b.Serialize() +func (blk *BlockHeader) ToStorageBlock() (block.Block, error) { + data, err := blk.Serialize() if err != nil { return nil, err } @@ -89,8 +89,8 @@ func (b *BlockHeader) ToStorageBlock() (block.Block, error) { return block.NewBlockWithCid(data, c) } -func (b *BlockHeader) Cid() cid.Cid { - sb, err := b.ToStorageBlock() +func (blk *BlockHeader) Cid() cid.Cid { + sb, err := blk.ToStorageBlock() if err != nil { panic(err) // Not sure i'm entirely comfortable with this one, needs to be checked } diff --git a/chain/types/message.go b/chain/types/message.go index 0441eacca..68844d63c 100644 --- a/chain/types/message.go +++ b/chain/types/message.go @@ -41,20 +41,16 @@ type Message struct { Params []byte } -func (t *Message) BlockMiner() address.Address { - panic("implement me") +func (m *Message) Caller() address.Address { + return m.From } -func (t *Message) Caller() address.Address { - return t.From +func (m *Message) Receiver() address.Address { + return m.To } -func (t *Message) Receiver() address.Address { - return t.To -} - -func (t *Message) ValueReceived() abi.TokenAmount { - return t.Value +func (m *Message) ValueReceived() abi.TokenAmount { + return m.Value } func DecodeMessage(b []byte) (*Message, error) { diff --git a/chain/types/signedmessage.go b/chain/types/signedmessage.go index 802312ba9..54e82a957 100644 --- a/chain/types/signedmessage.go +++ b/chain/types/signedmessage.go @@ -9,12 +9,12 @@ import ( "github.com/multiformats/go-multihash" ) -func (m *SignedMessage) ToStorageBlock() (block.Block, error) { - if m.Signature.Type == crypto.SigTypeBLS { - return m.Message.ToStorageBlock() +func (sm *SignedMessage) ToStorageBlock() (block.Block, error) { + if sm.Signature.Type == crypto.SigTypeBLS { + return sm.Message.ToStorageBlock() } - data, err := m.Serialize() + data, err := sm.Serialize() if err != nil { return nil, err } @@ -28,12 +28,12 @@ func (m *SignedMessage) ToStorageBlock() (block.Block, error) { return block.NewBlockWithCid(data, c) } -func (m *SignedMessage) Cid() cid.Cid { - if m.Signature.Type == crypto.SigTypeBLS { - return m.Message.Cid() +func (sm *SignedMessage) Cid() cid.Cid { + if sm.Signature.Type == crypto.SigTypeBLS { + return sm.Message.Cid() } - sb, err := m.ToStorageBlock() + sb, err := sm.ToStorageBlock() if err != nil { panic(err) } diff --git a/chain/types/tipset.go b/chain/types/tipset.go index c1934d1d8..09483dc5e 100644 --- a/chain/types/tipset.go +++ b/chain/types/tipset.go @@ -23,8 +23,6 @@ type TipSet struct { height abi.ChainEpoch } -// why didnt i just export the fields? Because the struct has methods with the -// same names already type ExpTipSet struct { Cids []cid.Cid Blocks []*BlockHeader @@ -32,6 +30,8 @@ type ExpTipSet struct { } func (ts *TipSet) MarshalJSON() ([]byte, error) { + // why didnt i just export the fields? Because the struct has methods with the + // same names already return json.Marshal(ExpTipSet{ Cids: ts.cids, Blocks: ts.blks, diff --git a/chain/types/tipset_key_test.go b/chain/types/tipset_key_test.go index 43ff1a3df..7b3ce439d 100644 --- a/chain/types/tipset_key_test.go +++ b/chain/types/tipset_key_test.go @@ -61,9 +61,9 @@ func TestTipSetKey(t *testing.T) { t.Run("JSON", func(t *testing.T) { k0 := NewTipSetKey() - verifyJson(t, "[]", k0) + verifyJSON(t, "[]", k0) k3 := NewTipSetKey(c1, c2, c3) - verifyJson(t, `[`+ + verifyJSON(t, `[`+ `{"/":"bafy2bzacecesrkxghscnq7vatble2hqdvwat6ed23vdu4vvo3uuggsoaya7ki"},`+ `{"/":"bafy2bzacebxfyh2fzoxrt6kcgc5dkaodpcstgwxxdizrww225vrhsizsfcg4g"},`+ `{"/":"bafy2bzacedwviarjtjraqakob5pslltmuo5n3xev3nt5zylezofkbbv5jclyu"}`+ @@ -71,7 +71,7 @@ func TestTipSetKey(t *testing.T) { }) } -func verifyJson(t *testing.T, expected string, k TipSetKey) { +func verifyJSON(t *testing.T, expected string, k TipSetKey) { bytes, err := json.Marshal(k) require.NoError(t, err) assert.Equal(t, expected, string(bytes)) diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 5ad0e6ee4..8bbb27ecc 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -32,7 +32,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/aerrors" ) -type invoker struct { +type Invoker struct { builtInCode map[cid.Cid]nativeCode builtInState map[cid.Cid]reflect.Type } @@ -40,8 +40,8 @@ type invoker struct { type invokeFunc func(rt runtime.Runtime, params []byte) ([]byte, aerrors.ActorError) type nativeCode []invokeFunc -func NewInvoker() *invoker { - inv := &invoker{ +func NewInvoker() *Invoker { + inv := &Invoker{ builtInCode: make(map[cid.Cid]nativeCode), builtInState: make(map[cid.Cid]reflect.Type), } @@ -62,7 +62,7 @@ func NewInvoker() *invoker { return inv } -func (inv *invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) { +func (inv *Invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) { code, ok := inv.builtInCode[codeCid] if !ok { @@ -76,7 +76,7 @@ func (inv *invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.Metho } -func (inv *invoker) Register(c cid.Cid, instance Invokee, state interface{}) { +func (inv *Invoker) Register(c cid.Cid, instance Invokee, state interface{}) { code, err := inv.transform(instance) if err != nil { panic(xerrors.Errorf("%s: %w", string(c.Hash()), err)) @@ -89,9 +89,7 @@ type Invokee interface { Exports() []interface{} } -var tAError = reflect.TypeOf((*aerrors.ActorError)(nil)).Elem() - -func (*invoker) transform(instance Invokee) (nativeCode, error) { +func (*Invoker) transform(instance Invokee) (nativeCode, error) { itype := reflect.TypeOf(instance) exports := instance.Exports() for i, m := range exports { diff --git a/chain/vm/invoker_test.go b/chain/vm/invoker_test.go index b46b445a2..55b276421 100644 --- a/chain/vm/invoker_test.go +++ b/chain/vm/invoker_test.go @@ -76,7 +76,7 @@ func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams) } func TestInvokerBasic(t *testing.T) { - inv := invoker{} + inv := Invoker{} code, err := inv.transform(basicContract{}) assert.NoError(t, err) diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 6f3274114..1a3fd97de 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -2,6 +2,7 @@ package vm import ( "context" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin" @@ -27,7 +28,7 @@ func init() { var EmptyObjectCid cid.Cid -// Creates account actors from only BLS/SECP256K1 addresses. +// TryCreateAccountActor creates account actors from only BLS/SECP256K1 addresses. func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aerrors.ActorError) { addrID, err := rt.state.RegisterNewAddress(addr) if err != nil { diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 403a92fa7..b6598c5fe 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -106,8 +106,8 @@ type notFoundErr interface { IsNotFound() bool } -func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool { - if err := rs.cst.Get(context.TODO(), c, o); err != nil { +func (rt *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool { + if err := rt.cst.Get(context.TODO(), c, o); err != nil { var nfe notFoundErr if xerrors.As(err, &nfe) && nfe.IsNotFound() { if xerrors.As(err, new(cbor.SerializationError)) { @@ -121,8 +121,8 @@ func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool { return true } -func (rs *Runtime) Put(x vmr.CBORMarshaler) cid.Cid { - c, err := rs.cst.Put(context.TODO(), x) +func (rt *Runtime) Put(x vmr.CBORMarshaler) cid.Cid { + c, err := rt.cst.Put(context.TODO(), x) if err != nil { if xerrors.As(err, new(cbor.SerializationError)) { panic(aerrors.Newf(exitcode.ErrSerialization, "failed to marshal cbor object %s", err)) @@ -134,7 +134,7 @@ func (rs *Runtime) Put(x vmr.CBORMarshaler) cid.Cid { var _ vmr.Runtime = (*Runtime)(nil) -func (rs *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) { +func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) { defer func() { if r := recover(); r != nil { if ar, ok := r.(aerrors.ActorError); ok { @@ -149,8 +149,8 @@ func (rs *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act ret := f() - if !rs.callerValidated { - rs.Abortf(exitcode.SysErrorIllegalActor, "Caller MUST be validated during method execution") + if !rt.callerValidated { + rt.Abortf(exitcode.SysErrorIllegalActor, "Caller MUST be validated during method execution") } switch ret := ret.(type) { @@ -171,25 +171,25 @@ func (rs *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act } } -func (rs *Runtime) Message() vmr.Message { - return rs.vmsg +func (rt *Runtime) Message() vmr.Message { + return rt.vmsg } -func (rs *Runtime) ValidateImmediateCallerAcceptAny() { - rs.abortIfAlreadyValidated() +func (rt *Runtime) ValidateImmediateCallerAcceptAny() { + rt.abortIfAlreadyValidated() return } -func (rs *Runtime) CurrentBalance() abi.TokenAmount { - b, err := rs.GetBalance(rs.Message().Receiver()) +func (rt *Runtime) CurrentBalance() abi.TokenAmount { + b, err := rt.GetBalance(rt.Message().Receiver()) if err != nil { - rs.Abortf(err.RetCode(), "get current balance: %v", err) + rt.Abortf(err.RetCode(), "get current balance: %v", err) } return b } -func (rs *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) { - act, err := rs.state.GetActor(addr) +func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) { + act, err := rt.state.GetActor(addr) if err != nil { if xerrors.Is(err, types.ErrActorNotFound) { return cid.Undef, false @@ -209,8 +209,8 @@ func (rt *Runtime) GetRandomness(personalization crypto.DomainSeparationTag, ran return res } -func (rs *Runtime) Store() vmr.Store { - return rs +func (rt *Runtime) Store() vmr.Store { + return rt } func (rt *Runtime) NewActorAddress() address.Address { @@ -235,12 +235,12 @@ func (rt *Runtime) NewActorAddress() address.Address { return addr } -func (rt *Runtime) CreateActor(codeId cid.Cid, address address.Address) { - if !builtin.IsBuiltinActor(codeId) { +func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) { + if !builtin.IsBuiltinActor(codeID) { rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.") } - if builtin.IsSingletonActor(codeId) { + if builtin.IsSingletonActor(codeID) { rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.") } @@ -252,7 +252,7 @@ func (rt *Runtime) CreateActor(codeId cid.Cid, address address.Address) { rt.ChargeGas(rt.Pricelist().OnCreateActor()) err = rt.state.SetActor(address, &types.Actor{ - Code: codeId, + Code: codeID, Head: EmptyObjectCid, Nonce: 0, Balance: big.Zero(), @@ -282,12 +282,12 @@ func (rt *Runtime) DeleteActor(addr address.Address) { } } -func (rs *Runtime) Syscalls() vmr.Syscalls { +func (rt *Runtime) Syscalls() vmr.Syscalls { // TODO: Make sure this is wrapped in something that charges gas for each of the calls - return rs.sys + return rt.sys } -func (rs *Runtime) StartSpan(name string) vmr.TraceSpan { +func (rt *Runtime) StartSpan(name string) vmr.TraceSpan { panic("implement me") } @@ -307,12 +307,12 @@ func (rt *Runtime) Context() context.Context { return rt.ctx } -func (rs *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) { +func (rt *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) { log.Error("Abortf: ", fmt.Sprintf(msg, args...)) panic(aerrors.NewfSkip(2, code, msg, args...)) } -func (rs *Runtime) AbortStateMsg(msg string) { +func (rt *Runtime) AbortStateMsg(msg string) { panic(aerrors.NewfSkip(3, 101, msg)) } @@ -330,8 +330,8 @@ func (rt *Runtime) ValidateImmediateCallerType(ts ...cid.Cid) { rt.Abortf(exitcode.SysErrForbidden, "caller cid type %q was not one of %v", callerCid, ts) } -func (rs *Runtime) CurrEpoch() abi.ChainEpoch { - return rs.height +func (rt *Runtime) CurrEpoch() abi.ChainEpoch { + return rt.height } type dumbWrapperType struct { @@ -342,20 +342,20 @@ func (dwt *dumbWrapperType) Into(um vmr.CBORUnmarshaler) error { return um.UnmarshalCBOR(bytes.NewReader(dwt.val)) } -func (rs *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMarshaler, value abi.TokenAmount) (vmr.SendReturn, exitcode.ExitCode) { - if !rs.allowInternal { - rs.Abortf(exitcode.SysErrorIllegalActor, "runtime.Send() is currently disallowed") +func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMarshaler, value abi.TokenAmount) (vmr.SendReturn, exitcode.ExitCode) { + if !rt.allowInternal { + rt.Abortf(exitcode.SysErrorIllegalActor, "runtime.Send() is currently disallowed") } var params []byte if m != nil { buf := new(bytes.Buffer) if err := m.MarshalCBOR(buf); err != nil { - rs.Abortf(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err) + rt.Abortf(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err) } params = buf.Bytes() } - ret, err := rs.internalSend(rs.Message().Receiver(), to, method, value, params) + ret, err := rt.internalSend(rt.Message().Receiver(), to, method, value, params) if err != nil { if err.IsFatal() { panic(err) @@ -422,48 +422,48 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, return ret, errSend } -func (rs *Runtime) State() vmr.StateHandle { - return &shimStateHandle{rs: rs} +func (rt *Runtime) State() vmr.StateHandle { + return &shimStateHandle{rt: rt} } type shimStateHandle struct { - rs *Runtime + rt *Runtime } func (ssh *shimStateHandle) Create(obj vmr.CBORMarshaler) { - c := ssh.rs.Put(obj) + c := ssh.rt.Put(obj) // TODO: handle error below - ssh.rs.stateCommit(EmptyObjectCid, c) + ssh.rt.stateCommit(EmptyObjectCid, c) } func (ssh *shimStateHandle) Readonly(obj vmr.CBORUnmarshaler) { - act, err := ssh.rs.state.GetActor(ssh.rs.Message().Receiver()) + act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver()) if err != nil { - ssh.rs.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err) + ssh.rt.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err) } - ssh.rs.Get(act.Head, obj) + ssh.rt.Get(act.Head, obj) } func (ssh *shimStateHandle) Transaction(obj vmr.CBORer, f func() interface{}) interface{} { if obj == nil { - ssh.rs.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()") + ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()") } - act, err := ssh.rs.state.GetActor(ssh.rs.Message().Receiver()) + act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver()) if err != nil { - ssh.rs.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err) + ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err) } baseState := act.Head - ssh.rs.Get(baseState, obj) + ssh.rt.Get(baseState, obj) - ssh.rs.allowInternal = false + ssh.rt.allowInternal = false out := f() - ssh.rs.allowInternal = true + ssh.rt.allowInternal = true - c := ssh.rs.Put(obj) + c := ssh.rt.Put(obj) // TODO: handle error below - ssh.rs.stateCommit(baseState, c) + ssh.rt.stateCommit(baseState, c) return out } diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index 07d086d13..100472c69 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -184,7 +184,7 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error { return err } - if err := sigs.CheckBlockSignature(blk, ss.ctx, waddr); err != nil { + if err := sigs.CheckBlockSignature(ss.ctx, blk, waddr); err != nil { return err } @@ -202,20 +202,6 @@ func (ss *syscallShim) VerifyPoSt(proof abi.WindowPoStVerifyInfo) error { return nil } -func cidToCommD(c cid.Cid) [32]byte { - b := c.Bytes() - var out [32]byte - copy(out[:], b[len(b)-32:]) - return out -} - -func cidToCommR(c cid.Cid) [32]byte { - b := c.Bytes() - var out [32]byte - copy(out[:], b[len(b)-32:]) - return out -} - func (ss *syscallShim) VerifySeal(info abi.SealVerifyInfo) error { //_, span := trace.StartSpan(ctx, "ValidatePoRep") //defer span.End() diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 763708eca..da38fcbf3 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -131,7 +131,7 @@ type VM struct { cst *cbor.BasicIpldStore buf *bufbstore.BufferedBS blockHeight abi.ChainEpoch - inv *invoker + inv *Invoker rand Rand Syscalls runtime.Syscalls @@ -454,7 +454,7 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) { return root, nil } -// vm.MutateState(idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...}) +// MutateState usage: MutateState(ctx, idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...}) func (vm *VM) MutateState(ctx context.Context, addr address.Address, fn interface{}) error { act, err := vm.cstate.GetActor(addr) if err != nil { @@ -591,7 +591,7 @@ func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params return ret, nil } -func (vm *VM) SetInvoker(i *invoker) { +func (vm *VM) SetInvoker(i *Invoker) { vm.inv = i } @@ -607,17 +607,17 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor return nil } - fromId, err := vm.cstate.LookupID(from) + fromID, err := vm.cstate.LookupID(from) if err != nil { return aerrors.Fatalf("transfer failed when resolving sender address: %s", err) } - toId, err := vm.cstate.LookupID(to) + toID, err := vm.cstate.LookupID(to) if err != nil { return aerrors.Fatalf("transfer failed when resolving receiver address: %s", err) } - if fromId == toId { + if fromID == toID { return nil } @@ -625,12 +625,12 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor return aerrors.Newf(exitcode.SysErrForbidden, "attempted to transfer negative value: %s", amt) } - f, err := vm.cstate.GetActor(fromId) + f, err := vm.cstate.GetActor(fromID) if err != nil { return aerrors.Fatalf("transfer failed when retrieving sender actor: %s", err) } - t, err := vm.cstate.GetActor(toId) + t, err := vm.cstate.GetActor(toID) if err != nil { return aerrors.Fatalf("transfer failed when retrieving receiver actor: %s", err) } @@ -640,11 +640,11 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor } depositFunds(t, amt) - if err := vm.cstate.SetActor(fromId, f); err != nil { + if err := vm.cstate.SetActor(fromID, f); err != nil { return aerrors.Fatalf("transfer failed when setting receiver actor: %s", err) } - if err := vm.cstate.SetActor(toId, t); err != nil { + if err := vm.cstate.SetActor(toID, t); err != nil { return aerrors.Fatalf("transfer failed when setting sender actor: %s", err) } diff --git a/cmd/lotus-chainwatch/blockssub.go b/cmd/lotus-chainwatch/blockssub.go index 2147639a3..c569f1885 100644 --- a/cmd/lotus-chainwatch/blockssub.go +++ b/cmd/lotus-chainwatch/blockssub.go @@ -21,7 +21,7 @@ func subBlocks(ctx context.Context, api aapi.FullNode, st *storage) { bh.Cid(): bh, }, false) if err != nil { - //log.Errorf("%+v", err) + log.Errorf("%+v", err) } } } diff --git a/cmd/lotus-chainwatch/dot.go b/cmd/lotus-chainwatch/dot.go index e898f7cc3..22c8b7f05 100644 --- a/cmd/lotus-chainwatch/dot.go +++ b/cmd/lotus-chainwatch/dot.go @@ -20,7 +20,13 @@ var dotCmd = &cli.Command{ } minH, err := strconv.ParseInt(cctx.Args().Get(0), 10, 32) + if err != nil { + return err + } tosee, err := strconv.ParseInt(cctx.Args().Get(1), 10, 32) + if err != nil { + return err + } maxH := minH + tosee res, err := st.db.Query(`select block, parent, b.miner, b.height, p.height from block_parents diff --git a/cmd/lotus-chainwatch/main.go b/cmd/lotus-chainwatch/main.go index 4896cb366..faedb3bea 100644 --- a/cmd/lotus-chainwatch/main.go +++ b/cmd/lotus-chainwatch/main.go @@ -17,7 +17,7 @@ import ( var log = logging.Logger("chainwatch") func main() { - logging.SetLogLevel("*", "INFO") + _ = logging.SetLogLevel("*", "INFO") log.Info("Starting chainwatch") diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index ab2c5560c..d42a72b9b 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -146,7 +146,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS } if len(bh.Parents) == 0 { // genesis case - ts, err := types.NewTipSet([]*types.BlockHeader{bh}) + ts, _ := types.NewTipSet([]*types.BlockHeader{bh}) aadrs, err := api.StateListActors(ctx, ts.Key()) if err != nil { log.Error(err) diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 8882ba3f1..d4e41895b 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -215,14 +215,14 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) { owner, err := address.NewFromString(r.FormValue("address")) if err != nil { w.WriteHeader(400) - w.Write([]byte(err.Error())) + _, _ = w.Write([]byte(err.Error())) return } if owner.Protocol() != address.BLS { w.WriteHeader(400) - w.Write([]byte("Miner address must use BLS. A BLS address starts with the prefix 't3'.")) - w.Write([]byte("Please create a BLS address by running \"lotus wallet new bls\" while connected to a Lotus node.")) + _, _ = w.Write([]byte("Miner address must use BLS. A BLS address starts with the prefix 't3'.")) + _, _ = w.Write([]byte("Please create a BLS address by running \"lotus wallet new bls\" while connected to a Lotus node.")) return } diff --git a/lib/parmap/parmap.go b/lib/parmap/parmap.go index 50613509e..b08594739 100644 --- a/lib/parmap/parmap.go +++ b/lib/parmap/parmap.go @@ -5,6 +5,7 @@ import ( "sync" ) +// MapArr transforms map into slice of map values func MapArr(in interface{}) interface{} { rin := reflect.ValueOf(in) rout := reflect.MakeSlice(reflect.SliceOf(rin.Type().Elem()), rin.Len(), rin.Len()) @@ -19,6 +20,7 @@ func MapArr(in interface{}) interface{} { return rout.Interface() } +// KMapArr transforms map into slice of map keys func KMapArr(in interface{}) interface{} { rin := reflect.ValueOf(in) rout := reflect.MakeSlice(reflect.SliceOf(rin.Type().Key()), rin.Len(), rin.Len()) @@ -33,7 +35,8 @@ func KMapArr(in interface{}) interface{} { return rout.Interface() } -// map[k]v => []func() (k, v) +// KMapArr transforms map into slice of functions returning (key, val) pairs. +// map[A]B => []func()(A, B) func KVMapArr(in interface{}) interface{} { rin := reflect.ValueOf(in) diff --git a/lib/sigs/doc.go b/lib/sigs/doc.go index 637cd2bcd..ca3093f39 100644 --- a/lib/sigs/doc.go +++ b/lib/sigs/doc.go @@ -1,4 +1,4 @@ -// Sigs package allows for signing, verifying signatures and key generation +// Package sigs allows for signing, verifying signatures and key generation // using key types selected by package user. // // For support of secp256k1 import: diff --git a/lib/sigs/sigs.go b/lib/sigs/sigs.go index 2f624ed76..4a4fd7340 100644 --- a/lib/sigs/sigs.go +++ b/lib/sigs/sigs.go @@ -68,7 +68,7 @@ func ToPublic(sigType crypto.SigType, pk []byte) ([]byte, error) { return sv.ToPublic(pk) } -func CheckBlockSignature(blk *types.BlockHeader, ctx context.Context, worker address.Address) error { +func CheckBlockSignature(ctx context.Context, blk *types.BlockHeader, worker address.Address) error { _, span := trace.StartSpan(ctx, "checkBlockSignature") defer span.End() @@ -103,7 +103,7 @@ type SigShim interface { var sigs map[crypto.SigType]SigShim -// RegisterSig should be only used during init +// RegisterSignature should be only used during init func RegisterSignature(typ crypto.SigType, vs SigShim) { if sigs == nil { sigs = make(map[crypto.SigType]SigShim) diff --git a/lotuspond/api.go b/lotuspond/api.go index 1f1432ca1..169cec1de 100644 --- a/lotuspond/api.go +++ b/lotuspond/api.go @@ -32,7 +32,7 @@ type api struct { type nodeInfo struct { Repo string ID int32 - ApiPort int32 + APIPort int32 State NodeState FullNode string // only for storage nodes diff --git a/lotuspond/main.go b/lotuspond/main.go index 3abcda635..8551a25dc 100644 --- a/lotuspond/main.go +++ b/lotuspond/main.go @@ -37,7 +37,7 @@ var onCmd = &cli.Command{ return err } - node := nodeById(client.Nodes(), int(nd)) + node := nodeByID(client.Nodes(), int(nd)) var cmd *exec.Cmd if !node.Storage { cmd = exec.Command("./lotus", cctx.Args().Slice()[1:]...) @@ -75,7 +75,7 @@ var shCmd = &cli.Command{ return err } - node := nodeById(client.Nodes(), int(nd)) + node := nodeByID(client.Nodes(), int(nd)) shcmd := exec.Command("/bin/bash") if !node.Storage { shcmd.Env = []string{ @@ -102,7 +102,7 @@ var shCmd = &cli.Command{ }, } -func nodeById(nodes []nodeInfo, i int) nodeInfo { +func nodeByID(nodes []nodeInfo, i int) nodeInfo { for _, n := range nodes { if n.ID == int32(i) { return n diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index 76b3f3aa2..32fc69b05 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "fmt" - "github.com/filecoin-project/lotus/chain/types" "io" "io/ioutil" "os" @@ -12,6 +11,8 @@ import ( "sync/atomic" "time" + "github.com/filecoin-project/lotus/chain/types" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -122,7 +123,7 @@ func (api *api) Spawn() (nodeInfo, error) { info := nodeInfo{ Repo: dir, ID: id, - ApiPort: 2500 + id, + APIPort: 2500 + id, State: NodeRunning, } @@ -198,7 +199,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { info := nodeInfo{ Repo: dir, ID: id, - ApiPort: 2500 + id, + APIPort: 2500 + id, State: NodeRunning, FullNode: fullNodeRepo, diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 4e613a1b0..9b83e6ff9 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -682,7 +682,7 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add return act.Balance, nil } - minBalance := types.BigDiv(types.BigInt(st.InitialBalance), types.NewInt(uint64(st.UnlockDuration))) + minBalance := types.BigDiv(st.InitialBalance, types.NewInt(uint64(st.UnlockDuration))) minBalance = types.BigMul(minBalance, types.NewInt(uint64(offset))) return types.BigSub(act.Balance, minBalance), nil } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 491ce27bb..cca706746 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -46,7 +46,7 @@ type StorageMinerAPI struct { func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) { w.WriteHeader(401) - json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) + _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) return } @@ -185,7 +185,7 @@ func (sm *StorageMinerAPI) MarketImportDealData(ctx context.Context, propCid cid if err != nil { return xerrors.Errorf("failed to open file: %w", err) } - defer fi.Close() + defer fi.Close() //nolint:errcheck return sm.StorageProvider.ImportDataForDeal(ctx, propCid, fi) } @@ -211,7 +211,7 @@ func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fn if err != nil { return xerrors.Errorf("failed to open given file: %w", err) } - defer fi.Close() + defer fi.Close() //nolint:errcheck return sm.StorageProvider.ImportDataForDeal(ctx, deal, fi) } diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 75b560d65..6733b0868 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -63,8 +63,7 @@ var ErrRepoExists = xerrors.New("repo exists") // FsRepo is struct for repo, use NewFS to create type FsRepo struct { - path string - repoType RepoType + path string } var _ Repo = &FsRepo{} diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index 9c6887723..eb653e1d7 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -38,8 +38,7 @@ func (pl *PointList) Points() []models.Point { } type InfluxWriteQueue struct { - influx client.Client - ch chan client.BatchPoints + ch chan client.BatchPoints } func NewInfluxWriteQueue(ctx context.Context, influx client.Client) *InfluxWriteQueue { From 96ade5f2dd1e5c7bc67cf7b4b7e7b17a1ffce96c Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 18:38:41 +0200 Subject: [PATCH 043/379] Cleanup more lint warnings Signed-off-by: Jakub Sztandera --- chain/events/events_called.go | 2 +- chain/events/events_test.go | 4 ---- chain/events/utils.go | 2 +- chain/messagepool/messagepool_test.go | 6 +++--- chain/stmgr/stmgr.go | 2 +- lib/parmap/parmap.go | 2 +- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/chain/events/events_called.go b/chain/events/events_called.go index c43130dac..04e7be715 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -23,7 +23,7 @@ type msgH = abi.ChainEpoch // message (msgH+confidence) type triggerH = abi.ChainEpoch -// CalledHandler +// CalledHandler arguments: // `ts` is the tipset, in which the `msg` is included. // `curH`-`ts.Height` = `confidence` type CalledHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 7533494e9..c81c04b32 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -209,10 +209,6 @@ func (fcs *fakeCS) advance(rev, app int, msgs map[int]cid.Cid, nulls ...int) { / fcs.sync.Lock() fcs.sub(revs, apps) - - fcs.sync.Lock() - fcs.sync.Unlock() - } func (fcs *fakeCS) notifDone() { diff --git a/chain/events/utils.go b/chain/events/utils.go index 1f4ca381b..d525e5368 100644 --- a/chain/events/utils.go +++ b/chain/events/utils.go @@ -36,7 +36,7 @@ func (e *calledEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd Ca func (e *calledEvents) MatchMsg(inmsg *types.Message) MatchFunc { return func(msg *types.Message) (bool, error) { if msg.From == inmsg.From && msg.Nonce == inmsg.Nonce && !inmsg.Equals(msg) { - return false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %s", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce) + return false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce) } return inmsg.Equals(msg), nil diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index 1667cdc5c..d1dedd534 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -25,7 +25,7 @@ type testMpoolAPI struct { tipsets []*types.TipSet } -func newTestMpoolApi() *testMpoolAPI { +func newTestMpoolAPI() *testMpoolAPI { return &testMpoolAPI{ bmsgs: make(map[cid.Cid][]*types.SignedMessage), statenonce: make(map[address.Address]uint64), @@ -138,7 +138,7 @@ func mustAdd(t *testing.T, mp *MessagePool, msg *types.SignedMessage) { } func TestMessagePool(t *testing.T) { - tma := newTestMpoolApi() + tma := newTestMpoolAPI() w, err := wallet.NewWallet(wallet.NewMemKeyStore()) if err != nil { @@ -179,7 +179,7 @@ func TestMessagePool(t *testing.T) { } func TestRevertMessages(t *testing.T) { - tma := newTestMpoolApi() + tma := newTestMpoolAPI() w, err := wallet.NewWallet(wallet.NewMemKeyStore()) if err != nil { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 17a9b58c1..a4bef46a2 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -405,7 +405,7 @@ func (sm *StateManager) LoadActorStateRaw(ctx context.Context, a address.Address return act, nil } -// ResolveToKeyAddr is similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses. +// ResolveToKeyAddress is similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses. // Uses the `TipSet` `ts` to generate the VM state. func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { switch addr.Protocol() { diff --git a/lib/parmap/parmap.go b/lib/parmap/parmap.go index b08594739..dcf0ef3c8 100644 --- a/lib/parmap/parmap.go +++ b/lib/parmap/parmap.go @@ -35,7 +35,7 @@ func KMapArr(in interface{}) interface{} { return rout.Interface() } -// KMapArr transforms map into slice of functions returning (key, val) pairs. +// KVMapArr transforms map into slice of functions returning (key, val) pairs. // map[A]B => []func()(A, B) func KVMapArr(in interface{}) interface{} { rin := reflect.ValueOf(in) From 22851df145479460ba3b0d05a618530cbf3fdfd2 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 18:45:50 +0200 Subject: [PATCH 044/379] Undo change in events_test Signed-off-by: Jakub Sztandera --- chain/events/events_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index c81c04b32..a048789ec 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -209,6 +209,9 @@ func (fcs *fakeCS) advance(rev, app int, msgs map[int]cid.Cid, nulls ...int) { / fcs.sync.Lock() fcs.sub(revs, apps) + + fcs.sync.Lock() + fcs.sync.Unlock() //nolint:staticcheck } func (fcs *fakeCS) notifDone() { From d7a2556292243984c2aa0539b3185f27f347f08d Mon Sep 17 00:00:00 2001 From: acruikshank Date: Tue, 2 Jun 2020 16:43:39 -0400 Subject: [PATCH 045/379] expand tilda before passing file name into chain import --- cmd/lotus/daemon.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 91af88a4e..8506b521d 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -150,6 +150,11 @@ var DaemonCmd = &cli.Command{ chainfile := cctx.String("import-chain") if chainfile != "" { + chainfile, err := homedir.Expand(chainfile) + if err != nil { + return err + } + if err := ImportChain(r, chainfile); err != nil { return err } From 1fd20b636bedbce56714d3090c6fffa2e28f49b3 Mon Sep 17 00:00:00 2001 From: acruikshank Date: Tue, 2 Jun 2020 16:48:50 -0400 Subject: [PATCH 046/379] tidy --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index ed91f8560..dc0908832 100644 --- a/go.sum +++ b/go.sum @@ -156,8 +156,6 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1 github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= github.com/filecoin-project/go-fil-markets v0.2.7 h1:bgdK/e+xW15aVZLtdFLzAHdrx1hqtGF9veg2lstLK6o= github.com/filecoin-project/go-fil-markets v0.2.7/go.mod h1:LI3VFHse33aU0djAmFQ8+Hg39i0J8ibAoppGu6TbgkA= -github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200520183639-7c6ee2e066b4 h1:H8AVYu0MV9m3CSnKMxeILMfh8xJtnqVdXfBF/qbzgu0= -github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200520183639-7c6ee2e066b4/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= From 3423d298156dcce5a587f5b77457762aceedd6cd Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 22:54:29 +0200 Subject: [PATCH 047/379] Prune go mod cache Circle reports 1.9GB, should be closer to 300MB Signed-off-by: Jakub Sztandera --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 700f1fbc9..858b21123 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -115,7 +115,7 @@ jobs: - go/mod-download - restore_cache: name: restore go mod cache - key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} + key: v2-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} - run: command: make debug @@ -162,7 +162,7 @@ jobs: - go/mod-download - restore_cache: name: restore go mod cache - key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} + key: v2-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} - run: command: make deps lotus no_output_timeout: 30m From 415b69155bbfcaf9431858819832f0518d998f19 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 23:02:37 +0200 Subject: [PATCH 048/379] Disable caches Signed-off-by: Jakub Sztandera --- .circleci/config.yml | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 858b21123..3b22557de 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ version: 2.1 orbs: - go: gotest/tools@0.0.9 + go: gotest/tools@0.0.13 executors: golang: @@ -79,7 +79,6 @@ jobs: steps: - install-deps - prepare - - go/mod-download - go/mod-tidy-check build-all: @@ -90,9 +89,6 @@ jobs: - go/mod-download - run: sudo apt-get update - run: sudo apt-get install npm - - restore_cache: - name: restore go mod cache - key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} - run: command: make buildall - store_artifacts: @@ -112,10 +108,6 @@ jobs: steps: - install-deps - prepare - - go/mod-download - - restore_cache: - name: restore go mod cache - key: v2-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} - run: command: make debug @@ -160,9 +152,6 @@ jobs: - install-deps - prepare - go/mod-download - - restore_cache: - name: restore go mod cache - key: v2-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} - run: command: make deps lotus no_output_timeout: 30m @@ -193,13 +182,6 @@ jobs: shell: /bin/bash -eo pipefail command: | bash <(curl -s https://codecov.io/bash) - - save_cache: - name: save go mod cache - key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }} - paths: - - "~/go/pkg" - - "~/go/src/github.com" - - "~/go/src/golang.org" test-short: <<: *test @@ -234,7 +216,7 @@ jobs: curl --location https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64 --output /usr/local/bin/jq chmod +x /usr/local/bin/jq - restore_cache: - name: restore go mod and cargo cache + name: restore cargo cache key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} - install-deps - go/mod-download From 9326cb5411a80915593aa200cf70e570143f4ab5 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 23:07:48 +0200 Subject: [PATCH 049/379] Update golangci-lint, increase its timeout Signed-off-by: Jakub Sztandera --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3b22557de..1da5c7952 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -259,7 +259,7 @@ jobs: default: golang golangci-lint-version: type: string - default: 1.23.8 + default: 1.27.0 concurrency: type: string default: '2' @@ -285,7 +285,7 @@ jobs: - run: name: Lint command: | - $HOME/.local/bin/golangci-lint run -v \ + $HOME/.local/bin/golangci-lint run -v --timeout 2m \ --concurrency << parameters.concurrency >> << parameters.args >> lint-changes: <<: *lint From 42c76aaebcce87d9d7e6d8d002b445b1cdd07c8a Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 23:11:07 +0200 Subject: [PATCH 050/379] Remove mod-download Signed-off-by: Jakub Sztandera --- .circleci/config.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1da5c7952..cbbc9514a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -86,7 +86,6 @@ jobs: steps: - install-deps - prepare - - go/mod-download - run: sudo apt-get update - run: sudo apt-get install npm - run: @@ -151,7 +150,6 @@ jobs: steps: - install-deps - prepare - - go/mod-download - run: command: make deps lotus no_output_timeout: 30m @@ -219,7 +217,6 @@ jobs: name: restore cargo cache key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} - install-deps - - go/mod-download - run: command: make build no_output_timeout: 30m @@ -246,7 +243,6 @@ jobs: steps: - install-deps - prepare - - go/mod-download - run: command: "! go fmt ./... 2>&1 | read" @@ -275,7 +271,6 @@ jobs: steps: - install-deps - prepare - - go/mod-download - run: command: make deps no_output_timeout: 30m From 2fdcf5347b9ddf9381e26525d99d179107e9fdd3 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 2 Jun 2020 17:35:23 -0700 Subject: [PATCH 051/379] reuse GetTipsetByHeight in GetRandomness --- chain/store/store.go | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/chain/store/store.go b/chain/store/store.go index 1d0668032..c9dac2e31 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -909,25 +909,26 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers cr defer span.End() span.AddAttributes(trace.Int64Attribute("round", int64(round))) - //defer func() { - //log.Infof("getRand %v %d %d %x -> %x", blks, pers, round, entropy, out) - //}() - for { - nts, err := cs.LoadTipSet(types.NewTipSetKey(blks...)) - if err != nil { - return nil, err - } - - mtb := nts.MinTicketBlock() - - // if at (or just past -- for null epochs) appropriate epoch - // or at genesis (works for negative epochs) - if nts.Height() <= round || mtb.Height == 0 { - return DrawRandomness(nts.MinTicketBlock().Ticket.VRFProof, pers, round, entropy) - } - - blks = mtb.Parents + ts, err := cs.LoadTipSet(types.NewTipSetKey(blks...)) + if err != nil { + return nil, err } + + searchHeight := round + if searchHeight < 0 { + searchHeight = 0 + } + + randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, true) + if err != nil { + return nil, err + } + + mtb := randTs.MinTicketBlock() + + // if at (or just past -- for null epochs) appropriate epoch + // or at genesis (works for negative epochs) + return DrawRandomness(mtb.Ticket.VRFProof, pers, round, entropy) } // GetTipsetByHeight returns the tipset on the chain behind 'ts' at the given From 186fd4da74e019ce1bbdacbca1b237e1b0ec4e83 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 3 Jun 2020 03:13:49 +0200 Subject: [PATCH 052/379] Add `lotus net scores` for pubsub score visibility Signed-off-by: Jakub Sztandera --- api/api_common.go | 1 + api/apistruct/struct.go | 4 ++++ api/types.go | 6 ++++++ cli/net.go | 26 +++++++++++++++++++++++++- node/builder.go | 1 + node/impl/common/common.go | 18 ++++++++++++++++++ node/modules/dtypes/scorekeeper.go | 24 ++++++++++++++++++++++++ node/modules/lp2p/pubsub.go | 7 ++++++- 8 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 node/modules/dtypes/scorekeeper.go diff --git a/api/api_common.go b/api/api_common.go index a49397247..7f0514fdf 100644 --- a/api/api_common.go +++ b/api/api_common.go @@ -25,6 +25,7 @@ type Common interface { NetAddrsListen(context.Context) (peer.AddrInfo, error) NetDisconnect(context.Context, peer.ID) error NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error) + NetPubsubScores(context.Context) ([]PubsubScore, error) // ID returns peerID of libp2p node backing this API ID(context.Context) (peer.ID, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 1f2191ae8..8532cad11 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -42,6 +42,7 @@ type CommonStruct struct { NetAddrsListen func(context.Context) (peer.AddrInfo, error) `perm:"read"` NetDisconnect func(context.Context, peer.ID) error `perm:"write"` NetFindPeer func(context.Context, peer.ID) (peer.AddrInfo, error) `perm:"read"` + NetPubsubScores func(context.Context) ([]api.PubsubScore, error) `perm:"read"` ID func(context.Context) (peer.ID, error) `perm:"read"` Version func(context.Context) (api.Version, error) `perm:"read"` @@ -256,6 +257,9 @@ func (c *CommonStruct) AuthNew(ctx context.Context, perms []auth.Permission) ([] return c.Internal.AuthNew(ctx, perms) } +func (c *CommonStruct) NetPubsubScores(ctx context.Context) ([]api.PubsubScore, error) { + return c.Internal.NetPubsubScores(ctx) +} func (c *CommonStruct) NetConnectedness(ctx context.Context, pid peer.ID) (network.Connectedness, error) { return c.Internal.NetConnectedness(ctx, pid) } diff --git a/api/types.go b/api/types.go index 26d0695e1..fcc013441 100644 --- a/api/types.go +++ b/api/types.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" + "github.com/libp2p/go-libp2p-core/peer" ma "github.com/multiformats/go-multiaddr" ) @@ -33,3 +34,8 @@ type ObjStat struct { Size uint64 Links uint64 } + +type PubsubScore struct { + ID peer.ID + Score float64 +} diff --git a/cli/net.go b/cli/net.go index b49d9604f..366162c3f 100644 --- a/cli/net.go +++ b/cli/net.go @@ -21,6 +21,7 @@ var netCmd = &cli.Command{ netListen, netId, netFindPeer, + netScores, }, } @@ -44,7 +45,30 @@ var netPeers = &cli.Command{ }) for _, peer := range peers { - fmt.Println(peer) + fmt.Printf("%s, %s\n", peer.ID, peer.Addrs) + } + + return nil + }, +} + +var netScores = &cli.Command{ + Name: "scores", + Usage: "Print peers' pubsub scores", + Action: func(cctx *cli.Context) error { + api, closer, err := GetAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + scores, err := api.NetPubsubScores(ctx) + if err != nil { + return err + } + + for _, peer := range scores { + fmt.Printf("%s, %f\n", peer.ID, peer.Score) } return nil diff --git a/node/builder.go b/node/builder.go index 3b8e0d62f..292cf39e6 100644 --- a/node/builder.go +++ b/node/builder.go @@ -180,6 +180,7 @@ func libp2p() Option { Override(ConnectionManagerKey, lp2p.ConnectionManager(50, 200, 20*time.Second, nil)), Override(AutoNATSvcKey, lp2p.AutoNATService), + Override(new(*dtypes.ScoreKeeper), lp2p.ScoreKeeper), Override(new(*pubsub.PubSub), lp2p.GossipSub), Override(new(*config.Pubsub), func(bs dtypes.Bootstrapper) *config.Pubsub { return &config.Pubsub{ diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 505466a8e..6de137d9f 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -2,6 +2,8 @@ package common import ( "context" + "sort" + "strings" logging "github.com/ipfs/go-log/v2" @@ -28,6 +30,7 @@ type CommonAPI struct { APISecret *dtypes.APIAlg Host host.Host Router lp2p.BaseIpfsRouting + Sk *dtypes.ScoreKeeper } type jwtPayload struct { @@ -54,6 +57,21 @@ func (a *CommonAPI) AuthNew(ctx context.Context, perms []auth.Permission) ([]byt func (a *CommonAPI) NetConnectedness(ctx context.Context, pid peer.ID) (network.Connectedness, error) { return a.Host.Network().Connectedness(pid), nil } +func (a *CommonAPI) NetPubsubScores(context.Context) ([]api.PubsubScore, error) { + scores := a.Sk.Get() + out := make([]api.PubsubScore, len(scores)) + i := 0 + for k, v := range scores { + out[i] = api.PubsubScore{k, v} + i++ + } + + sort.Slice(out, func(i, j int) bool { + return strings.Compare(string(out[i].ID), string(out[j].ID)) > 0 + }) + + return out, nil +} func (a *CommonAPI) NetPeers(context.Context) ([]peer.AddrInfo, error) { conns := a.Host.Network().Conns() diff --git a/node/modules/dtypes/scorekeeper.go b/node/modules/dtypes/scorekeeper.go new file mode 100644 index 000000000..221821bf8 --- /dev/null +++ b/node/modules/dtypes/scorekeeper.go @@ -0,0 +1,24 @@ +package dtypes + +import ( + "sync" + + peer "github.com/libp2p/go-libp2p-peer" +) + +type ScoreKeeper struct { + lk sync.Mutex + scores map[peer.ID]float64 +} + +func (sk *ScoreKeeper) Update(scores map[peer.ID]float64) { + sk.lk.Lock() + sk.scores = scores + sk.lk.Unlock() +} + +func (sk *ScoreKeeper) Get() map[peer.ID]float64 { + sk.lk.Lock() + defer sk.lk.Unlock() + return sk.scores +} diff --git a/node/modules/lp2p/pubsub.go b/node/modules/lp2p/pubsub.go index 35285f5c1..739bbd115 100644 --- a/node/modules/lp2p/pubsub.go +++ b/node/modules/lp2p/pubsub.go @@ -28,7 +28,11 @@ func init() { pubsub.GossipSubDirectConnectInitialDelay = 30 * time.Second } -func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtypes.NetworkName, bp dtypes.BootstrapPeers, cfg *config.Pubsub) (service *pubsub.PubSub, err error) { +func ScoreKeeper() *dtypes.ScoreKeeper { + return new(dtypes.ScoreKeeper) +} + +func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtypes.NetworkName, bp dtypes.BootstrapPeers, cfg *config.Pubsub, sk *dtypes.ScoreKeeper) (service *pubsub.PubSub, err error) { bootstrappers := make(map[peer.ID]struct{}) for _, pi := range bp { bootstrappers[pi.ID] = struct{}{} @@ -161,6 +165,7 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp OpportunisticGraftThreshold: 5, }, ), + pubsub.WithPeerScoreInspect(sk.Update, 10*time.Second), } // enable Peer eXchange on bootstrappers From 7f962e19c2821601bcfaec6bfc9dd52fa717982e Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 3 Jun 2020 03:19:18 +0200 Subject: [PATCH 053/379] Fix lint Signed-off-by: Jakub Sztandera --- node/impl/common/common.go | 2 +- node/modules/dtypes/scorekeeper.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 6de137d9f..a0620c65b 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -62,7 +62,7 @@ func (a *CommonAPI) NetPubsubScores(context.Context) ([]api.PubsubScore, error) out := make([]api.PubsubScore, len(scores)) i := 0 for k, v := range scores { - out[i] = api.PubsubScore{k, v} + out[i] = api.PubsubScore{ID: k, Score: v} i++ } diff --git a/node/modules/dtypes/scorekeeper.go b/node/modules/dtypes/scorekeeper.go index 221821bf8..74bcb3f46 100644 --- a/node/modules/dtypes/scorekeeper.go +++ b/node/modules/dtypes/scorekeeper.go @@ -3,7 +3,7 @@ package dtypes import ( "sync" - peer "github.com/libp2p/go-libp2p-peer" + peer "github.com/libp2p/go-libp2p-core/peer" ) type ScoreKeeper struct { From 5574e4f11bd4b333e5170ba7c432556ce9e09813 Mon Sep 17 00:00:00 2001 From: acruikshank Date: Wed, 3 Jun 2020 15:38:37 -0400 Subject: [PATCH 054/379] add confidence and timeout to message wait --- api/api_full.go | 2 +- api/apistruct/struct.go | 6 ++-- build/params_shared.go | 2 ++ chain/stmgr/stmgr.go | 46 ++++++++++++++++++++++++++---- cli/multisig.go | 7 +++-- cli/paych.go | 3 +- cli/state.go | 5 ++-- cmd/lotus-fountain/main.go | 4 +-- cmd/lotus-shed/verifreg.go | 5 ++-- cmd/lotus-storage-miner/init.go | 4 +-- markets/retrievaladapter/client.go | 5 ++-- markets/storageadapter/client.go | 4 +-- markets/storageadapter/provider.go | 2 +- node/impl/full/state.go | 6 ++-- paychmgr/simple.go | 5 ++-- storage/adapter_storage_miner.go | 3 +- storage/miner.go | 2 +- storage/wdpost_run.go | 4 +-- 18 files changed, 79 insertions(+), 36 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index cf7f5b79b..ca032d81e 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -155,7 +155,7 @@ type FullNode interface { StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error) - StateWaitMsg(context.Context, cid.Cid) (*MsgLookup, error) + StateWaitMsg(context.Context, cid.Cid, uint64, uint64) (*MsgLookup, error) StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error) StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) StateListActors(context.Context, types.TipSetKey) ([]address.Address, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 5903f8ee0..ebd890f82 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -133,7 +133,7 @@ type FullNodeStruct struct { StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"` StateReadState func(context.Context, *types.Actor, types.TipSetKey) (*api.ActorState, error) `perm:"read"` StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateWaitMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"` + StateWaitMsg func(context.Context, cid.Cid, uint64, uint64) (*api.MsgLookup, error) `perm:"read"` StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"` StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` @@ -581,8 +581,8 @@ func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, tsk types.Ti return c.Internal.StatePledgeCollateral(ctx, tsk) } -func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) { - return c.Internal.StateWaitMsg(ctx, msgc) +func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64, timeout uint64) (*api.MsgLookup, error) { + return c.Internal.StateWaitMsg(ctx, msgc, confidence, timeout) } func (c *FullNodeStruct) StateSearchMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) { diff --git a/build/params_shared.go b/build/params_shared.go index 2b2f3e985..3411880de 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -59,6 +59,8 @@ var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) // Epochs const Finality = miner.ChainFinalityish +const MessageConfidence = 5 +const MessageTimeout = 72 // constants for Weight calculation // The ratio of weight contributed by short-term vs long-term factors in a given round diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index e291fe623..d783e6ea7 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -480,7 +480,10 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T return r, nil } -func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*types.TipSet, *types.MessageReceipt, error) { +// WaitForMessage blocks until a message appears on chain. It looks backwards in the chain to see if this has already +// happened. It guarantees that the message has been on chain for at least confidence epochs without being reverted +// before returning. +func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64, timeout uint64) (*types.TipSet, *types.MessageReceipt, error) { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -528,6 +531,11 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*type close(backSearchWait) }() + var candidateTs *types.TipSet + var candidateRcp *types.MessageReceipt + heightOfHead := head[0].Val.Height() + reverts := map[types.TipSetKey]bool{} + for { select { case notif, ok := <-tsub: @@ -537,21 +545,49 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*type for _, val := range notif { switch val.Type { case store.HCRevert: - continue + if val.Val.Equals(candidateTs) { + candidateTs = nil + candidateRcp = nil + } + if backSearchWait != nil { + reverts[val.Val.Key()] = true + } case store.HCApply: + if candidateTs != nil && val.Val.Height() >= candidateTs.Height() + abi.ChainEpoch(confidence) { + return candidateTs, candidateRcp, nil + } r, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage()) if err != nil { return nil, nil, err } if r != nil { - return val.Val, r, nil + if confidence == 0 { + return val.Val, r, err + } + candidateTs = val.Val + candidateRcp = r + } + heightOfHead = val.Val.Height() + + // check for timeout + if heightOfHead >= head[0].Val.Height() + abi.ChainEpoch(timeout) { + return nil, nil, nil } } } case <-backSearchWait: - if backTs != nil { - return backTs, backRcp, nil + // check if we found the message in the chain and that is hasn't been reverted since we started searching + if backTs != nil && !reverts[backTs.Key()] { + // if head is at or past confidence interval, return immediately + if heightOfHead >= backTs.Height() + abi.ChainEpoch(confidence) { + return backTs, backRcp, nil + } + + // wait for confidence interval + candidateTs = backTs + candidateRcp = backRcp } + reverts = nil backSearchWait = nil case <-ctx.Done(): return nil, nil, ctx.Err() diff --git a/cli/multisig.go b/cli/multisig.go index ff2ff2fce..43696736e 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -6,6 +6,7 @@ import ( "encoding/binary" "encoding/hex" "fmt" + "github.com/filecoin-project/lotus/build" "os" "sort" "strconv" @@ -117,7 +118,7 @@ var msigCreateCmd = &cli.Command{ } // wait for it to get mined into a block - wait, err := api.StateWaitMsg(ctx, msgCid) + wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence, build.MessageTimeout) if err != nil { return err } @@ -333,7 +334,7 @@ var msigProposeCmd = &cli.Command{ fmt.Println("send proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid) + wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence, build.MessageTimeout) if err != nil { return err } @@ -449,7 +450,7 @@ var msigApproveCmd = &cli.Command{ fmt.Println("sent approval in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid) + wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence, build.MessageTimeout) if err != nil { return err } diff --git a/cli/paych.go b/cli/paych.go index e150d6769..e2ea67fad 100644 --- a/cli/paych.go +++ b/cli/paych.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/base64" "fmt" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/builtin/paych" @@ -361,7 +362,7 @@ var paychVoucherSubmitCmd = &cli.Command{ return err } - mwait, err := api.StateWaitMsg(ctx, mcid) + mwait, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) if err != nil { return err } diff --git a/cli/state.go b/cli/state.go index 102c8d0bb..b8c319ef3 100644 --- a/cli/state.go +++ b/cli/state.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/filecoin-project/lotus/build" "reflect" "sort" "strconv" @@ -392,7 +393,7 @@ var stateReplaySetCmd = &cli.Command{ ts, err = types.NewTipSet(headers) } else { - r, err := api.StateWaitMsg(ctx, mcid) + r, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) if err != nil { return xerrors.Errorf("finding message in chain: %w", err) } @@ -1156,7 +1157,7 @@ var stateWaitMsgCmd = &cli.Command{ return err } - mw, err := api.StateWaitMsg(ctx, msg) + mw, err := api.StateWaitMsg(ctx, msg, build.MessageConfidence, build.MessageTimeout) if err != nil { return err } diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index b2275b9ca..e4c756d0b 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -334,7 +334,7 @@ func (h *handler) msgwait(w http.ResponseWriter, r *http.Request) { return } - mw, err := h.api.StateWaitMsg(r.Context(), c) + mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence, build.MessageTimeout) if err != nil { w.WriteHeader(400) w.Write([]byte(err.Error())) @@ -357,7 +357,7 @@ func (h *handler) msgwaitaddr(w http.ResponseWriter, r *http.Request) { return } - mw, err := h.api.StateWaitMsg(r.Context(), c) + mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence, build.MessageTimeout) if err != nil { w.WriteHeader(400) w.Write([]byte(err.Error())) diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go index 41de8c879..a00839d69 100644 --- a/cmd/lotus-shed/verifreg.go +++ b/cmd/lotus-shed/verifreg.go @@ -3,6 +3,7 @@ package main import ( "bytes" "fmt" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/go-address" "gopkg.in/urfave/cli.v2" @@ -85,7 +86,7 @@ var verifRegAddVerifierCmd = &cli.Command{ fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid()) - mwait, err := api.StateWaitMsg(ctx, smsg.Cid()) + mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, build.MessageTimeout) if err != nil { return err } @@ -161,7 +162,7 @@ var verifRegVerifyClientCmd = &cli.Command{ fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid()) - mwait, err := api.StateWaitMsg(ctx, smsg.Cid()) + mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, build.MessageTimeout) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index f834a09a5..a5e6f1c13 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -577,7 +577,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. } log.Info("Waiting for message: ", smsg.Cid()) - ret, err := api.StateWaitMsg(ctx, smsg.Cid()) + ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, build.MessageTimeout) if err != nil { return err } @@ -659,7 +659,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, log.Infof("Pushed StorageMarket.CreateStorageMiner, %s to Mpool", signed.Cid()) log.Infof("Waiting for confirmation") - mw, err := api.StateWaitMsg(ctx, signed.Cid()) + mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, build.MessageTimeout) if err != nil { return address.Undef, err } diff --git a/markets/retrievaladapter/client.go b/markets/retrievaladapter/client.go index dcd42d414..21ac3af6c 100644 --- a/markets/retrievaladapter/client.go +++ b/markets/retrievaladapter/client.go @@ -3,6 +3,7 @@ package retrievaladapter import ( "bytes" "context" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/retrievalmarket" @@ -72,7 +73,7 @@ func (rcn *retrievalClientNode) GetChainHead(ctx context.Context) (shared.TipSet // WaitForPaymentChannelAddFunds waits messageCID to appear on chain. If it doesn't appear within // defaultMsgWaitTimeout it returns error func (rcn *retrievalClientNode) WaitForPaymentChannelAddFunds(messageCID cid.Cid) error { - _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID) + _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID, build.MessageConfidence, build.MessageTimeout) if err != nil { return err @@ -84,7 +85,7 @@ func (rcn *retrievalClientNode) WaitForPaymentChannelAddFunds(messageCID cid.Cid } func (rcn *retrievalClientNode) WaitForPaymentChannelCreation(messageCID cid.Cid) (address.Address, error) { - _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID) + _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID, build.MessageConfidence, build.MessageTimeout) if err != nil { return address.Undef, err diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 754327076..64f3d6686 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -211,7 +211,7 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor } // TODO: timeout - _, ret, err := c.sm.WaitForMessage(ctx, *deal.PublishMessage) + _, ret, err := c.sm.WaitForMessage(ctx, *deal.PublishMessage, build.MessageConfidence, build.MessageTimeout) if err != nil { return 0, xerrors.Errorf("waiting for deal publish message: %w", err) } @@ -397,7 +397,7 @@ func (n *ClientNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetToke } func (n *ClientNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, err error) error) error { - receipt, err := n.StateWaitMsg(ctx, mcid) + receipt, err := n.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) if err != nil { return cb(0, nil, err) } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index ead0d99e6..67d3b9920 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -338,7 +338,7 @@ func (n *ProviderNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetTo } func (n *ProviderNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, err error) error) error { - receipt, err := n.StateWaitMsg(ctx, mcid) + receipt, err := n.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) if err != nil { return cb(0, nil, err) } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 546434d8c..da4f3e290 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -344,10 +344,8 @@ func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) return &out, nil } -func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) { - // TODO: consider using event system for this, expose confidence - - ts, recpt, err := a.StateManager.WaitForMessage(ctx, msg) +func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, timeout uint64) (*api.MsgLookup, error) { + ts, recpt, err := a.StateManager.WaitForMessage(ctx, msg, confidence, timeout) if err != nil { return nil, err } diff --git a/paychmgr/simple.go b/paychmgr/simple.go index ff537d425..d528a94aa 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -3,6 +3,7 @@ package paychmgr import ( "bytes" "context" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/specs-actors/actors/builtin" init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" @@ -55,7 +56,7 @@ func (pm *Manager) createPaych(ctx context.Context, from, to address.Address, am // (tricky because we need to setup channel tracking before we know its address) func (pm *Manager) waitForPaychCreateMsg(ctx context.Context, mcid cid.Cid) { defer pm.store.lk.Unlock() - mwait, err := pm.state.StateWaitMsg(ctx, mcid) + mwait, err := pm.state.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) if err != nil { log.Errorf("wait msg: %w", err) } @@ -105,7 +106,7 @@ func (pm *Manager) addFunds(ctx context.Context, ch address.Address, from addres // (tricky because we need to setup channel tracking before we know it's address) func (pm *Manager) waitForAddFundsMsg(ctx context.Context, mcid cid.Cid) { defer pm.store.lk.Unlock() - mwait, err := pm.state.StateWaitMsg(ctx, mcid) + mwait, err := pm.state.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) if err != nil { log.Error(err) } diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 391a38b37..76e89b748 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -3,6 +3,7 @@ package storage import ( "bytes" "context" + "github.com/filecoin-project/lotus/build" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -81,7 +82,7 @@ func (s SealingAPIAdapter) StateMinerDeadlines(ctx context.Context, maddr addres } func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (sealing.MsgLookup, error) { - wmsg, err := s.delegate.StateWaitMsg(ctx, mcid) + wmsg, err := s.delegate.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) if err != nil { return sealing.MsgLookup{}, err } diff --git a/storage/miner.go b/storage/miner.go index 779f981e9..c692db853 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -53,7 +53,7 @@ type storageMinerApi interface { StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) - StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually + StateWaitMsg(context.Context, cid.Cid, uint64, uint64) (*api.MsgLookup, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 63109e5f5..63cf809ad 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -167,7 +167,7 @@ func (s *WindowPoStScheduler) checkRecoveries(ctx context.Context, deadline uint log.Warnw("declare faults recovered Message CID", "cid", sm.Cid()) - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid()) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence, build.MessageTimeout) if err != nil { return xerrors.Errorf("declare faults recovered wait error: %w", err) } @@ -406,7 +406,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi log.Infof("Submitted window post: %s", sm.Cid()) go func() { - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid()) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence, build.MessageTimeout) if err != nil { log.Error(err) return From 57567db0174ef53c9c758c151a4415ddf702ef55 Mon Sep 17 00:00:00 2001 From: acruikshank Date: Wed, 3 Jun 2020 15:51:11 -0400 Subject: [PATCH 055/379] tidy --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index ed91f8560..dc0908832 100644 --- a/go.sum +++ b/go.sum @@ -156,8 +156,6 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1 github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= github.com/filecoin-project/go-fil-markets v0.2.7 h1:bgdK/e+xW15aVZLtdFLzAHdrx1hqtGF9veg2lstLK6o= github.com/filecoin-project/go-fil-markets v0.2.7/go.mod h1:LI3VFHse33aU0djAmFQ8+Hg39i0J8ibAoppGu6TbgkA= -github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200520183639-7c6ee2e066b4 h1:H8AVYu0MV9m3CSnKMxeILMfh8xJtnqVdXfBF/qbzgu0= -github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200520183639-7c6ee2e066b4/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= From 04f0130530baa6c2a237fc3397041f4fd3eda6d2 Mon Sep 17 00:00:00 2001 From: acruikshank Date: Wed, 3 Jun 2020 17:42:06 -0400 Subject: [PATCH 056/379] remove timeout --- api/api_full.go | 2 +- api/apistruct/struct.go | 6 +++--- build/params_shared.go | 1 - chain/stmgr/stmgr.go | 7 +------ cli/multisig.go | 6 +++--- cli/paych.go | 2 +- cli/state.go | 4 ++-- cmd/lotus-fountain/main.go | 4 ++-- cmd/lotus-shed/verifreg.go | 4 ++-- cmd/lotus-storage-miner/init.go | 4 ++-- markets/retrievaladapter/client.go | 4 ++-- markets/storageadapter/client.go | 4 ++-- markets/storageadapter/provider.go | 2 +- node/impl/full/state.go | 4 ++-- paychmgr/simple.go | 4 ++-- storage/adapter_storage_miner.go | 2 +- storage/miner.go | 2 +- storage/wdpost_run.go | 4 ++-- 18 files changed, 30 insertions(+), 36 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index ca032d81e..4b091caa1 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -155,7 +155,7 @@ type FullNode interface { StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error) - StateWaitMsg(context.Context, cid.Cid, uint64, uint64) (*MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error) StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error) StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) StateListActors(context.Context, types.TipSetKey) ([]address.Address, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index ebd890f82..93a5ca8cf 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -133,7 +133,7 @@ type FullNodeStruct struct { StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"` StateReadState func(context.Context, *types.Actor, types.TipSetKey) (*api.ActorState, error) `perm:"read"` StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateWaitMsg func(context.Context, cid.Cid, uint64, uint64) (*api.MsgLookup, error) `perm:"read"` + StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"` StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"` StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"` @@ -581,8 +581,8 @@ func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, tsk types.Ti return c.Internal.StatePledgeCollateral(ctx, tsk) } -func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64, timeout uint64) (*api.MsgLookup, error) { - return c.Internal.StateWaitMsg(ctx, msgc, confidence, timeout) +func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64) (*api.MsgLookup, error) { + return c.Internal.StateWaitMsg(ctx, msgc, confidence) } func (c *FullNodeStruct) StateSearchMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) { diff --git a/build/params_shared.go b/build/params_shared.go index 3411880de..97ca46986 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -60,7 +60,6 @@ var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) // Epochs const Finality = miner.ChainFinalityish const MessageConfidence = 5 -const MessageTimeout = 72 // constants for Weight calculation // The ratio of weight contributed by short-term vs long-term factors in a given round diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index d783e6ea7..b4f27bea2 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -483,7 +483,7 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T // WaitForMessage blocks until a message appears on chain. It looks backwards in the chain to see if this has already // happened. It guarantees that the message has been on chain for at least confidence epochs without being reverted // before returning. -func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64, timeout uint64) (*types.TipSet, *types.MessageReceipt, error) { +func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64) (*types.TipSet, *types.MessageReceipt, error) { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -568,11 +568,6 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid candidateRcp = r } heightOfHead = val.Val.Height() - - // check for timeout - if heightOfHead >= head[0].Val.Height() + abi.ChainEpoch(timeout) { - return nil, nil, nil - } } } case <-backSearchWait: diff --git a/cli/multisig.go b/cli/multisig.go index 43696736e..4d6d6603d 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -118,7 +118,7 @@ var msigCreateCmd = &cli.Command{ } // wait for it to get mined into a block - wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence, build.MessageTimeout) + wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence) if err != nil { return err } @@ -334,7 +334,7 @@ var msigProposeCmd = &cli.Command{ fmt.Println("send proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence, build.MessageTimeout) + wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence) if err != nil { return err } @@ -450,7 +450,7 @@ var msigApproveCmd = &cli.Command{ fmt.Println("sent approval in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence, build.MessageTimeout) + wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence) if err != nil { return err } diff --git a/cli/paych.go b/cli/paych.go index e2ea67fad..a1998fff1 100644 --- a/cli/paych.go +++ b/cli/paych.go @@ -362,7 +362,7 @@ var paychVoucherSubmitCmd = &cli.Command{ return err } - mwait, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) + mwait, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence) if err != nil { return err } diff --git a/cli/state.go b/cli/state.go index b8c319ef3..9b7021520 100644 --- a/cli/state.go +++ b/cli/state.go @@ -393,7 +393,7 @@ var stateReplaySetCmd = &cli.Command{ ts, err = types.NewTipSet(headers) } else { - r, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) + r, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence) if err != nil { return xerrors.Errorf("finding message in chain: %w", err) } @@ -1157,7 +1157,7 @@ var stateWaitMsgCmd = &cli.Command{ return err } - mw, err := api.StateWaitMsg(ctx, msg, build.MessageConfidence, build.MessageTimeout) + mw, err := api.StateWaitMsg(ctx, msg, build.MessageConfidence) if err != nil { return err } diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index e4c756d0b..593dc2e1d 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -334,7 +334,7 @@ func (h *handler) msgwait(w http.ResponseWriter, r *http.Request) { return } - mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence, build.MessageTimeout) + mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence) if err != nil { w.WriteHeader(400) w.Write([]byte(err.Error())) @@ -357,7 +357,7 @@ func (h *handler) msgwaitaddr(w http.ResponseWriter, r *http.Request) { return } - mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence, build.MessageTimeout) + mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence) if err != nil { w.WriteHeader(400) w.Write([]byte(err.Error())) diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go index a00839d69..e375abe73 100644 --- a/cmd/lotus-shed/verifreg.go +++ b/cmd/lotus-shed/verifreg.go @@ -86,7 +86,7 @@ var verifRegAddVerifierCmd = &cli.Command{ fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid()) - mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, build.MessageTimeout) + mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) if err != nil { return err } @@ -162,7 +162,7 @@ var verifRegVerifyClientCmd = &cli.Command{ fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid()) - mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, build.MessageTimeout) + mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index a5e6f1c13..fe3c1e0dc 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -577,7 +577,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. } log.Info("Waiting for message: ", smsg.Cid()) - ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, build.MessageTimeout) + ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) if err != nil { return err } @@ -659,7 +659,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, log.Infof("Pushed StorageMarket.CreateStorageMiner, %s to Mpool", signed.Cid()) log.Infof("Waiting for confirmation") - mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, build.MessageTimeout) + mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) if err != nil { return address.Undef, err } diff --git a/markets/retrievaladapter/client.go b/markets/retrievaladapter/client.go index 21ac3af6c..0c1992236 100644 --- a/markets/retrievaladapter/client.go +++ b/markets/retrievaladapter/client.go @@ -73,7 +73,7 @@ func (rcn *retrievalClientNode) GetChainHead(ctx context.Context) (shared.TipSet // WaitForPaymentChannelAddFunds waits messageCID to appear on chain. If it doesn't appear within // defaultMsgWaitTimeout it returns error func (rcn *retrievalClientNode) WaitForPaymentChannelAddFunds(messageCID cid.Cid) error { - _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID, build.MessageConfidence, build.MessageTimeout) + _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID, build.MessageConfidence) if err != nil { return err @@ -85,7 +85,7 @@ func (rcn *retrievalClientNode) WaitForPaymentChannelAddFunds(messageCID cid.Cid } func (rcn *retrievalClientNode) WaitForPaymentChannelCreation(messageCID cid.Cid) (address.Address, error) { - _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID, build.MessageConfidence, build.MessageTimeout) + _, mr, err := rcn.chainapi.StateManager.WaitForMessage(context.TODO(), messageCID, build.MessageConfidence) if err != nil { return address.Undef, err diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 64f3d6686..a0c7899e6 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -211,7 +211,7 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor } // TODO: timeout - _, ret, err := c.sm.WaitForMessage(ctx, *deal.PublishMessage, build.MessageConfidence, build.MessageTimeout) + _, ret, err := c.sm.WaitForMessage(ctx, *deal.PublishMessage, build.MessageConfidence) if err != nil { return 0, xerrors.Errorf("waiting for deal publish message: %w", err) } @@ -397,7 +397,7 @@ func (n *ClientNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetToke } func (n *ClientNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, err error) error) error { - receipt, err := n.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) + receipt, err := n.StateWaitMsg(ctx, mcid, build.MessageConfidence) if err != nil { return cb(0, nil, err) } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index 67d3b9920..560fbf202 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -338,7 +338,7 @@ func (n *ProviderNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetTo } func (n *ProviderNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, err error) error) error { - receipt, err := n.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) + receipt, err := n.StateWaitMsg(ctx, mcid, build.MessageConfidence) if err != nil { return cb(0, nil, err) } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index da4f3e290..da8f90234 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -344,8 +344,8 @@ func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) return &out, nil } -func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, timeout uint64) (*api.MsgLookup, error) { - ts, recpt, err := a.StateManager.WaitForMessage(ctx, msg, confidence, timeout) +func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { + ts, recpt, err := a.StateManager.WaitForMessage(ctx, msg, confidence) if err != nil { return nil, err } diff --git a/paychmgr/simple.go b/paychmgr/simple.go index d528a94aa..209217c0c 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -56,7 +56,7 @@ func (pm *Manager) createPaych(ctx context.Context, from, to address.Address, am // (tricky because we need to setup channel tracking before we know its address) func (pm *Manager) waitForPaychCreateMsg(ctx context.Context, mcid cid.Cid) { defer pm.store.lk.Unlock() - mwait, err := pm.state.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) + mwait, err := pm.state.StateWaitMsg(ctx, mcid, build.MessageConfidence) if err != nil { log.Errorf("wait msg: %w", err) } @@ -106,7 +106,7 @@ func (pm *Manager) addFunds(ctx context.Context, ch address.Address, from addres // (tricky because we need to setup channel tracking before we know it's address) func (pm *Manager) waitForAddFundsMsg(ctx context.Context, mcid cid.Cid) { defer pm.store.lk.Unlock() - mwait, err := pm.state.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) + mwait, err := pm.state.StateWaitMsg(ctx, mcid, build.MessageConfidence) if err != nil { log.Error(err) } diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 76e89b748..8d9bf7774 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -82,7 +82,7 @@ func (s SealingAPIAdapter) StateMinerDeadlines(ctx context.Context, maddr addres } func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (sealing.MsgLookup, error) { - wmsg, err := s.delegate.StateWaitMsg(ctx, mcid, build.MessageConfidence, build.MessageTimeout) + wmsg, err := s.delegate.StateWaitMsg(ctx, mcid, build.MessageConfidence) if err != nil { return sealing.MsgLookup{}, err } diff --git a/storage/miner.go b/storage/miner.go index c692db853..961e1ab8f 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -53,7 +53,7 @@ type storageMinerApi interface { StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) - StateWaitMsg(context.Context, cid.Cid, uint64, uint64) (*api.MsgLookup, error) // TODO: removeme eventually + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 63cf809ad..b7004ea9f 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -167,7 +167,7 @@ func (s *WindowPoStScheduler) checkRecoveries(ctx context.Context, deadline uint log.Warnw("declare faults recovered Message CID", "cid", sm.Cid()) - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence, build.MessageTimeout) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence) if err != nil { return xerrors.Errorf("declare faults recovered wait error: %w", err) } @@ -406,7 +406,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi log.Infof("Submitted window post: %s", sm.Cid()) go func() { - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence, build.MessageTimeout) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence) if err != nil { log.Error(err) return From 29dbc26dbd948a40611541a3868c360d9baa6459 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 2 Jun 2020 20:12:53 +0200 Subject: [PATCH 057/379] Update cli Signed-off-by: Jakub Sztandera --- cli/auth.go | 2 +- cli/chain.go | 2 +- cli/client.go | 2 +- cli/cmd.go | 2 +- cli/log.go | 2 +- cli/mpool.go | 2 +- cli/multisig.go | 2 +- cli/net.go | 2 +- cli/params.go | 2 +- cli/paych.go | 2 +- cli/send.go | 2 +- cli/state.go | 2 +- cli/sync.go | 2 +- cli/version.go | 2 +- cli/wait.go | 2 +- cli/wallet.go | 2 +- cmd/chain-noise/main.go | 2 +- cmd/lotus-bench/import.go | 2 +- cmd/lotus-bench/main.go | 2 +- cmd/lotus-chainwatch/dot.go | 2 +- cmd/lotus-chainwatch/main.go | 2 +- cmd/lotus-fountain/main.go | 2 +- cmd/lotus-health/main.go | 2 +- cmd/lotus-seal-worker/main.go | 2 +- cmd/lotus-seed/genesis.go | 2 +- cmd/lotus-seed/main.go | 2 +- cmd/lotus-shed/base16.go | 2 +- cmd/lotus-shed/base32.go | 2 +- cmd/lotus-shed/bigint.go | 2 +- cmd/lotus-shed/bitfield.go | 2 +- cmd/lotus-shed/commp.go | 2 +- cmd/lotus-shed/import-car.go | 2 +- cmd/lotus-shed/keyinfo.go | 2 +- cmd/lotus-shed/main.go | 2 +- cmd/lotus-shed/nonce-fix.go | 2 +- cmd/lotus-shed/params.go | 2 +- cmd/lotus-shed/peerkey.go | 2 +- cmd/lotus-shed/proofs.go | 2 +- cmd/lotus-shed/stateroot-stats.go | 2 +- cmd/lotus-shed/verifreg.go | 2 +- cmd/lotus-storage-miner/info.go | 2 +- cmd/lotus-storage-miner/init.go | 2 +- cmd/lotus-storage-miner/main.go | 10 +++++----- cmd/lotus-storage-miner/market.go | 2 +- cmd/lotus-storage-miner/proving.go | 2 +- cmd/lotus-storage-miner/rewards.go | 2 +- cmd/lotus-storage-miner/run.go | 2 +- cmd/lotus-storage-miner/sectors.go | 2 +- cmd/lotus-storage-miner/storage.go | 2 +- cmd/lotus-storage-miner/workers.go | 2 +- cmd/lotus/daemon.go | 2 +- cmd/lotus/daemon_nodaemon.go | 2 +- cmd/lotus/debug_advance.go | 2 +- cmd/lotus/main.go | 10 +++++----- go.mod | 2 +- go.sum | 2 -- lotuspond/main.go | 2 +- 57 files changed, 64 insertions(+), 66 deletions(-) diff --git a/cli/auth.go b/cli/auth.go index a40e0a328..e3497f17c 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -4,7 +4,7 @@ import ( "fmt" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc/auth" diff --git a/cli/chain.go b/cli/chain.go index 9e245c875..4d296cf78 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -25,7 +25,7 @@ import ( cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" diff --git a/cli/client.go b/cli/client.go index 3bfc5de70..ea6241b9b 100644 --- a/cli/client.go +++ b/cli/client.go @@ -10,7 +10,7 @@ import ( "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/storagemarket" diff --git a/cli/cmd.go b/cli/cmd.go index fd0ab1e78..3953f1372 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -14,7 +14,7 @@ import ( "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc" diff --git a/cli/log.go b/cli/log.go index 561d949d5..3e1027ccf 100644 --- a/cli/log.go +++ b/cli/log.go @@ -4,7 +4,7 @@ import ( "fmt" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var logCmd = &cli.Command{ diff --git a/cli/mpool.go b/cli/mpool.go index 0c5102d01..1b8a1e0d1 100644 --- a/cli/mpool.go +++ b/cli/mpool.go @@ -6,7 +6,7 @@ import ( "sort" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" diff --git a/cli/multisig.go b/cli/multisig.go index 37106dff5..19d1aa420 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -19,7 +19,7 @@ import ( cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" diff --git a/cli/net.go b/cli/net.go index b49d9604f..96185ad07 100644 --- a/cli/net.go +++ b/cli/net.go @@ -7,7 +7,7 @@ import ( "github.com/libp2p/go-libp2p-core/peer" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/lib/addrutil" ) diff --git a/cli/params.go b/cli/params.go index f6acbaad7..e1ad3e5d9 100644 --- a/cli/params.go +++ b/cli/params.go @@ -4,7 +4,7 @@ import ( "github.com/docker/go-units" paramfetch "github.com/filecoin-project/go-paramfetch" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/build" ) diff --git a/cli/paych.go b/cli/paych.go index 5fe5fac0c..597f80837 100644 --- a/cli/paych.go +++ b/cli/paych.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" types "github.com/filecoin-project/lotus/chain/types" ) diff --git a/cli/send.go b/cli/send.go index f43e90c36..9f9c70dde 100644 --- a/cli/send.go +++ b/cli/send.go @@ -5,7 +5,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/types" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var sendCmd = &cli.Command{ diff --git a/cli/state.go b/cli/state.go index 102c8d0bb..9e97037ad 100644 --- a/cli/state.go +++ b/cli/state.go @@ -17,7 +17,7 @@ import ( "github.com/multiformats/go-multihash" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cli/sync.go b/cli/sync.go index 891f61da3..2a062cbcd 100644 --- a/cli/sync.go +++ b/cli/sync.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" cid "github.com/ipfs/go-cid" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" diff --git a/cli/version.go b/cli/version.go index 50bc0d259..d257f5ba9 100644 --- a/cli/version.go +++ b/cli/version.go @@ -3,7 +3,7 @@ package cli import ( "fmt" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var versionCmd = &cli.Command{ diff --git a/cli/wait.go b/cli/wait.go index ce4c4dccb..ca8cdce3f 100644 --- a/cli/wait.go +++ b/cli/wait.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var waitApiCmd = &cli.Command{ diff --git a/cli/wallet.go b/cli/wallet.go index 688a2829f..a731c1b2c 100644 --- a/cli/wallet.go +++ b/cli/wallet.go @@ -15,7 +15,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/crypto" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var walletCmd = &cli.Command{ diff --git a/cmd/chain-noise/main.go b/cmd/chain-noise/main.go index e152ccf75..a1e92ee96 100644 --- a/cmd/chain-noise/main.go +++ b/cmd/chain-noise/main.go @@ -14,7 +14,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) func main() { diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f33cc1d9d..11d58d9b8 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -24,7 +24,7 @@ import ( "github.com/ipfs/go-datastore" badger "github.com/ipfs/go-ds-badger2" blockstore "github.com/ipfs/go-ipfs-blockstore" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) type TipSetExec struct { diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 4ac52b497..5e34c36b0 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -16,7 +16,7 @@ import ( "github.com/minio/blake2b-simd" "github.com/mitchellh/go-homedir" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" paramfetch "github.com/filecoin-project/go-paramfetch" diff --git a/cmd/lotus-chainwatch/dot.go b/cmd/lotus-chainwatch/dot.go index 22c8b7f05..87dab62ad 100644 --- a/cmd/lotus-chainwatch/dot.go +++ b/cmd/lotus-chainwatch/dot.go @@ -6,7 +6,7 @@ import ( "strconv" "github.com/ipfs/go-cid" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var dotCmd = &cli.Command{ diff --git a/cmd/lotus-chainwatch/main.go b/cmd/lotus-chainwatch/main.go index faedb3bea..b5ca379e0 100644 --- a/cmd/lotus-chainwatch/main.go +++ b/cmd/lotus-chainwatch/main.go @@ -8,7 +8,7 @@ import ( logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index d4e41895b..050b64c87 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -15,7 +15,7 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p-core/peer" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index 264b3b84e..9860b5b7c 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -10,7 +10,7 @@ import ( cid "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc" diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index e9721e9dd..5ca1483c1 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -13,7 +13,7 @@ import ( "github.com/gorilla/mux" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index 3dc6e15d2..471fb99df 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -7,7 +7,7 @@ import ( "github.com/google/uuid" "github.com/mitchellh/go-homedir" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi/big" diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index 47dd850c0..1e4f8fe0d 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -12,7 +12,7 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/mitchellh/go-homedir" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus-shed/base16.go b/cmd/lotus-shed/base16.go index e1b5a6502..adfdfeddb 100644 --- a/cmd/lotus-shed/base16.go +++ b/cmd/lotus-shed/base16.go @@ -8,7 +8,7 @@ import ( "os" "strings" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var base16Cmd = &cli.Command{ diff --git a/cmd/lotus-shed/base32.go b/cmd/lotus-shed/base32.go index ff7fab858..cd30a2146 100644 --- a/cmd/lotus-shed/base32.go +++ b/cmd/lotus-shed/base32.go @@ -7,7 +7,7 @@ import ( "os" "strings" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/multiformats/go-base32" ) diff --git a/cmd/lotus-shed/bigint.go b/cmd/lotus-shed/bigint.go index 3db0de68d..e087a341a 100644 --- a/cmd/lotus-shed/bigint.go +++ b/cmd/lotus-shed/bigint.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/filecoin-project/lotus/chain/types" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var bigIntParseCmd = &cli.Command{ diff --git a/cmd/lotus-shed/bitfield.go b/cmd/lotus-shed/bitfield.go index 96116b3b3..0cf9e4ea0 100644 --- a/cmd/lotus-shed/bitfield.go +++ b/cmd/lotus-shed/bitfield.go @@ -8,7 +8,7 @@ import ( "os" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-bitfield" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" diff --git a/cmd/lotus-shed/commp.go b/cmd/lotus-shed/commp.go index acc1e73e6..9b0cab75d 100644 --- a/cmd/lotus-shed/commp.go +++ b/cmd/lotus-shed/commp.go @@ -5,7 +5,7 @@ import ( "fmt" commcid "github.com/filecoin-project/go-fil-commcid" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var commpToCidCmd = &cli.Command{ diff --git a/cmd/lotus-shed/import-car.go b/cmd/lotus-shed/import-car.go index 970341a3a..091ab9054 100644 --- a/cmd/lotus-shed/import-car.go +++ b/cmd/lotus-shed/import-car.go @@ -8,7 +8,7 @@ import ( blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/ipld/go-car" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/node/repo" ) diff --git a/cmd/lotus-shed/keyinfo.go b/cmd/lotus-shed/keyinfo.go index f1a42894a..42ab91601 100644 --- a/cmd/lotus-shed/keyinfo.go +++ b/cmd/lotus-shed/keyinfo.go @@ -9,7 +9,7 @@ import ( "strings" "text/template" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index e7264c92c..09cffac5d 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -4,7 +4,7 @@ import ( "os" logging "github.com/ipfs/go-log/v2" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/build" ) diff --git a/cmd/lotus-shed/nonce-fix.go b/cmd/lotus-shed/nonce-fix.go index aaecdcf58..4fb30300a 100644 --- a/cmd/lotus-shed/nonce-fix.go +++ b/cmd/lotus-shed/nonce-fix.go @@ -5,7 +5,7 @@ import ( "math" "github.com/filecoin-project/go-address" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" diff --git a/cmd/lotus-shed/params.go b/cmd/lotus-shed/params.go index 210711b91..a81110b12 100644 --- a/cmd/lotus-shed/params.go +++ b/cmd/lotus-shed/params.go @@ -4,7 +4,7 @@ import ( "github.com/docker/go-units" paramfetch "github.com/filecoin-project/go-paramfetch" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/build" ) diff --git a/cmd/lotus-shed/peerkey.go b/cmd/lotus-shed/peerkey.go index 65220209d..6d9ee99b6 100644 --- a/cmd/lotus-shed/peerkey.go +++ b/cmd/lotus-shed/peerkey.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/modules/lp2p" diff --git a/cmd/lotus-shed/proofs.go b/cmd/lotus-shed/proofs.go index 9f86d9fa7..3a4615658 100644 --- a/cmd/lotus-shed/proofs.go +++ b/cmd/lotus-shed/proofs.go @@ -4,7 +4,7 @@ import ( "encoding/hex" "fmt" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ffi "github.com/filecoin-project/filecoin-ffi" "github.com/filecoin-project/go-address" diff --git a/cmd/lotus-shed/stateroot-stats.go b/cmd/lotus-shed/stateroot-stats.go index 89bd0bb47..0546e5315 100644 --- a/cmd/lotus-shed/stateroot-stats.go +++ b/cmd/lotus-shed/stateroot-stats.go @@ -3,7 +3,7 @@ package main import ( "fmt" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/ipfs/go-cid" diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go index 41de8c879..44adc7297 100644 --- a/cmd/lotus-shed/verifreg.go +++ b/cmd/lotus-shed/verifreg.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/filecoin-project/go-address" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 0257be850..264128cee 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -8,7 +8,7 @@ import ( "github.com/fatih/color" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/specs-actors/actors/builtin/miner" sealing "github.com/filecoin-project/storage-fsm" diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index f1677801b..e63e983b9 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -19,7 +19,7 @@ import ( "github.com/libp2p/go-libp2p-core/peer" "github.com/mitchellh/go-homedir" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index e3e908fd1..10ffb85ad 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -4,8 +4,8 @@ import ( "os" logging "github.com/ipfs/go-log/v2" + "github.com/urfave/cli/v2" "go.opencensus.io/trace" - "gopkg.in/urfave/cli.v2" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" @@ -55,10 +55,10 @@ func main() { } app := &cli.App{ - Name: "lotus-storage-miner", - Usage: "Filecoin decentralized storage network storage miner", - Version: build.UserVersion(), - EnableShellCompletion: true, + Name: "lotus-storage-miner", + Usage: "Filecoin decentralized storage network storage miner", + Version: build.UserVersion(), + EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index b918937db..68b626360 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "github.com/ipfs/go-cid" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) var setPriceCmd = &cli.Command{ diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 7cfa010b9..9f9ca600a 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -10,8 +10,8 @@ import ( lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/urfave/cli/v2" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" ) var provingCmd = &cli.Command{ diff --git a/cmd/lotus-storage-miner/rewards.go b/cmd/lotus-storage-miner/rewards.go index 68b7ab9d9..4152880ae 100644 --- a/cmd/lotus-storage-miner/rewards.go +++ b/cmd/lotus-storage-miner/rewards.go @@ -3,7 +3,7 @@ package main import ( "fmt" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 467033f9c..f3c7fa8ef 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -12,7 +12,7 @@ import ( "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index d923089ec..1a500cc8b 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -9,7 +9,7 @@ import ( "time" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus-storage-miner/storage.go b/cmd/lotus-storage-miner/storage.go index 40205531a..a8ceda6c2 100644 --- a/cmd/lotus-storage-miner/storage.go +++ b/cmd/lotus-storage-miner/storage.go @@ -15,7 +15,7 @@ import ( "github.com/google/uuid" "github.com/mitchellh/go-homedir" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus-storage-miner/workers.go b/cmd/lotus-storage-miner/workers.go index 8114b74e6..009d2fb90 100644 --- a/cmd/lotus-storage-miner/workers.go +++ b/cmd/lotus-storage-miner/workers.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/fatih/color" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/sector-storage/storiface" diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 5aa3fe33d..4d75bdd84 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -22,7 +22,7 @@ import ( "go.opencensus.io/stats/view" "go.opencensus.io/tag" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" diff --git a/cmd/lotus/daemon_nodaemon.go b/cmd/lotus/daemon_nodaemon.go index 05a8f97da..a11d92c6c 100644 --- a/cmd/lotus/daemon_nodaemon.go +++ b/cmd/lotus/daemon_nodaemon.go @@ -5,7 +5,7 @@ package main import ( "errors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) // DaemonCmd is the `go-lotus daemon` command diff --git a/cmd/lotus/debug_advance.go b/cmd/lotus/debug_advance.go index 990bbe95d..ae4064982 100644 --- a/cmd/lotus/debug_advance.go +++ b/cmd/lotus/debug_advance.go @@ -13,7 +13,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/crypto" "golang.org/x/xerrors" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" ) func init() { diff --git a/cmd/lotus/main.go b/cmd/lotus/main.go index 4bc13d6fe..5376ce02a 100644 --- a/cmd/lotus/main.go +++ b/cmd/lotus/main.go @@ -4,8 +4,8 @@ import ( "context" "os" + "github.com/urfave/cli/v2" "go.opencensus.io/trace" - "gopkg.in/urfave/cli.v2" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" @@ -50,10 +50,10 @@ func main() { defer span.End() app := &cli.App{ - Name: "lotus", - Usage: "Filecoin decentralized storage network client", - Version: build.UserVersion(), - EnableShellCompletion: true, + Name: "lotus", + Usage: "Filecoin decentralized storage network client", + Version: build.UserVersion(), + EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", diff --git a/go.mod b/go.mod index 56309be9e..ba737b67b 100644 --- a/go.mod +++ b/go.mod @@ -104,6 +104,7 @@ require ( github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 + github.com/urfave/cli/v2 v2.2.0 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 @@ -117,7 +118,6 @@ require ( golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 - gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect ) diff --git a/go.sum b/go.sum index cb372e94d..c234fadc3 100644 --- a/go.sum +++ b/go.sum @@ -1456,8 +1456,6 @@ gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVY gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 h1:Ggy3mWN4l3PUFPfSG0YB3n5fVYggzysUmiUQ89SnX6Y= -gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/lotuspond/main.go b/lotuspond/main.go index 8551a25dc..fee36d86a 100644 --- a/lotuspond/main.go +++ b/lotuspond/main.go @@ -8,7 +8,7 @@ import ( "path" "strconv" - "gopkg.in/urfave/cli.v2" + "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc" ) From cd817906b200583a12da09fc5a3709db82433ef6 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 3 Jun 2020 18:30:43 -0700 Subject: [PATCH 058/379] handle sourcing randomness from a future block --- chain/store/store.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chain/store/store.go b/chain/store/store.go index c9dac2e31..72c77ee36 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -914,6 +914,10 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers cr return nil, err } + if round > ts.Height() { + return DrawRandomness(ts.MinTicket().VRFProof, pers, round, entropy) + } + searchHeight := round if searchHeight < 0 { searchHeight = 0 From 5f95a92135a4557de791d8a07b83f438d8d9dbab Mon Sep 17 00:00:00 2001 From: acruikshank Date: Wed, 3 Jun 2020 22:18:38 -0400 Subject: [PATCH 059/379] fix race (sort of) by increasing confidence --- markets/storageadapter/client.go | 2 +- markets/storageadapter/provider.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index a0c7899e6..3f13978c2 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -321,7 +321,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider } } - if err := c.ev.Called(checkFunc, called, revert, 3, build.SealRandomnessLookbackLimit, matchEvent); err != nil { + if err := c.ev.Called(checkFunc, called, revert, build.MessageConfidence + 1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { return xerrors.Errorf("failed to set up called handler: %w", err) } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index 560fbf202..7c7310cd9 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -321,7 +321,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide } - if err := n.ev.Called(checkFunc, called, revert, 3, build.SealRandomnessLookbackLimit, matchEvent); err != nil { + if err := n.ev.Called(checkFunc, called, revert, build.MessageConfidence + 1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { return xerrors.Errorf("failed to set up called handler: %w", err) } From ce330746269f7fb39f88c087c87f22caaec9e1a7 Mon Sep 17 00:00:00 2001 From: acruikshank Date: Wed, 3 Jun 2020 22:30:09 -0400 Subject: [PATCH 060/379] go fmt --- chain/stmgr/stmgr.go | 4 ++-- markets/storageadapter/client.go | 2 +- markets/storageadapter/provider.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index b4f27bea2..e016bcce9 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -553,7 +553,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid reverts[val.Val.Key()] = true } case store.HCApply: - if candidateTs != nil && val.Val.Height() >= candidateTs.Height() + abi.ChainEpoch(confidence) { + if candidateTs != nil && val.Val.Height() >= candidateTs.Height()+abi.ChainEpoch(confidence) { return candidateTs, candidateRcp, nil } r, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage()) @@ -574,7 +574,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid // check if we found the message in the chain and that is hasn't been reverted since we started searching if backTs != nil && !reverts[backTs.Key()] { // if head is at or past confidence interval, return immediately - if heightOfHead >= backTs.Height() + abi.ChainEpoch(confidence) { + if heightOfHead >= backTs.Height()+abi.ChainEpoch(confidence) { return backTs, backRcp, nil } diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 3f13978c2..d9deaedf2 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -321,7 +321,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider } } - if err := c.ev.Called(checkFunc, called, revert, build.MessageConfidence + 1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { + if err := c.ev.Called(checkFunc, called, revert, build.MessageConfidence+1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { return xerrors.Errorf("failed to set up called handler: %w", err) } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index 7c7310cd9..ddbc826eb 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -321,7 +321,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide } - if err := n.ev.Called(checkFunc, called, revert, build.MessageConfidence + 1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { + if err := n.ev.Called(checkFunc, called, revert, build.MessageConfidence+1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { return xerrors.Errorf("failed to set up called handler: %w", err) } From ea111b058e3dbcc4adacd9426f24b952ea9586c4 Mon Sep 17 00:00:00 2001 From: acruikshank Date: Wed, 3 Jun 2020 22:34:57 -0400 Subject: [PATCH 061/379] imports --- cli/multisig.go | 2 +- cli/state.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/multisig.go b/cli/multisig.go index 4d6d6603d..5672c40a6 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -6,7 +6,6 @@ import ( "encoding/binary" "encoding/hex" "fmt" - "github.com/filecoin-project/lotus/build" "os" "sort" "strconv" @@ -24,6 +23,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" + "github.com/filecoin-project/lotus/build" types "github.com/filecoin-project/lotus/chain/types" ) diff --git a/cli/state.go b/cli/state.go index 9b7021520..e69a6d750 100644 --- a/cli/state.go +++ b/cli/state.go @@ -5,7 +5,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/filecoin-project/lotus/build" "reflect" "sort" "strconv" @@ -36,6 +35,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/miner" ) From c0cdcbb9e0b51b16a0db5832c36df9ba713d54df Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 4 Jun 2020 08:09:01 -0400 Subject: [PATCH 062/379] Adjust service logging and startup settings --- Makefile | 3 ++- scripts/chainwatch.service | 5 ++++- scripts/lotus-daemon.service | 6 +++--- scripts/lotus-miner.service | 3 ++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index fdf9e7e09..5db557d7e 100644 --- a/Makefile +++ b/Makefile @@ -105,11 +105,12 @@ install: install-services: install mkdir -p /usr/local/lib/systemd/system + mkdir -p /var/log/lotus install -C -m 0644 ./scripts/lotus-daemon.service /usr/local/lib/systemd/system/lotus-daemon.service install -C -m 0644 ./scripts/lotus-miner.service /usr/local/lib/systemd/system/lotus-miner.service systemctl daemon-reload @echo - @echo "lotus and lotus-miner services installed. Don't forget to 'systemctl enable lotus|lotus-miner' for it to be enabled on startup." + @echo "lotus-daemon and lotus-miner services installed. Don't forget to 'systemctl enable lotus-daemon|lotus-miner' for it to be enabled on startup." clean-services: rm -f /usr/local/lib/systemd/system/lotus-daemon.service diff --git a/scripts/chainwatch.service b/scripts/chainwatch.service index 47af6b59e..e958ec857 100644 --- a/scripts/chainwatch.service +++ b/scripts/chainwatch.service @@ -1,12 +1,15 @@ [Unit] Description=Chainwatch +PartOf=sentinel.service After=lotus-daemon.service Requires=lotus-daemon.service [Service] -ExecStart=/usr/local/bin/chainwatch run +Environment=GOLOG_FILE="/var/log/lotus/chainwatch.log" +Environment=GOLOG_LOG_FMT="json" Environment=LOTUS_DB="postgres://postgres:password@localhost:5432/postgres?sslmode=disable" Environment=LOTUS_PATH="/root/.lotus" +ExecStart=/usr/local/bin/chainwatch run [Install] WantedBy=multiuser.target diff --git a/scripts/lotus-daemon.service b/scripts/lotus-daemon.service index 46bc47bdb..99a94e217 100644 --- a/scripts/lotus-daemon.service +++ b/scripts/lotus-daemon.service @@ -1,15 +1,15 @@ [Unit] Description=Lotus Daemon After=network-online.target -Wants=network-online.target +Requires=network-online.target [Service] -Environment=GOLOG_FILE="/var/log/lotus-daemon" +Environment=GOLOG_FILE="/var/log/lotus/daemon.log" Environment=GOLOG_LOG_FMT="json" ExecStart=/usr/local/bin/lotus daemon #ExecStop=/bin/sh -a -c /root/capture_lotus_heap.sh Restart=always -RestartSec=30 +RestartSec=10 MemoryAccounting=true MemoryHigh=8G diff --git a/scripts/lotus-miner.service b/scripts/lotus-miner.service index 7b866e043..3a460450f 100644 --- a/scripts/lotus-miner.service +++ b/scripts/lotus-miner.service @@ -2,10 +2,11 @@ Description=Lotus Storage Miner After=network.target After=lotus-daemon.service +Requires=lotus-daemon.service [Service] ExecStart=/usr/local/bin/lotus-storage-miner run -Environment=GOLOG_FILE="/var/log/lotus-miner" +Environment=GOLOG_FILE="/var/log/lotus/miner.log" Environment=GOLOG_LOG_FMT="json" [Install] From ce30162907c8d774a6b8e711bfccfa2e26b02651 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 4 Jun 2020 08:10:08 -0400 Subject: [PATCH 063/379] Fix documentation link for new systemd page --- documentation/en/.library.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/en/.library.json b/documentation/en/.library.json index 018e6189b..293c871ea 100644 --- a/documentation/en/.library.json +++ b/documentation/en/.library.json @@ -58,8 +58,8 @@ }, { "title": "Use Lotus with systemd", - "slug": "en+install-system-services", - "github": "en/install-system-services.md", + "slug": "en+install-systemd-services", + "github": "en/install-systemd-services.md", "value": null }, { From da960a9de4a968211bb48f27a4bf4dda4190451d Mon Sep 17 00:00:00 2001 From: acruikshank Date: Thu, 4 Jun 2020 09:54:37 -0400 Subject: [PATCH 064/379] more import rearrangement --- markets/retrievaladapter/client.go | 2 +- paychmgr/simple.go | 2 +- storage/adapter_storage_miner.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/markets/retrievaladapter/client.go b/markets/retrievaladapter/client.go index 0c1992236..709254d49 100644 --- a/markets/retrievaladapter/client.go +++ b/markets/retrievaladapter/client.go @@ -3,7 +3,6 @@ package retrievaladapter import ( "bytes" "context" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/retrievalmarket" @@ -15,6 +14,7 @@ import ( "github.com/ipfs/go-cid" "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/node/impl/full" payapi "github.com/filecoin-project/lotus/node/impl/paych" "github.com/filecoin-project/lotus/paychmgr" diff --git a/paychmgr/simple.go b/paychmgr/simple.go index 209217c0c..191a4c474 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -3,7 +3,6 @@ package paychmgr import ( "bytes" "context" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/specs-actors/actors/builtin" init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" @@ -13,6 +12,7 @@ import ( "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 8d9bf7774..809d13d3d 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -3,7 +3,6 @@ package storage import ( "bytes" "context" - "github.com/filecoin-project/lotus/build" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -19,6 +18,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api/apibstore" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" From c625b307818752dc3d287f0f61e50a3e8ccae6df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Jun 2020 15:54:36 +0200 Subject: [PATCH 065/379] Update fsm adapter --- node/impl/storminer.go | 2 +- storage/adapter_storage_miner.go | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/node/impl/storminer.go b/node/impl/storminer.go index cca706746..e48c9fcad 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -120,7 +120,7 @@ func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid abi.SectorNumb Value: info.SeedValue, Epoch: info.SeedEpoch, }, - Retries: info.Nonce, + Retries: info.InvalidProofs, LastErr: info.LastErr, Log: log, diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 09197e71a..314fe7faf 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -163,9 +163,13 @@ func (s SealingAPIAdapter) StateSectorPreCommitInfo(ctx context.Context, maddr a } var pci miner.SectorPreCommitOnChainInfo - if _, err := precommits.Get(adt.UIntKey(uint64(sectorNumber)), &pci); err != nil { + ok, err := precommits.Get(adt.UIntKey(uint64(sectorNumber)), &pci) + if err != nil { return nil, err } + if !ok { + return nil, nil + } return &pci, nil } From fa3b1552cf67cfea96962ddc312828dba8a82309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Jun 2020 15:54:54 +0200 Subject: [PATCH 066/379] Update sector-storage intefraces --- api/api_worker.go | 2 ++ api/apistruct/struct.go | 10 ++++++++++ cmd/lotus-seal-worker/main.go | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/api/api_worker.go b/api/api_worker.go index 182b2fe6a..a130824ab 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -25,6 +25,8 @@ type WorkerAPI interface { storage.Sealer + MoveStorage(ctx context.Context, sector abi.SectorID) error + UnsealPiece(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error ReadPiece(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 1f2191ae8..1cbf44bd4 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -213,6 +213,7 @@ type StorageMinerStruct struct { StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"` StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` + StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` @@ -236,6 +237,7 @@ type WorkerStruct struct { SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"` SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"` FinalizeSector func(context.Context, abi.SectorID) error `perm:"admin"` + MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"` ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error `perm:"admin"` @@ -802,6 +804,10 @@ func (c *StorageMinerStruct) StorageReportHealth(ctx context.Context, id stores. return c.Internal.StorageReportHealth(ctx, id, report) } +func (c *StorageMinerStruct) StorageLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error { + return c.Internal.StorageLock(ctx, sector, read, write) +} + func (c *StorageMinerStruct) MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error { return c.Internal.MarketImportDealData(ctx, propcid, path) } @@ -868,6 +874,10 @@ func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID) return w.Internal.FinalizeSector(ctx, sector) } +func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID) error { + return w.Internal.MoveStorage(ctx, sector) +} + func (w *WorkerStruct) UnsealPiece(ctx context.Context, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error { return w.Internal.UnsealPiece(ctx, id, index, size, randomness, c) } diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index e9721e9dd..f11a51b78 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -155,7 +155,7 @@ var runCmd = &cli.Command{ var taskTypes []sealtasks.TaskType - taskTypes = append(taskTypes, sealtasks.TTFetch) + taskTypes = append(taskTypes, sealtasks.TTFetch, sealtasks.TTCommit1, sealtasks.TTFinalize) if cctx.Bool("precommit1") { taskTypes = append(taskTypes, sealtasks.TTPreCommit1) From 8bbe63bd9d723ca67ae13106a7392ac60ccd2012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Jun 2020 17:10:41 +0200 Subject: [PATCH 067/379] Add expected win rate to miner-info --- cmd/lotus-storage-miner/info.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 0257be850..aa6feaa96 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "sort" + "time" "github.com/fatih/color" "golang.org/x/xerrors" @@ -14,6 +15,7 @@ import ( sealing "github.com/filecoin-project/storage-fsm" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -117,6 +119,18 @@ var infoCmd = &cli.Command{ faultyPercentage) } + expWinChance := float64(types.BigMul(qpercI, types.NewInt(build.BlocksPerEpoch)).Int64()) / 1000000 + if expWinChance > 0 { + if expWinChance > 1 { + expWinChance = 1 + } + winRate := time.Duration(float64(time.Second * build.BlockDelay) / expWinChance) + winPerDay := float64(time.Hour * 24) / float64(winRate) + + fmt.Print("Expected block win rate: ") + color.Blue("%.4f/day (every %s)", winPerDay, winRate.Truncate(time.Second)) + } + fmt.Println() fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance))) @@ -168,6 +182,7 @@ var stateList = []stateMeta{ {col: color.FgYellow, state: sealing.PreCommit1}, {col: color.FgYellow, state: sealing.PreCommit2}, {col: color.FgYellow, state: sealing.PreCommitting}, + {col: color.FgYellow, state: sealing.PreCommitWait}, {col: color.FgYellow, state: sealing.WaitSeed}, {col: color.FgYellow, state: sealing.Committing}, {col: color.FgYellow, state: sealing.CommitWait}, @@ -179,6 +194,7 @@ var stateList = []stateMeta{ {col: color.FgRed, state: sealing.ComputeProofFailed}, {col: color.FgRed, state: sealing.CommitFailed}, {col: color.FgRed, state: sealing.PackingFailed}, + {col: color.FgRed, state: sealing.FinalizeFailed}, {col: color.FgRed, state: sealing.Faulty}, {col: color.FgRed, state: sealing.FaultReported}, {col: color.FgRed, state: sealing.FaultedFinal}, From 0bc174697a7e4fd45843f65b93e7ff031bf11c57 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 5 Jun 2020 00:52:45 +0200 Subject: [PATCH 068/379] Fix WindowPoStScheduler Signed-off-by: Jakub Sztandera --- storage/wdpost_run.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 3613736b8..ea95245dd 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -176,7 +176,7 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, deadline log.Warnw("declare faults recovered Message CID", "cid", sm.Cid()) - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid()) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence) if err != nil { return xerrors.Errorf("declare faults recovered wait error: %w", err) } From 9e5cc7c910837bebdf84ef3541ca5efa9401a909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 4 Jun 2020 21:22:53 +0200 Subject: [PATCH 069/379] Update fsm, sector-storage --- api/api_worker.go | 2 +- api/apistruct/struct.go | 6 +++--- cmd/lotus-storage-miner/info.go | 3 ++- go.mod | 4 ++-- go.sum | 10 ++++++---- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/api/api_worker.go b/api/api_worker.go index a130824ab..69a5aed5f 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -30,7 +30,7 @@ type WorkerAPI interface { UnsealPiece(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error ReadPiece(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error - Fetch(context.Context, abi.SectorID, stores.SectorFileType, bool, stores.AcquireMode) error + Fetch(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error Closing(context.Context) (<-chan struct{}, error) } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 1cbf44bd4..ff27475e5 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -242,7 +242,7 @@ type WorkerStruct struct { UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"` ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error `perm:"admin"` - Fetch func(context.Context, abi.SectorID, stores.SectorFileType, bool, stores.AcquireMode) error `perm:"admin"` + Fetch func(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error `perm:"admin"` Closing func(context.Context) (<-chan struct{}, error) `perm:"admin"` } @@ -886,8 +886,8 @@ func (w *WorkerStruct) ReadPiece(ctx context.Context, writer io.Writer, id abi.S return w.Internal.ReadPiece(ctx, writer, id, index, size) } -func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, b bool, am stores.AcquireMode) error { - return w.Internal.Fetch(ctx, id, fileType, b, am) +func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, ptype stores.PathType, am stores.AcquireMode) error { + return w.Internal.Fetch(ctx, id, fileType, ptype, am) } func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) { diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index aa6feaa96..dfb53d898 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -189,7 +189,8 @@ var stateList = []stateMeta{ {col: color.FgYellow, state: sealing.FinalizeSector}, {col: color.FgRed, state: sealing.FailedUnrecoverable}, - {col: color.FgRed, state: sealing.SealFailed}, + {col: color.FgRed, state: sealing.SealPreCommit1Failed}, + {col: color.FgRed, state: sealing.SealPreCommit2Failed}, {col: color.FgRed, state: sealing.PreCommitFailed}, {col: color.FgRed, state: sealing.ComputeProofFailed}, {col: color.FgRed, state: sealing.CommitFailed}, diff --git a/go.mod b/go.mod index e4a4a9993..96919c680 100644 --- a/go.mod +++ b/go.mod @@ -29,10 +29,10 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200505180321-973f8949ea8e github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200529175241-9df0cdf19326 + github.com/filecoin-project/sector-storage v0.0.0-20200604213020-13176e8b537d github.com/filecoin-project/specs-actors v0.5.4 github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 - github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960 + github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index 57da8c1ce..bf77833c4 100644 --- a/go.sum +++ b/go.sum @@ -208,8 +208,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= -github.com/filecoin-project/sector-storage v0.0.0-20200529175241-9df0cdf19326 h1:WIIvOzK9KaWMFXhvivUxeg4cdMzQ/5/MW+bNpYj43wU= -github.com/filecoin-project/sector-storage v0.0.0-20200529175241-9df0cdf19326/go.mod h1:hUQo3z/5B8t8Yl+XgIxBqgNfYtIcCYzKjWWY27dHBCk= +github.com/filecoin-project/sector-storage v0.0.0-20200604213020-13176e8b537d h1:Lh6iYC2xhsV5hvACi6joUIBLabzCcOZiAxg67ZLP5dE= +github.com/filecoin-project/sector-storage v0.0.0-20200604213020-13176e8b537d/go.mod h1:hUQo3z/5B8t8Yl+XgIxBqgNfYtIcCYzKjWWY27dHBCk= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= @@ -218,8 +218,10 @@ github.com/filecoin-project/specs-actors v0.5.4 h1:Od00SYb/pTXC84oZGz9h2xGBm8GIH github.com/filecoin-project/specs-actors v0.5.4/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= -github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960 h1:KXkOn1r3lyxKn2rHUcVox6WYtfIEsgyZdBVoIVJARjY= -github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= +github.com/filecoin-project/storage-fsm v0.0.0-20200604153036-8ad1af106d62 h1:QDnMGcx4QisW/8tPHM4Uy9K4LkYBIijaHFxhk5Cpmxs= +github.com/filecoin-project/storage-fsm v0.0.0-20200604153036-8ad1af106d62/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= +github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa h1:kTCIBKMhhhVcjCh1ws72vpdDr4cdZjCyIUDFijuWuvA= +github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= From 813961b458e184e1c5f187260c6a6a64c8b2ff28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 5 Jun 2020 14:57:37 +0200 Subject: [PATCH 070/379] compute-state html: Allow linking to internal executions --- cli/state.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cli/state.go b/cli/state.go index c8425f645..fbc0b109b 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1042,7 +1042,7 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( if len(ir.InternalExecutions) > 0 { fmt.Println("
Internal executions:
") - if err := printInternalExecutionsHtml(ir.InternalExecutions, getCode); err != nil { + if err := printInternalExecutionsHtml(cid.String(), ir.InternalExecutions, getCode); err != nil { return err } } @@ -1054,8 +1054,10 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( return nil } -func printInternalExecutionsHtml(trace []*types.ExecutionResult, getCode func(addr address.Address) (cid.Cid, error)) error { - for _, im := range trace { +func printInternalExecutionsHtml(hashName string, trace []*types.ExecutionResult, getCode func(addr address.Address) (cid.Cid, error)) error { + for i, im := range trace { + hashName := fmt.Sprintf("%s-r%d", hashName, i) + toCode, err := getCode(im.Msg.To) if err != nil { return xerrors.Errorf("getting code for %s: %w", toCode, err) @@ -1086,18 +1088,18 @@ func printInternalExecutionsHtml(trace []*types.ExecutionResult, getCode func(ad slow := im.Duration > 10*time.Millisecond veryslow := im.Duration > 50*time.Millisecond - fmt.Printf(`
-

%s:%s

+ fmt.Printf(`
+
%s -> %s (%s FIL), M%d
%s
Took %s, Exit: %d%s -`, codeStr(toCode), methods[toCode][im.Msg.Method].name, im.Msg.From, im.Msg.To, types.FIL(im.Msg.Value), im.Msg.Method, params, slow, veryslow, im.Duration, im.MsgRct.ExitCode, im.MsgRct.ExitCode, ret) +`, hashName, hashName, codeStr(toCode), methods[toCode][im.Msg.Method].name, im.Msg.From, im.Msg.To, types.FIL(im.Msg.Value), im.Msg.Method, params, slow, veryslow, im.Duration, im.MsgRct.ExitCode, im.MsgRct.ExitCode, ret) if im.MsgRct.ExitCode != 0 { fmt.Printf(`
Error:
%s
`, im.Error) } if len(im.Subcalls) > 0 { fmt.Println("
Subcalls:
") - if err := printInternalExecutionsHtml(im.Subcalls, getCode); err != nil { + if err := printInternalExecutionsHtml(hashName, im.Subcalls, getCode); err != nil { return err } } From 6b06ae528c44130c5bc9fe9d7b05d7a7ea1b1b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 5 Jun 2020 17:41:21 +0200 Subject: [PATCH 071/379] chain get: @state selector to prettify actor state --- cli/chain.go | 3 ++- node/impl/full/chain.go | 51 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/cli/chain.go b/cli/chain.go index 4d296cf78..a174e75f2 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -442,7 +442,8 @@ var chainGetCmd = &cli.Command{ - /ipfs/[cid]/@Hi:123 - get varint elem 123 from hamt - /ipfs/[cid]/@Hu:123 - get uvarint elem 123 from hamt - /ipfs/[cid]/@Ha:t01 - get element under Addr(t01).Bytes - - /ipfs/[cid]/@A:10 - get 10th amt element + - /ipfs/[cid]/@A:10 - get 10th amt element + - .../@Ha:t01/@state - get pretty map-based actor state List of --as-type types: - raw diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index f6553fa54..d5c8f385b 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -1,7 +1,9 @@ package full import ( + "bytes" "context" + "encoding/json" "fmt" "io" "strconv" @@ -33,6 +35,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" ) var log = logging.Logger("fullnode") @@ -377,6 +380,54 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod return resolveOnce(bs)(ctx, ds, n, names[1:]) } + if names[0] == "@state" { + var act types.Actor + if err := act.UnmarshalCBOR(bytes.NewReader(nd.RawData())); err != nil { + return nil, nil, xerrors.Errorf("unmarshaling actor struct for @state: %w", err) + } + + head, err := ds.Get(ctx, act.Head) + if err != nil { + return nil, nil, xerrors.Errorf("getting actor head for @state: %w", err) + } + + m, err := vm.DumpActorState(act.Code, head.RawData()) + if err != nil { + return nil, nil, err + } + + // a hack to workaround struct aliasing in refmt + ms := map[string]interface{}{} + { + mstr, err := json.Marshal(m) + if err != nil { + return nil, nil, err + } + if err := json.Unmarshal(mstr, &ms); err != nil { + return nil, nil, err + } + } + + n, err := cbor.WrapObject(ms, mh.SHA2_256, 32) + if err != nil { + return nil, nil, err + } + + if err := bs.Put(n); err != nil { + return nil, nil, xerrors.Errorf("put amt val: %w", err) + } + + if len(names) == 1 { + return &ipld.Link{ + Name: "state", + Size: 0, + Cid: n.Cid(), + }, nil, nil + } + + return resolveOnce(bs)(ctx, ds, n, names[1:]) + } + return nd.ResolveLink(names) } } From 51f1712564a89707f237c4fa3db1ebc705e229d7 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Fri, 5 Jun 2020 10:47:49 -0700 Subject: [PATCH 072/379] add a simple semaphore to batch verify seals --- chain/vm/syscalls.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index 100472c69..143807ab4 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + goruntime "runtime" "sync" "github.com/filecoin-project/go-address" @@ -243,6 +244,8 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { out := make(map[address.Address][]bool) + sema := make(chan struct{}, goruntime.NumCPU()) + var wg sync.WaitGroup for addr, seals := range inp { results := make([]bool, len(seals)) @@ -252,12 +255,16 @@ func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]abi.SealVerify wg.Add(1) go func(ma address.Address, ix int, svi abi.SealVerifyInfo, res []bool) { defer wg.Done() + sema <- struct{}{} + if err := ss.VerifySeal(svi); err != nil { log.Warnw("seal verify in batch failed", "miner", ma, "index", ix, "err", err) res[ix] = false } else { res[ix] = true } + + <-sema }(addr, i, s, results) } } From cd6670205c43a2c4d9b73039d33e5a59f2ce49e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 5 Jun 2020 20:21:40 +0200 Subject: [PATCH 073/379] Update sector-storage --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2f2adce08..e59cdfbaa 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200505180321-973f8949ea8e github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200604213020-13176e8b537d + github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f github.com/filecoin-project/specs-actors v0.5.4 github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa diff --git a/go.sum b/go.sum index 9cb785560..bb16166fd 100644 --- a/go.sum +++ b/go.sum @@ -219,8 +219,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= -github.com/filecoin-project/sector-storage v0.0.0-20200604213020-13176e8b537d h1:Lh6iYC2xhsV5hvACi6joUIBLabzCcOZiAxg67ZLP5dE= -github.com/filecoin-project/sector-storage v0.0.0-20200604213020-13176e8b537d/go.mod h1:hUQo3z/5B8t8Yl+XgIxBqgNfYtIcCYzKjWWY27dHBCk= +github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f h1:UASwQxRVA9LEfpFhhh87RvZMaPRFfR7QlWXNd9u6Aj0= +github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f/go.mod h1:hUQo3z/5B8t8Yl+XgIxBqgNfYtIcCYzKjWWY27dHBCk= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= From 3f81ff35078020edae3c98473a20d0e7bb1f048b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 5 Jun 2020 22:06:11 +0200 Subject: [PATCH 074/379] Update specs-actors --- chain/gen/genesis/miners.go | 2 +- cli/client.go | 4 ++-- cmd/lotus-fountain/main.go | 2 +- cmd/lotus-storage-miner/init.go | 4 ++-- go.mod | 2 +- go.sum | 2 ++ markets/storageadapter/client.go | 3 ++- node/impl/client/client.go | 4 ++-- node/node_test.go | 2 +- 9 files changed, 14 insertions(+), 11 deletions(-) diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index fa71865b8..92d77d270 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -71,7 +71,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid constructorParams := &power.CreateMinerParams{ Owner: m.Worker, Worker: m.Worker, - Peer: m.PeerId, + Peer: []byte(m.PeerId), SealProofType: spt, } diff --git a/cli/client.go b/cli/client.go index ea6241b9b..8ee26f2d2 100644 --- a/cli/client.go +++ b/cli/client.go @@ -446,11 +446,11 @@ var clientQueryAskCmd = &cli.Command{ return xerrors.Errorf("failed to get peerID for miner: %w", err) } - if mi.PeerId == peer.ID("SETME") { + if peer.ID(mi.PeerId) == peer.ID("SETME") { return fmt.Errorf("the miner hasn't initialized yet") } - pid = mi.PeerId + pid = peer.ID(mi.PeerId) } ask, err := api.ClientQueryAsk(ctx, pid, maddr) diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index f181bf173..8b13c7ba6 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -294,7 +294,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) { Owner: owner, Worker: owner, SealProofType: spt, - Peer: h.defaultMinerPeer, + Peer: abi.PeerID(h.defaultMinerPeer), }) if err != nil { w.WriteHeader(400) diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 5d598fa5b..bcdb113d8 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -545,7 +545,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. return xerrors.Errorf("getWorkerAddr returned bad address: %w", err) } - enc, err := actors.SerializeParams(&miner2.ChangePeerIDParams{NewID: peerid}) + enc, err := actors.SerializeParams(&miner2.ChangePeerIDParams{NewID: abi.PeerID(peerid)}) if err != nil { return err } @@ -622,7 +622,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, Owner: owner, Worker: worker, SealProofType: spt, - Peer: peerid, + Peer: abi.PeerID(peerid), }) if err != nil { return address.Undef, err diff --git a/go.mod b/go.mod index e59cdfbaa..6626da43a 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f - github.com/filecoin-project/specs-actors v0.5.4 + github.com/filecoin-project/specs-actors v0.5.5-0.20200605181154-8e2301d36794 github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index bb16166fd..cbaa7e296 100644 --- a/go.sum +++ b/go.sum @@ -227,6 +227,8 @@ github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVl github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.4 h1:Od00SYb/pTXC84oZGz9h2xGBm8GIHo8GXUaRKg1ClZo= github.com/filecoin-project/specs-actors v0.5.4/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= +github.com/filecoin-project/specs-actors v0.5.5-0.20200605181154-8e2301d36794 h1:JrpmpAPPjso2+RNvPYqXLaDRLyg6A1l26ub4ah+WC1o= +github.com/filecoin-project/specs-actors v0.5.5-0.20200605181154-8e2301d36794/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa h1:kTCIBKMhhhVcjCh1ws72vpdDr4cdZjCyIUDFijuWuvA= diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index d9deaedf2..5f962c171 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -19,6 +19,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/events" @@ -79,7 +80,7 @@ func (n *ClientNodeAdapter) ListStorageProviders(ctx context.Context, encodedTs return nil, err } - storageProviderInfo := utils.NewStorageProviderInfo(addr, mi.Worker, mi.SectorSize, mi.PeerId) + storageProviderInfo := utils.NewStorageProviderInfo(addr, mi.Worker, mi.SectorSize, peer.ID(mi.PeerId)) out = append(out, &storageProviderInfo) } diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 594787ae8..59a258489 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -103,7 +103,7 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) return nil, xerrors.New("data doesn't fit in a sector") } - providerInfo := utils.NewStorageProviderInfo(params.Miner, mi.Worker, mi.SectorSize, mi.PeerId) + providerInfo := utils.NewStorageProviderInfo(params.Miner, mi.Worker, mi.SectorSize, peer.ID(mi.PeerId)) dealStart := params.DealStartEpoch if dealStart <= 0 { // unset, or explicitly 'epoch undefined' @@ -309,7 +309,7 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref return err } - order.MinerPeerID = mi.PeerId + order.MinerPeerID = peer.ID(mi.PeerId) } if order.Size == 0 { diff --git a/node/node_test.go b/node/node_test.go index 6258fa943..8b17fac2e 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -97,7 +97,7 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a peerid, err := peer.IDFromPrivateKey(pk) require.NoError(t, err) - enc, err := actors.SerializeParams(&saminer.ChangePeerIDParams{NewID: peerid}) + enc, err := actors.SerializeParams(&saminer.ChangePeerIDParams{NewID: abi.PeerID(peerid)}) require.NoError(t, err) msg := &types.Message{ From 73d928751d7d2344f57c4ff3c5496fd2c2198d10 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Fri, 5 Jun 2020 15:12:13 -0700 Subject: [PATCH 075/379] disallow sourcing randomness from future epochs --- chain/store/store.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/store/store.go b/chain/store/store.go index 72c77ee36..998129d41 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -904,7 +904,7 @@ func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.Cha return h.Sum(nil), nil } -func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) (out []byte, err error) { +func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { _, span := trace.StartSpan(ctx, "store.GetRandomness") defer span.End() span.AddAttributes(trace.Int64Attribute("round", int64(round))) @@ -915,7 +915,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers cr } if round > ts.Height() { - return DrawRandomness(ts.MinTicket().VRFProof, pers, round, entropy) + return nil, xerrors.Errorf("cannot draw randomness from the future") } searchHeight := round From 2571480bb67e9c3e7aa20cac1848beed8ef8f983 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 5 Jun 2020 18:10:50 -0400 Subject: [PATCH 076/379] Update chain-val, use tagged specs-actors --- go.mod | 4 ++-- go.sum | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 6626da43a..51f33818d 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 - github.com/filecoin-project/chain-validation v0.0.6-0.20200528212128-d4578ae4f874 + github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94 github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f - github.com/filecoin-project/specs-actors v0.5.5-0.20200605181154-8e2301d36794 + github.com/filecoin-project/specs-actors v0.5.5 github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index cbaa7e296..b1c3b032c 100644 --- a/go.sum +++ b/go.sum @@ -180,8 +180,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= -github.com/filecoin-project/chain-validation v0.0.6-0.20200528212128-d4578ae4f874 h1:NNzyoQjidcvvoARgaM6zo2jYXC0KwNQkaYuDiBFcAD4= -github.com/filecoin-project/chain-validation v0.0.6-0.20200528212128-d4578ae4f874/go.mod h1:aV5C4aX+kZwh5OlTHNCHxQ5vTnpTFKUuKiDTk9f/8Es= +github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94 h1:svEal/usZ/REEjEz6ije3/ALn8duM2CckR0LjT1btx0= +github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94/go.mod h1:aOmmdhO0xIRtWCwx3MyIv3tPCCorM1Bq7pNOJGMLndA= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= @@ -225,10 +225,8 @@ github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.m github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= -github.com/filecoin-project/specs-actors v0.5.4 h1:Od00SYb/pTXC84oZGz9h2xGBm8GIHo8GXUaRKg1ClZo= -github.com/filecoin-project/specs-actors v0.5.4/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= -github.com/filecoin-project/specs-actors v0.5.5-0.20200605181154-8e2301d36794 h1:JrpmpAPPjso2+RNvPYqXLaDRLyg6A1l26ub4ah+WC1o= -github.com/filecoin-project/specs-actors v0.5.5-0.20200605181154-8e2301d36794/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.5.5 h1:bDsowem6dLRc9B7g3sgFYvHgfWTH4D9q5ehWLGLdKCw= +github.com/filecoin-project/specs-actors v0.5.5/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa h1:kTCIBKMhhhVcjCh1ws72vpdDr4cdZjCyIUDFijuWuvA= From f765fe36d7e8542ed37ce71a97871729fdbef1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 5 Jun 2020 01:38:38 +0200 Subject: [PATCH 077/379] Make lotus-storage-miner deadlines correct --- cmd/lotus-storage-miner/proving.go | 59 ++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 9f9ca600a..3415c7ffd 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -3,15 +3,21 @@ package main import ( "bytes" "fmt" + "os" + "text/tabwriter" "time" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-bitfield" + rlepluslazy "github.com/filecoin-project/go-bitfield/rle" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/urfave/cli/v2" - "golang.org/x/xerrors" ) var provingCmd = &cli.Command{ @@ -191,28 +197,59 @@ var provingDeadlinesCmd = &cli.Command{ } } + tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) + _, _ = fmt.Fprintln(tw, "deadline\tsectors\tpartitions\tproven") + for i, field := range deadlines.Due { c, err := field.Count() if err != nil { return err } - var info string - proven, err := mas.PostSubmissions.IsSet(uint64(i)) + firstPartition, sectorCount, err := miner.PartitionsForDeadline(deadlines, mas.Info.WindowPoStPartitionSectors, uint64(i)) if err != nil { return err } - if proven { - info += ", proven" + partitionCount := (sectorCount + mas.Info.WindowPoStPartitionSectors - 1) / mas.Info.WindowPoStPartitionSectors + + var provenPartitions uint64 + { + var maskRuns []rlepluslazy.Run + if firstPartition > 0 { + maskRuns = append(maskRuns, rlepluslazy.Run{ + Val: false, + Len: firstPartition, + }) + } + maskRuns = append(maskRuns, rlepluslazy.Run{ + Val: true, + Len: partitionCount, + }) + + ppbm, err := bitfield.NewFromIter(&rlepluslazy.RunSliceIterator{Runs: maskRuns}) + if err != nil { + return err + } + + pp, err := bitfield.IntersectBitField(ppbm, mas.PostSubmissions) + if err != nil { + return err + } + + provenPartitions, err = pp.Count() + if err != nil { + return err + } } + var cur string if di.Index == uint64(i) { - info += " (current)" + cur += "\t(current)" } - fmt.Printf("%d: %d sectors%s\n", i, c, info) + _, _ = fmt.Fprintf(tw,"%d\t%d\t%d\t%d%s\n", i, c, partitionCount, provenPartitions, cur) } - return nil + return tw.Flush() }, } From 3b133971657f3c70c3f16d426b2068ac31a716a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 6 Jun 2020 00:59:01 +0200 Subject: [PATCH 078/379] gofmt --- api/apistruct/struct.go | 4 ++-- cli/auth.go | 2 +- cli/chain.go | 2 +- cli/client.go | 2 +- cli/cmd.go | 2 +- cli/log.go | 2 +- cli/mpool.go | 2 +- cli/multisig.go | 2 +- cli/params.go | 2 +- cli/state.go | 2 +- cmd/lotus-bench/main.go | 2 +- cmd/lotus-chainwatch/main.go | 2 +- cmd/lotus-fountain/main.go | 2 +- cmd/lotus-seal-worker/main.go | 2 +- cmd/lotus-seed/genesis.go | 2 +- cmd/lotus-shed/bitfield.go | 2 +- cmd/lotus-shed/import-car.go | 2 +- cmd/lotus-shed/params.go | 2 +- cmd/lotus-storage-miner/info.go | 6 +++--- cmd/lotus-storage-miner/init.go | 2 +- cmd/lotus-storage-miner/proving.go | 2 +- cmd/lotus-storage-miner/run.go | 2 +- cmd/lotus-storage-miner/sectors.go | 2 +- cmd/lotus-storage-miner/storage.go | 2 +- cmd/lotus/daemon.go | 2 +- 25 files changed, 28 insertions(+), 28 deletions(-) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index aba0790e7..940f876e2 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -216,7 +216,7 @@ type StorageMinerStruct struct { StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"` StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` - StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` + StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` @@ -240,7 +240,7 @@ type WorkerStruct struct { SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"` SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"` FinalizeSector func(context.Context, abi.SectorID) error `perm:"admin"` - MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` + MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"` ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error `perm:"admin"` diff --git a/cli/auth.go b/cli/auth.go index e3497f17c..d59ac37a5 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -3,8 +3,8 @@ package cli import ( "fmt" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-jsonrpc/auth" diff --git a/cli/chain.go b/cli/chain.go index a174e75f2..d76335263 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -23,9 +23,9 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/power" "github.com/filecoin-project/specs-actors/actors/util/adt" cid "github.com/ipfs/go-cid" + "github.com/urfave/cli/v2" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" diff --git a/cli/client.go b/cli/client.go index afd8e3e29..d6b59db53 100644 --- a/cli/client.go +++ b/cli/client.go @@ -11,8 +11,8 @@ import ( "github.com/ipfs/go-cidutil/cidenc" "github.com/libp2p/go-libp2p-core/peer" "github.com/multiformats/go-multibase" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/storagemarket" diff --git a/cli/cmd.go b/cli/cmd.go index 3953f1372..83a1845fc 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -13,8 +13,8 @@ import ( "github.com/mitchellh/go-homedir" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-jsonrpc" diff --git a/cli/log.go b/cli/log.go index 3e1027ccf..a7d95799d 100644 --- a/cli/log.go +++ b/cli/log.go @@ -3,8 +3,8 @@ package cli import ( "fmt" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" ) var logCmd = &cli.Command{ diff --git a/cli/mpool.go b/cli/mpool.go index 1b8a1e0d1..fec7b2e0d 100644 --- a/cli/mpool.go +++ b/cli/mpool.go @@ -5,8 +5,8 @@ import ( "fmt" "sort" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" diff --git a/cli/multisig.go b/cli/multisig.go index 961a14a56..e0f233db8 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -17,9 +17,9 @@ import ( cid "github.com/ipfs/go-cid" "github.com/ipfs/go-hamt-ipld" cbor "github.com/ipfs/go-ipld-cbor" + "github.com/urfave/cli/v2" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" diff --git a/cli/params.go b/cli/params.go index 93c8d9458..b0594b641 100644 --- a/cli/params.go +++ b/cli/params.go @@ -3,8 +3,8 @@ package cli import ( "github.com/docker/go-units" paramfetch "github.com/filecoin-project/go-paramfetch" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" ) diff --git a/cli/state.go b/cli/state.go index fbc0b109b..c0cfd8eb4 100644 --- a/cli/state.go +++ b/cli/state.go @@ -15,9 +15,9 @@ import ( "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" "github.com/multiformats/go-multihash" + "github.com/urfave/cli/v2" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" - "github.com/urfave/cli/v2" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index e410d09c5..5951bd6fa 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -15,8 +15,8 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/minio/blake2b-simd" "github.com/mitchellh/go-homedir" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" paramfetch "github.com/filecoin-project/go-paramfetch" diff --git a/cmd/lotus-chainwatch/main.go b/cmd/lotus-chainwatch/main.go index b5ca379e0..704c4d457 100644 --- a/cmd/lotus-chainwatch/main.go +++ b/cmd/lotus-chainwatch/main.go @@ -7,8 +7,8 @@ import ( "os" logging "github.com/ipfs/go-log/v2" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 8b13c7ba6..c5c6d5857 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -14,8 +14,8 @@ import ( "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p-core/peer" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index c9f0239cf..65418ead8 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -12,8 +12,8 @@ import ( "github.com/google/uuid" "github.com/gorilla/mux" logging "github.com/ipfs/go-log/v2" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index 471fb99df..748b406ac 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -6,8 +6,8 @@ import ( "github.com/google/uuid" "github.com/mitchellh/go-homedir" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi/big" diff --git a/cmd/lotus-shed/bitfield.go b/cmd/lotus-shed/bitfield.go index 0cf9e4ea0..79ce214ee 100644 --- a/cmd/lotus-shed/bitfield.go +++ b/cmd/lotus-shed/bitfield.go @@ -7,8 +7,8 @@ import ( "io/ioutil" "os" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-bitfield" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" diff --git a/cmd/lotus-shed/import-car.go b/cmd/lotus-shed/import-car.go index 091ab9054..e54089df0 100644 --- a/cmd/lotus-shed/import-car.go +++ b/cmd/lotus-shed/import-car.go @@ -7,8 +7,8 @@ import ( blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/ipld/go-car" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/node/repo" ) diff --git a/cmd/lotus-shed/params.go b/cmd/lotus-shed/params.go index 74876d778..3f7e7b6fb 100644 --- a/cmd/lotus-shed/params.go +++ b/cmd/lotus-shed/params.go @@ -4,8 +4,8 @@ import ( "github.com/docker/go-units" paramfetch "github.com/filecoin-project/go-paramfetch" lcli "github.com/filecoin-project/lotus/cli" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" ) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 161a386a0..9d98f8569 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -8,8 +8,8 @@ import ( "time" "github.com/fatih/color" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/specs-actors/actors/builtin/miner" sealing "github.com/filecoin-project/storage-fsm" @@ -124,8 +124,8 @@ var infoCmd = &cli.Command{ if expWinChance > 1 { expWinChance = 1 } - winRate := time.Duration(float64(time.Second * build.BlockDelay) / expWinChance) - winPerDay := float64(time.Hour * 24) / float64(winRate) + winRate := time.Duration(float64(time.Second*build.BlockDelay) / expWinChance) + winPerDay := float64(time.Hour*24) / float64(winRate) fmt.Print("Expected block win rate: ") color.Blue("%.4f/day (every %s)", winPerDay, winRate.Truncate(time.Second)) diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 024b8d540..29e82cc2f 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -18,8 +18,8 @@ import ( "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" "github.com/mitchellh/go-homedir" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 3415c7ffd..8adb021ea 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -247,7 +247,7 @@ var provingDeadlinesCmd = &cli.Command{ if di.Index == uint64(i) { cur += "\t(current)" } - _, _ = fmt.Fprintf(tw,"%d\t%d\t%d\t%d%s\n", i, c, partitionCount, provenPartitions, cur) + _, _ = fmt.Fprintf(tw, "%d\t%d\t%d\t%d%s\n", i, c, partitionCount, provenPartitions, cur) } return tw.Flush() diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 62df0a48d..29634d17d 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -11,8 +11,8 @@ import ( mux "github.com/gorilla/mux" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index 1a500cc8b..4a3109f37 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -8,8 +8,8 @@ import ( "text/tabwriter" "time" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus-storage-miner/storage.go b/cmd/lotus-storage-miner/storage.go index a8ceda6c2..4ab46fdae 100644 --- a/cmd/lotus-storage-miner/storage.go +++ b/cmd/lotus-storage-miner/storage.go @@ -14,8 +14,8 @@ import ( "github.com/fatih/color" "github.com/google/uuid" "github.com/mitchellh/go-homedir" - "golang.org/x/xerrors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 6da80a0c8..fd9ceea85 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -18,11 +18,11 @@ import ( blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/mitchellh/go-homedir" "github.com/multiformats/go-multiaddr" + "github.com/urfave/cli/v2" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" "golang.org/x/xerrors" - "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" From 94da3396228ff829635fe3b09376771f877eec58 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 6 Jun 2020 02:47:29 +0200 Subject: [PATCH 079/379] Fix protobuf panic by updating protobuf to 1.4.2 The panic is caused by usage of internal protobuf interface. It was changed in protobuf 1.4.0 and reluctantly fixed in 1.4.2 Signed-off-by: Jakub Sztandera --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index a6b832d16..9d5411681 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect + github.com/golang/protobuf v1.4.2 // indirect github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index fb7ad986f..7deb743d1 100644 --- a/go.sum +++ b/go.sum @@ -292,6 +292,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= From baa69c3c812aae2de1bbb7860b18ec30becd7e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 6 Jun 2020 19:51:10 +0200 Subject: [PATCH 080/379] Update specs-actors to v0.5.6 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 9d5411681..786afed49 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f - github.com/filecoin-project/specs-actors v0.5.5 + github.com/filecoin-project/specs-actors v0.5.6 github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 7deb743d1..be456d1dd 100644 --- a/go.sum +++ b/go.sum @@ -227,6 +227,8 @@ github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVl github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= github.com/filecoin-project/specs-actors v0.5.5 h1:bDsowem6dLRc9B7g3sgFYvHgfWTH4D9q5ehWLGLdKCw= github.com/filecoin-project/specs-actors v0.5.5/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.5.6 h1:WlhtoXwFoKlP1b06NI4NJaxC4m9EXNV+qFVl43/xRN8= +github.com/filecoin-project/specs-actors v0.5.6/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa h1:kTCIBKMhhhVcjCh1ws72vpdDr4cdZjCyIUDFijuWuvA= From e91cc9cd08da76c54ce2344a245af1ab2f460939 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 3 Jun 2020 15:48:22 +0200 Subject: [PATCH 081/379] Add drand topic scores Signed-off-by: Jakub Sztandera --- node/modules/lp2p/pubsub.go | 94 ++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 13 deletions(-) diff --git a/node/modules/lp2p/pubsub.go b/node/modules/lp2p/pubsub.go index fdb4dc028..76387dd1d 100644 --- a/node/modules/lp2p/pubsub.go +++ b/node/modules/lp2p/pubsub.go @@ -2,6 +2,7 @@ package lp2p import ( "context" + "encoding/json" "time" host "github.com/libp2p/go-libp2p-core/host" @@ -11,6 +12,7 @@ import ( blake2b "github.com/minio/blake2b-simd" ma "github.com/multiformats/go-multiaddr" "go.uber.org/fx" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/node/config" @@ -28,17 +30,42 @@ func init() { pubsub.GossipSubDlazy = 12 pubsub.GossipSubDirectConnectInitialDelay = 30 * time.Second } - func ScoreKeeper() *dtypes.ScoreKeeper { return new(dtypes.ScoreKeeper) } -func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtypes.NetworkName, bp dtypes.BootstrapPeers, cfg *config.Pubsub, sk *dtypes.ScoreKeeper) (service *pubsub.PubSub, err error) { +type GossipIn struct { + fx.In + Mctx helpers.MetricsCtx + Lc fx.Lifecycle + Host host.Host + Nn dtypes.NetworkName + Bp dtypes.BootstrapPeers + Cfg *config.Pubsub + Sk *dtypes.ScoreKeeper +} + +func getDrandTopic() (string, error) { + var drandInfo = struct { + Hash string `json:"hash"` + }{} + err := json.Unmarshal([]byte(build.DrandChain), &drandInfo) + if err != nil { + return "", xerrors.Errorf("could not unmarshal drand chain info: %w", err) + } + return "/drand/pubsub/v0.0.0/" + drandInfo.Hash, nil +} + +func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { bootstrappers := make(map[peer.ID]struct{}) - for _, pi := range bp { + for _, pi := range in.Bp { bootstrappers[pi.ID] = struct{}{} } - isBootstrapNode := cfg.Bootstrapper + isBootstrapNode := in.Cfg.Bootstrapper + drandTopic, err := getDrandTopic() + if err != nil { + return nil, err + } options := []pubsub.Option{ // Gossipsubv1.1 configuration @@ -80,7 +107,48 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp // topic parameters Topics: map[string]*pubsub.TopicScoreParams{ - build.BlocksTopic(nn): { + drandTopic: { + // expected 2 beaconsn/min + TopicWeight: 0.5, // 5x block topic + + // 1 tick per second, maxes at 1 after 1 hour + TimeInMeshWeight: 0.00027, // ~1/3600 + TimeInMeshQuantum: time.Second, + TimeInMeshCap: 1, + + // deliveries decay after 1 hour, cap at 100 blocks + FirstMessageDeliveriesWeight: 5, // max value is 500 + FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), + FirstMessageDeliveriesCap: 100, // 100 blocks in an hour + + // Mesh Delivery Failure is currently turned off for blocks + // This is on purpose as + // - the traffic is very low for meaningful distribution of incoming edges. + // - the reaction time needs to be very slow -- in the order of 10 min at least + // so we might as well let opportunistic grafting repair the mesh on its own + // pace. + // - the network is too small, so large asymmetries can be expected between mesh + // edges. + // We should revisit this once the network grows. + // + // // tracks deliveries in the last minute + // // penalty activates at 1 minute and expects ~0.4 blocks + // MeshMessageDeliveriesWeight: -576, // max penalty is -100 + // MeshMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Minute), + // MeshMessageDeliveriesCap: 10, // 10 blocks in a minute + // MeshMessageDeliveriesThreshold: 0.41666, // 10/12/2 blocks/min + // MeshMessageDeliveriesWindow: 10 * time.Millisecond, + // MeshMessageDeliveriesActivation: time.Minute, + // + // // decays after 15 min + // MeshFailurePenaltyWeight: -576, + // MeshFailurePenaltyDecay: pubsub.ScoreParameterDecay(15 * time.Minute), + + // invalid messages decay after 1 hour + InvalidMessageDeliveriesWeight: -1000, + InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), + }, + build.BlocksTopic(in.Nn): { // expected 10 blocks/min TopicWeight: 0.1, // max is 50, max mesh penalty is -10, single invalid message is -100 @@ -121,7 +189,7 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp InvalidMessageDeliveriesWeight: -1000, InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), }, - build.MessagesTopic(nn): { + build.MessagesTopic(in.Nn): { // expected > 1 tx/second TopicWeight: 0.05, // max is 25, max mesh penalty is -5, single invalid message is -100 @@ -166,7 +234,7 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp OpportunisticGraftThreshold: 5, }, ), - pubsub.WithPeerScoreInspect(sk.Update, 10*time.Second), + pubsub.WithPeerScoreInspect(in.Sk.Update, 10*time.Second), } // enable Peer eXchange on bootstrappers @@ -184,10 +252,10 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp } // direct peers - if cfg.DirectPeers != nil { + if in.Cfg.DirectPeers != nil { var directPeerInfo []peer.AddrInfo - for _, addr := range cfg.DirectPeers { + for _, addr := range in.Cfg.DirectPeers { a, err := ma.NewMultiaddr(addr) if err != nil { return nil, err @@ -205,8 +273,8 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp } // tracer - if cfg.RemoteTracer != "" { - a, err := ma.NewMultiaddr(cfg.RemoteTracer) + if in.Cfg.RemoteTracer != "" { + a, err := ma.NewMultiaddr(in.Cfg.RemoteTracer) if err != nil { return nil, err } @@ -216,7 +284,7 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp return nil, err } - tr, err := pubsub.NewRemoteTracer(context.TODO(), host, *pi) + tr, err := pubsub.NewRemoteTracer(context.TODO(), in.Host, *pi) if err != nil { return nil, err } @@ -229,7 +297,7 @@ func GossipSub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtyp // in peer scores for debugging purposes -- this might be trigged by metrics collection // options = append(options, pubsub.WithPeerScoreInspect(XXX, time.Second)) - return pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, options...) + return pubsub.NewGossipSub(helpers.LifecycleCtx(in.Mctx, in.Lc), in.Host, options...) } func HashMsgId(m *pubsub_pb.Message) string { From 7762cd0a686a808a5f0f4f3e32acac402ac7d11d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 8 Jun 2020 11:31:33 +0200 Subject: [PATCH 082/379] Assign positive scores to drand bootstrappers Signed-off-by: Jakub Sztandera --- build/bootstrap.go | 9 +++++++++ node/builder.go | 1 + node/modules/core.go | 4 ++++ node/modules/dtypes/bootstrap.go | 1 + node/modules/lp2p/pubsub.go | 11 +++++++++++ 5 files changed, 26 insertions(+) diff --git a/build/bootstrap.go b/build/bootstrap.go index ca6cc26ce..0710f0dc0 100644 --- a/build/bootstrap.go +++ b/build/bootstrap.go @@ -34,3 +34,12 @@ func BuiltinBootstrap() ([]peer.AddrInfo, error) { }) return out, err } + +func DrandBootstrap() ([]peer.AddrInfo, error) { + addrs := []string{ + "/dnsaddr/pl-eu.testnet.drand.sh/", + "/dnsaddr/pl-us.testnet.drand.sh/", + "/dnsaddr/pl-sin.testnet.drand.sh/", + } + return addrutil.ParseAddresses(context.TODO(), addrs) +} diff --git a/node/builder.go b/node/builder.go index cf772746d..f503bff5c 100644 --- a/node/builder.go +++ b/node/builder.go @@ -218,6 +218,7 @@ func Online() Option { // TODO: Fix offline mode Override(new(dtypes.BootstrapPeers), modules.BuiltinBootstrap), + Override(new(dtypes.DrandBootstrap), modules.DrandBootstrap), Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages), diff --git a/node/modules/core.go b/node/modules/core.go index 6521b60df..ca9872d90 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -89,3 +89,7 @@ func ConfigBootstrap(peers []string) func() (dtypes.BootstrapPeers, error) { func BuiltinBootstrap() (dtypes.BootstrapPeers, error) { return build.BuiltinBootstrap() } + +func DrandBootstrap() (dtypes.DrandBootstrap, error) { + return build.DrandBootstrap() +} diff --git a/node/modules/dtypes/bootstrap.go b/node/modules/dtypes/bootstrap.go index 13003f029..96cd2f673 100644 --- a/node/modules/dtypes/bootstrap.go +++ b/node/modules/dtypes/bootstrap.go @@ -3,5 +3,6 @@ package dtypes import "github.com/libp2p/go-libp2p-core/peer" type BootstrapPeers []peer.AddrInfo +type DrandBootstrap []peer.AddrInfo type Bootstrapper bool diff --git a/node/modules/lp2p/pubsub.go b/node/modules/lp2p/pubsub.go index 76387dd1d..bf9d88d42 100644 --- a/node/modules/lp2p/pubsub.go +++ b/node/modules/lp2p/pubsub.go @@ -41,6 +41,7 @@ type GossipIn struct { Host host.Host Nn dtypes.NetworkName Bp dtypes.BootstrapPeers + Db dtypes.DrandBootstrap Cfg *config.Pubsub Sk *dtypes.ScoreKeeper } @@ -61,6 +62,11 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { for _, pi := range in.Bp { bootstrappers[pi.ID] = struct{}{} } + drandBootstrappers := make(map[peer.ID]struct{}) + for _, pi := range in.Db { + drandBootstrappers[pi.ID] = struct{}{} + } + isBootstrapNode := in.Cfg.Bootstrapper drandTopic, err := getDrandTopic() if err != nil { @@ -83,6 +89,11 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { return 2500 } + _, ok = drandBootstrappers[p] + if ok && !isBootstrapNode { + return 1500 + } + // TODO: we want to plug the application specific score to the node itself in order // to provide feedback to the pubsub system based on observed behaviour return 0 From 9d49c6861f7be4a96000d842e1b0eedfd1cf0219 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Mon, 8 Jun 2020 09:51:47 -0700 Subject: [PATCH 083/379] don't update the mining base if mining fails for some reason --- miner/miner.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/miner/miner.go b/miner/miner.go index e906e6e70..f2059ef7f 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -153,13 +153,14 @@ func (m *Miner) mine(ctx context.Context) { m.niceSleep(build.BlockDelay * time.Second) continue } - lastBase = *base b, err := m.mineOne(ctx, base) if err != nil { log.Errorf("mining block failed: %+v", err) + m.niceSleep(time.Second) continue } + lastBase = *base onDone(b != nil) From 751bc45befc9a7f227bc70fd2dcb80fb509de938 Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 8 Jun 2020 12:20:44 -0700 Subject: [PATCH 084/379] display a little inline warning if balance is zero --- cli/wallet.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cli/wallet.go b/cli/wallet.go index f9f749d72..ccca4d23d 100644 --- a/cli/wallet.go +++ b/cli/wallet.go @@ -113,7 +113,12 @@ var walletBalance = &cli.Command{ return err } - fmt.Printf("%s\n", types.FIL(balance)) + if balance.Equals(types.NewInt(0)) { + fmt.Printf("%s (warning: may display 0 if chain sync in progress)\n", types.FIL(balance)) + } else { + fmt.Printf("%s\n", types.FIL(balance)) + } + return nil }, } From 28f895cec2af37d8a34c8ea1671eef0029b4830f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 8 Jun 2020 20:20:58 +0200 Subject: [PATCH 085/379] Update sector-storage with better post faults --- api/apistruct/struct.go | 5 +++++ cmd/lotus-bench/main.go | 4 ++-- go.mod | 4 ++-- go.sum | 6 ++++-- storage/wdpost_run.go | 7 +++++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index c41b6e229..88f23d724 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -218,6 +218,7 @@ type StorageMinerStruct struct { StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"` StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` + StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` @@ -823,6 +824,10 @@ func (c *StorageMinerStruct) StorageLock(ctx context.Context, sector abi.SectorI return c.Internal.StorageLock(ctx, sector, read, write) } +func (c *StorageMinerStruct) StorageTryLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) { + return c.Internal.StorageTryLock(ctx, sector, read, write) +} + func (c *StorageMinerStruct) MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error { return c.Internal.MarketImportDealData(ctx, propcid, path) } diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 5951bd6fa..7f6d0c5de 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -345,7 +345,7 @@ var sealBenchCmd = &cli.Command{ verifyWinningPost2 := time.Now() log.Info("computing window post snark (cold)") - wproof1, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:]) + wproof1, _, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:]) if err != nil { return err } @@ -353,7 +353,7 @@ var sealBenchCmd = &cli.Command{ windowpost1 := time.Now() log.Info("computing window post snark (hot)") - wproof2, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:]) + wproof2, _, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:]) if err != nil { return err } diff --git a/go.mod b/go.mod index 786afed49..39f5bff3d 100644 --- a/go.mod +++ b/go.mod @@ -29,9 +29,9 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f + github.com/filecoin-project/sector-storage v0.0.0-20200608203246-bccaf697129c github.com/filecoin-project/specs-actors v0.5.6 - github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 + github.com/filecoin-project/specs-storage v0.1.0 github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 diff --git a/go.sum b/go.sum index be456d1dd..f86e293ef 100644 --- a/go.sum +++ b/go.sum @@ -219,8 +219,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= -github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f h1:UASwQxRVA9LEfpFhhh87RvZMaPRFfR7QlWXNd9u6Aj0= -github.com/filecoin-project/sector-storage v0.0.0-20200605192746-4b9317d1f08f/go.mod h1:hUQo3z/5B8t8Yl+XgIxBqgNfYtIcCYzKjWWY27dHBCk= +github.com/filecoin-project/sector-storage v0.0.0-20200608203246-bccaf697129c h1:xWl+lxNnPmRhHPvcIM10AJHHhdAEo8lrJjWdd7kpQzA= +github.com/filecoin-project/sector-storage v0.0.0-20200608203246-bccaf697129c/go.mod h1:SfaVNw/A6LwqqEt6wEMVBN5Grn3XC50j+yjmegHIe7Y= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= @@ -231,6 +231,8 @@ github.com/filecoin-project/specs-actors v0.5.6 h1:WlhtoXwFoKlP1b06NI4NJaxC4m9EX github.com/filecoin-project/specs-actors v0.5.6/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= +github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= +github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa h1:kTCIBKMhhhVcjCh1ws72vpdDr4cdZjCyIUDFijuWuvA= github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index ea95245dd..8cd9fdc5f 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -431,8 +431,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo return nil, err } - // TODO: Faults! - postOut, err := s.prover.GenerateWindowPoSt(ctx, abi.ActorID(mid), ssi, abi.PoStRandomness(rand)) + postOut, postSkipped, err := s.prover.GenerateWindowPoSt(ctx, abi.ActorID(mid), ssi, abi.PoStRandomness(rand)) if err != nil { return nil, xerrors.Errorf("running post failed: %w", err) } @@ -441,6 +440,10 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo return nil, xerrors.Errorf("received proofs back from generate window post") } + for _, sector := range postSkipped { + skipped.Set(uint64(sector.Number)) + } + elapsed := time.Since(tsStart) log.Infow("submitting window PoSt", "elapsed", elapsed) From 19013b09e0982dc79e128d7c13e6c13309be40b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 8 Jun 2020 13:11:41 +0200 Subject: [PATCH 086/379] v27 parameters --- build/proof-params/parameters.json | 180 ++++++++++++++--------------- 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/build/proof-params/parameters.json b/build/proof-params/parameters.json index 4ca3e6d2d..b632c17e8 100644 --- a/build/proof-params/parameters.json +++ b/build/proof-params/parameters.json @@ -1,152 +1,152 @@ { - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": { - "cid": "QmYkygifkXnrnsN4MJsjBFHTQJHx294CyikDgDK8nYxdGh", - "digest": "df3f30442a6d6b4192f5071fb17e820c", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": { + "cid": "QmeDRyxek34F1H6xJY6AkFdWvPsy5F6dKTrebV3ZtWT4ky", + "digest": "f5827f2d8801c62c831e0f972f6dc8bb", "sector_size": 2048 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": { - "cid": "QmdXyqbmy2bkJA9Kyhh6z25GrTCq48LwX6c1mxPsm54wi7", - "digest": "0bea3951abf9557a3569f68e52a30c6c", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": { + "cid": "QmUw1ZmG4BBbX19MsbH3zAEGKUc42iFJc5ZAyomDHeJTsA", + "digest": "398fecdb4b2de445125852bc3c080b35", "sector_size": 2048 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": { - "cid": "Qmf5XZZtP5VcYTf65MbKjLVabcS6cYMbr2rFShmfJzh5e5", - "digest": "655e6277638edc8c658094f6f0b33d54", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": { + "cid": "QmUeNKp9YZpiAFm81RV5KuxH1FDGJx2DuwcbU2XNSZLLSv", + "digest": "2b6d2972ac9e862e8134d98fb695b0c5", "sector_size": 536870912 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": { - "cid": "QmPuhdWnAXBks43emnkqi9FQzyU1gASKyz23zrD27BPGs8", - "digest": "57690e3a6a94c3f704802a674b34f36b", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": { + "cid": "QmQaQmTXX995Akd66ggtJY5bNx6Gkxk8P34JTdMMq8393G", + "digest": "3688c9eb256b7b17f411dad78d5ef74a", "sector_size": 536870912 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": { - "cid": "QmPNVgTN7N5vDtD5u7ERMTLcvUtrKRBfYVUDr6uW3pKhX7", - "digest": "3d390654f58e603b896ac70c653f5676", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": { + "cid": "QmfEYTMSkwGJTumQx26iKXGNKiYh3mmAC4SkdybZpJCj5p", + "digest": "09bff16aed893349d94485cfae366a9c", "sector_size": 2048 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": { - "cid": "Qmbj61Zez7v5xA7nSCnmWbyLYznWJDWeusz7Yg8EcgVdoN", - "digest": "8c170a164743c39576a7f47a1b51e6f3", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": { + "cid": "QmP4ThPieSUJyRanjibWpT5R5cCMzMAU4j8Y7kBn7CSW1Q", + "digest": "142f2f7e8f1b1779290315cabfd2c803", "sector_size": 2048 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": { - "cid": "QmRApb8RZoBK3cqicT7V3ydXg8yVvqPFMPrQNXP33aBihp", - "digest": "b1b58ff9a297b82885e8a7dfb035f83c", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": { + "cid": "QmcAixrHsz29DgvtZiMc2kQjvPRvWxYUp36QYmRDZbmREm", + "digest": "8f987f64d434365562180b96ec12e299", "sector_size": 8388608 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": { - "cid": "QmcytF1dTdqMFoyXi931j1RgmGtLfR9LLLaBznRt1tPQyD", - "digest": "1a09e00c641f192f55af3433a028f050", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": { + "cid": "QmT4iFnbL6r4txS5PXsiV7NTzbhCxHy54PvdkJJGV2VFXb", + "digest": "94b6c24ac01924f4feeecedd16b5d77d", "sector_size": 8388608 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": { - "cid": "QmPvr54tWaVeP4WnekivzUAJitTqsQfvikBvAHNEaDNQSw", - "digest": "9380e41368ed4083dbc922b290d3b786", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": { + "cid": "QmbjFst6SFCK1KsTQrfwPdxf3VTNa1raed574tEZZ9PoyQ", + "digest": "2c245fe8179839dd6c6cdea207c67ae8", "sector_size": 8388608 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": { - "cid": "QmXyVLVDRCcxA9SjT7PeK8HFtyxZ2ZH3SHa8KoGLw8VGJt", - "digest": "f0731a7e20f90704bd38fc5d27882f6d", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": { + "cid": "QmQJKmvZN1a5cQ1Nw6CDyXs3nuRPzvyU5NvCFMUL2BfcZC", + "digest": "56ae47bfda53bb8d22981ed8d8d27d72", "sector_size": 8388608 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": { - "cid": "Qmf5f6ko3dqj7qauzXpZqxM9B2x2sL977K6gE2ppNwuJPv", - "digest": "273ebb8c896326b7c292bee8b775fd38", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": { + "cid": "QmQCABxeTpdvXTyjDyk7nPBxkQzCh7MXfGztWnSXEPKMLW", + "digest": "7e6b2eb5ecbb11ac651ad66ebbb2075a", "sector_size": 536870912 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": { - "cid": "QmfP3MQe8koW63n5MkDENENVHxib78MJYYyZvbneCsuze8", - "digest": "3dd94da9da64e51b3445bc528d84e76d", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": { + "cid": "QmPBweyugh5Sx4umk8ULhgEGbjY8xmWLfU6M7EMpc8Mad6", + "digest": "94a8d9e25a9ab9674d339833664eba25", "sector_size": 536870912 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": { - "cid": "QmYEeeCE8uT2bsVkxcqqUYeMmMEbe6rfmo8wQCv7jFHqqm", - "digest": "c947f2021304ed43b7216f7a8436e294", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": { + "cid": "QmY5yax1E9KymBnCeHksE9Zi8NieZbmwcpoDGoabkeeb9h", + "digest": "c909ea9e3fe25ab9b391a64593afdbba", "sector_size": 34359738368 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": { - "cid": "QmXB63ExriFjB4ywWnXTnFwCcLFfCeEP3h15qtL5i7F4aX", - "digest": "ab20d7b253e7e9a0d2ccdf7599ec8ec3", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": { + "cid": "QmXnPo4yH5mwMguwrvqgRfduSttbmPrXtbBfbwU21wQWHt", + "digest": "caf900461e988bbf86dbcaca087b7864", "sector_size": 34359738368 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": { - "cid": "QmW5Yxg3L1NSzuQVcRMHMbG3uvVoi4dTLzVaDpnEUPQpnA", - "digest": "079ba19645828ae42b22b0e3f4866e8d", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": { + "cid": "QmZtzzPWwmZEgR7MSMvXRbt9KVK8k4XZ5RLWHybHJW9SdE", + "digest": "a2844f0703f186d143a06146a04577d8", "sector_size": 34359738368 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": { - "cid": "QmQzZ5dJ11tcSBees38WX41tZLXS9BqpEti253m5QcnTNs", - "digest": "c76125a50a7de315165de359b5174ae4", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": { + "cid": "QmWxEA7EdQCUJTzjNpxg5XTF45D2uVyYnN1QRUb5TRYU8M", + "digest": "2306247a1e616dbe07f01b88196c2044", "sector_size": 34359738368 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": { - "cid": "QmNk3wga1tS53FUu1QnkK8ehWA2cqpCnSEAPv3KLxdJxNa", - "digest": "421e4790c0b80e0107a7ff67acf14084", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": { + "cid": "QmP676KwuvyF9Y64uJnXvLtvD1xcuWQ6wD23RzYtQ6dd4f", + "digest": "215b1c667a4f46a1d0178338df568615", "sector_size": 68719476736 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": { - "cid": "QmVQCHGsrUtbn9RjHs1e6GXfeXDW5m9w4ge48PSX3Z2as2", - "digest": "8b60e9cc1470a6729c687d6cf0a1f79c", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": { + "cid": "QmPvPwbJtcSGyqB1rQJhSF5yvFbX9ZBSsHVej5F8JUyHUJ", + "digest": "0c9c423b28b1455fcbc329a1045fd4dd", "sector_size": 68719476736 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": { - "cid": "QmTL3VvydaMFWKvE5VzxjgKsJYgL9JMM4JVYNtQxdj9JK1", - "digest": "2685f31124b22ea6b2857e5a5e87ffa3", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": { + "cid": "QmUxPQfvckzm1t6MFRdDZ1fDK5UJzAjK7pTZ97cwyachdr", + "digest": "965132f51ae445b0e6d32692b7561995", "sector_size": 68719476736 }, - "v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": { - "cid": "QmSVWbLqQYbUbbJyfsRMzEib2rfSqMtnPks1Nw22omcBQm", - "digest": "efe703cd2839597c7ca5c2a906b74296", + "v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": { + "cid": "QmTxq2EBnQWb5R8tS4MHdchj4vNfLYGoSXxwJFvs5xgW4K", + "digest": "fc8c3d26e0e56373ad96cb41520d55a6", "sector_size": 68719476736 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": { - "cid": "QmU9dH31nZZUJnsogR4Ld4ySUcH6wm2RgmGiujwnqtbU6k", - "digest": "fcef8e87ae2afd7a28aae44347b804cf", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": { + "cid": "QmRjgZHERgqGoRagR788Kh6ybi26csVYa8mqbqhmZm57Jx", + "digest": "cfc7b0897d1eee48c586f7beb89e67f7", "sector_size": 2048 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": { - "cid": "QmdJ15DMGPooye5NaPcRfXUdHUDibcN7hKjbmTGuu1K4AQ", - "digest": "2ee2b3518229680db15161d4f582af37", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": { + "cid": "QmNjvnvFP7KgovHUddULoB19fBHT81iz7NcUbzEHZUUPsm", + "digest": "fb59bd061c987eac7068008c44de346b", "sector_size": 2048 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": { - "cid": "QmZgtxcY3tMXXQxZTA7ZTUDXLVUnfxNcerXgeW4gG2NnfP", - "digest": "3273c7135cb75684248b475781b738ee", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": { + "cid": "QmTpRPBA4dt8fgGpcVzi4L1KA1U2eBHCE8WVmS2GUygMvT", + "digest": "36d465915b0afbf96bd08e7915e00952", "sector_size": 536870912 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": { - "cid": "QmSS6ZkAV2aGZcgKgdPpEEgihXF1ryZX8PSAZDWSoeL1d4", - "digest": "1519b5f61d9044a59f2bdc57537c094b", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": { + "cid": "QmRzDyVfQCLsxspoVsed5bcQRsG6KiktngJfcNBL3TJPZe", + "digest": "99d16df0eb6a7e227a4f4570c4f6b6f1", "sector_size": 536870912 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": { - "cid": "QmQBGXeiNn6hVwbR6qFarQqiNGDdKk4h9ucfyvcXyfYz2N", - "digest": "7d5f896f435c38e93bcda6dd168d860b", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": { + "cid": "QmV8ZjTSGzDUWmFvsq9NSyPBR7eDDUcvCPNgj2yE7HMAFu", + "digest": "34f3ddf1d1c9f41c0cd73b91e8b4bc27", "sector_size": 8388608 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": { - "cid": "QmPrZgBVGMckEAeu5eSJnLmiAwcPQjKjZe5ir6VaQ5AxKs", - "digest": "fe6d2de44580a0db5a4934688899b92f", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": { + "cid": "QmTa3VbjTiqJWU6r4WKayaQrUaaBsrpp5UDqYvPDd2C5hs", + "digest": "ec62d59651daa5631d3d1e9c782dd940", "sector_size": 8388608 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": { - "cid": "QmZL2cq45XJn5BFzagAZwgFmLrcM1W6CXoiEF9C5j5tjEF", - "digest": "acdfed9f0512bc85a01a9fb871d475d5", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": { + "cid": "Qmf8ngfArxrv9tFWDqBcNegdBMymvuakwyHKd1pbW3pbsb", + "digest": "a16d6f4c6424fb280236739f84b24f97", "sector_size": 34359738368 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": { - "cid": "QmQ4zB7nNa1tDYNifBkExRnZtwtxZw775iaqvVsZyRi6Q2", - "digest": "524a2f3e9d6826593caebc41bb545c40", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": { + "cid": "QmfQgVFerArJ6Jupwyc9tKjLD9n1J9ajLHBdpY465tRM7M", + "digest": "7a139d82b8a02e35279d657e197f5c1f", "sector_size": 34359738368 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": { - "cid": "QmY7DitNKXFeLQt9QoVQkfjM1EvRnprqUVxjmkTXkHDNka", - "digest": "f27271c0537ba65ade2ec045f8fbd069", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": { + "cid": "QmfDha8271nXJn14Aq3qQeghjMBWbs6HNSGa6VuzCVk4TW", + "digest": "5d3cd3f107a3bea8a96d1189efd2965c", "sector_size": 68719476736 }, - "v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": { - "cid": "QmUJsvoCuQ4LszPmeRVAkMYb5qY95ctz3UXKhu8xLzyFKo", - "digest": "576b292938c6c9d0a0e721bd867a543b", + "v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": { + "cid": "QmRVtTtiFzHJTHurYzaCvetGAchux9cktixT4aGHthN6Zt", + "digest": "62c366405404e60f171e661492740b1c", "sector_size": 68719476736 } } \ No newline at end of file From 6e11ff37962d101f5462a4bc5862b27112bc7ac6 Mon Sep 17 00:00:00 2001 From: Jim Pick Date: Mon, 8 Jun 2020 17:03:11 -0700 Subject: [PATCH 087/379] Make libp2p swarm Announce / NoAnnounce addresses configurable In go-ipfs, it is possible to manually configure addresses to announce or not announce to the swarm. https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#addressesannounce This PR adds the same feature to Lotus. It can be configured from the [libp2p] section of either the .lotus or .lotusstorage config.toml file. Example: [Libp2p] ListenAddresses = ["/ip4/0.0.0.0/tcp/34515", "/ip6/::/tcp/34515"] AnnounceAddresses = ["/ip4/52.13.91.110/tcp/34515"] --- documentation/en/setting-a-static-port.md | 14 ++++++++++++++ node/builder.go | 3 +++ node/config/def.go | 10 +++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/documentation/en/setting-a-static-port.md b/documentation/en/setting-a-static-port.md index 43a38daa9..714f455b0 100644 --- a/documentation/en/setting-a-static-port.md +++ b/documentation/en/setting-a-static-port.md @@ -15,6 +15,20 @@ To change the port to `1347`: After changing the port value, restart your **daemon**. +## Announce Addresses + +If the **swarm port** is port-forwarded from another address, it is possible to control what addresses +are announced to the network. + +```sh +[Libp2p] + AnnounceAddresses = ["/ip4//tcp/1347"] +``` + +If non-empty, this array specifies the swarm addresses to announce to the network. If empty, the daemon will announce inferred swarm addresses. + +Similarly, it is possible to set `NoAnnounceAddresses` with an array of addresses to not announce to the network. + ## Ubuntu's Uncomplicated Firewall Open firewall manually: diff --git a/node/builder.go b/node/builder.go index f503bff5c..35ef69bfe 100644 --- a/node/builder.go +++ b/node/builder.go @@ -371,6 +371,9 @@ func ConfigCommon(cfg *config.Common) Option { Override(new(dtypes.BootstrapPeers), modules.ConfigBootstrap(cfg.Libp2p.BootstrapPeers)), ), ), + Override(AddrsFactoryKey, lp2p.AddrsFactory( + cfg.Libp2p.AnnounceAddresses, + cfg.Libp2p.NoAnnounceAddresses)), ) } diff --git a/node/config/def.go b/node/config/def.go index 9ca97bb47..575284b95 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -39,9 +39,11 @@ type API struct { // Libp2p contains configs for libp2p type Libp2p struct { - ListenAddresses []string - BootstrapPeers []string - ProtectedPeers []string + ListenAddresses []string + AnnounceAddresses []string + NoAnnounceAddresses []string + BootstrapPeers []string + ProtectedPeers []string ConnMgrLow uint ConnMgrHigh uint @@ -78,6 +80,8 @@ func defCommon() Common { "/ip4/0.0.0.0/tcp/0", "/ip6/::/tcp/0", }, + AnnounceAddresses: []string{}, + NoAnnounceAddresses: []string{}, ConnMgrLow: 150, ConnMgrHigh: 180, From 093dc907b34af1e57ab44f835a57a84d967277da Mon Sep 17 00:00:00 2001 From: Rob Quist Date: Tue, 9 Jun 2020 20:57:21 +0200 Subject: [PATCH 088/379] Update documentation about Lotus Seal Worker Running the initial command `lotus-seal-worker run` gave an error about `--address` being a required parameter. After setting that to `127.0.0.1:2345` the miner started to freak out and sectors broke as the mining process locked up. It seems like in the mean time the sealing work has already been moved into the `lotus-storage-miner` and thus doesn't need to run alongside the miner. Changed the docs to what I think is correct now - but please check, I could be horribly wrong :) --- documentation/en/mining-lotus-seal-worker.md | 38 ++++---------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/documentation/en/mining-lotus-seal-worker.md b/documentation/en/mining-lotus-seal-worker.md index 3e0240430..da87293a5 100644 --- a/documentation/en/mining-lotus-seal-worker.md +++ b/documentation/en/mining-lotus-seal-worker.md @@ -1,6 +1,6 @@ # Lotus Seal Worker -The **Lotus Seal Worker** is an extra process that can offload heavy processing tasks from your **Lotus Storage Miner**. It can be run on the same machine as your `lotus-storage-miner`, or on another machine communicating over a fast network. +The **Lotus Seal Worker** is an extra process that can offload heavy processing tasks from your **Lotus Storage Miner**. The sealing process automatically runs in the **Lotus Storage Miner** process, but you can use the Seal Worker on another machine communicating over a fast network to free up resources on the machine running the mining process. ## Note: Using the Lotus Seal Worker from China @@ -12,39 +12,13 @@ IPFS_GATEWAY="https://proof-parameters.s3.cn-south-1.jdcloud-oss.com/ipfs/" ## Get Started -Make sure that the `lotus-seal-worker` is installed by running: +Make sure that the `lotus-seal-worker` is compiled and installed by running: ```sh make lotus-seal-worker ``` -## Running Alongside Storage Miner - -You may wish to run the **Lotus Seal Worker** on the same computer as the **Lotus Storage Miner**. This allows you to easily set the process priority of the sealing tasks to be lower than the priority of your more important storage miner process. - -To do this, simply run `lotus-seal-worker run`, and the seal worker will automatically pick up the correct authentication tokens from the `LOTUS_STORAGE_PATH` miner repository. - -To check that the **Lotus Seal Worker** is properly connected to your storage miner, run `lotus-storage-miner info` and check that the remote worker count has increased. - -```sh -why@computer ~/lotus> lotus-storage-miner workers list -Worker 0, host computer - CPU: [ ] 0 core(s) in use - RAM: [|||||||||||||||||| ] 28% 18.1 GiB/62.7 GiB - VMEM: [|||||||||||||||||| ] 28% 18.1 GiB/62.7 GiB - GPU: GeForce RTX 2080, not used -Worker 1, host computer - CPU: [ ] 0 core(s) in use - RAM: [|||||||||||||||||| ] 28% 18.1 GiB/62.7 GiB - VMEM: [|||||||||||||||||| ] 28% 18.1 GiB/62.7 GiB - GPU: GeForce RTX 2080, not used -``` - -## Running Over the Network - -Warning: This setup is a little more complex than running it locally. - -To use an entirely separate computer for sealing tasks, you will want to run the `lotus-seal-worker` on a separate machine, connected to your **Lotus Storage Miner** via the local area network. +## Setting up the Storage Miner First, you will need to ensure your `lotus-storage-miner`'s API is accessible over the network. @@ -62,7 +36,7 @@ To make your node accessible over the local area network, you will need to deter A more permissive and less secure option is to change it to `0.0.0.0`. This will allow anyone who can connect to your computer on that port to access the [API](https://docs.lotu.sh/en+api). They will still need an auth token. -`RemoteListenAddress` must be set to an address which other nodes on your network will be able to reach +`RemoteListenAddress` must be set to an address which other nodes on your network will be able to reach. Next, you will need to [create an authentication token](https://docs.lotu.sh/en+api-scripting-support#generate-a-jwt-46). All Lotus APIs require authentication tokens to ensure your processes are as secure against attackers attempting to make unauthenticated requests to them. @@ -73,9 +47,11 @@ On the machine that will run `lotus-seal-worker`, set the `STORAGE_API_INFO` env Once this is set, run: ```sh -lotus-seal-worker run +lotus-seal-worker run --address 192.168.2.10:2345 ``` +Replace `192.168.2.10:2345` with the proper IP and port. + To check that the **Lotus Seal Worker** is connected to your **Lotus Storage Miner**, run `lotus-storage-miner workers list` and check that the remote worker count has increased. ```sh From 5feea2e0f8fbbdadf2b5afd88171265ef214cd88 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 9 Jun 2020 22:55:56 +0200 Subject: [PATCH 089/379] Update go-log to master It restores line informations in log messages Signed-off-by: Jakub Sztandera --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 786afed49..70a5c839b 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf github.com/ipfs/go-ipld-format v0.2.0 github.com/ipfs/go-log v1.0.4 - github.com/ipfs/go-log/v2 v2.1.1 + github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7 github.com/ipfs/go-merkledag v0.3.1 github.com/ipfs/go-path v0.0.7 github.com/ipfs/go-unixfs v0.2.4 diff --git a/go.sum b/go.sum index be456d1dd..1b6b9f0f0 100644 --- a/go.sum +++ b/go.sum @@ -527,8 +527,8 @@ github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.0/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= -github.com/ipfs/go-log/v2 v2.1.1 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0= -github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7 h1:LtL/rvdfbKSthZGmAAD9o4KKg6HA6Qn8gXCCdgnj7lw= +github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= From 5cf76ba8b3737ce8d6c6ab1c2dd63d75b57cb517 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Mon, 8 Jun 2020 21:03:44 -0400 Subject: [PATCH 090/379] Create an api.MinerInfo that has peerID as a Peer ID --- api/api_full.go | 35 ++++++++++++++++++++++++++++++++++- api/apistruct/struct.go | 4 ++-- cli/state.go | 14 +------------- node/impl/full/state.go | 11 ++++++++--- storage/miner.go | 2 +- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index dca416b94..746e2b166 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -146,7 +146,7 @@ type FullNode interface { StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error) StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error) - StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) + StateMinerInfo(context.Context, address.Address, types.TipSetKey) (MinerInfo, error) StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error) StateMinerFaults(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error) // Returns all non-expired Faults that occur within lookback epochs of the given tipset @@ -299,6 +299,39 @@ type MinerPower struct { TotalPower power.Claim } +type MinerInfo struct { + Owner address.Address // Must be an ID-address. + Worker address.Address // Must be an ID-address. + NewWorker address.Address // Must be an ID-address. + WorkerChangeEpoch abi.ChainEpoch + PeerId peer.ID + Multiaddrs []abi.Multiaddrs + SealProofType abi.RegisteredProof + SectorSize abi.SectorSize + WindowPoStPartitionSectors uint64 +} + +func NewApiMinerInfo(info miner.MinerInfo) MinerInfo { + mi := MinerInfo{ + Owner: info.Owner, + Worker: info.Worker, + NewWorker: address.Undef, + WorkerChangeEpoch: -1, + PeerId: peer.ID(info.PeerId), + Multiaddrs: info.Multiaddrs, + SealProofType: info.SealProofType, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + } + + if info.PendingWorkerKey != nil { + mi.NewWorker = info.PendingWorkerKey.NewWorker + mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt + } + + return mi +} + type QueryOffer struct { Err string diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 88f23d724..31cd6badd 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -125,7 +125,7 @@ type FullNodeStruct struct { StateMinerProvingSet func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) `perm:"read"` StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"` - StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) `perm:"read"` + StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"` StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error) `perm:"read"` StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error) `perm:"read"` StateAllMinerFaults func(context.Context, abi.ChainEpoch, types.TipSetKey) ([]*api.Fault, error) `perm:"read"` @@ -552,7 +552,7 @@ func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address, return c.Internal.StateMinerPower(ctx, a, tsk) } -func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { +func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error) { return c.Internal.StateMinerInfo(ctx, actor, tsk) } diff --git a/cli/state.go b/cli/state.go index c0cfd8eb4..6720ceacd 100644 --- a/cli/state.go +++ b/cli/state.go @@ -145,23 +145,11 @@ var stateMinerInfo = &cli.Command{ return err } - act, err := api.StateGetActor(ctx, addr, ts.Key()) + mi, err := api.StateMinerInfo(ctx, addr, ts.Key()) if err != nil { return err } - aso, err := api.ChainReadObj(ctx, act.Head) - if err != nil { - return err - } - - var mst miner2.State - if err := mst.UnmarshalCBOR(bytes.NewReader(aso)); err != nil { - return err - } - - mi := mst.Info - fmt.Printf("Owner:\t%s\n", mi.Owner) fmt.Printf("Worker:\t%s\n", mi.Worker) fmt.Printf("PeerID:\t%s\n", mi.PeerId) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index c4a9f67fd..fae2a7b67 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -77,12 +77,17 @@ func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Addres return stmgr.GetProvingSetRaw(ctx, a.StateManager, mas) } -func (a *StateAPI) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { +func (a *StateAPI) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { - return miner.MinerInfo{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) + return api.MinerInfo{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return stmgr.StateMinerInfo(ctx, a.StateManager, ts, actor) + + mi, err := stmgr.StateMinerInfo(ctx, a.StateManager, ts, actor) + if err != nil { + return api.MinerInfo{}, err + } + return api.NewApiMinerInfo(mi), nil } func (a *StateAPI) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) (*miner.Deadlines, error) { diff --git a/storage/miner.go b/storage/miner.go index 117c91a57..171c166aa 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -51,7 +51,7 @@ type storageMinerApi interface { StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) - StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) + StateMinerInfo(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) // TODO: removeme eventually From 1ccad2222752aa7cf4b7ee6fcf520a5da32d64db Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 9 Jun 2020 19:08:43 -0400 Subject: [PATCH 091/379] Move api.MinerInfo to api/types --- api/api_full.go | 33 --------------------------------- api/types.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 746e2b166..63d9a5e5d 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -299,39 +299,6 @@ type MinerPower struct { TotalPower power.Claim } -type MinerInfo struct { - Owner address.Address // Must be an ID-address. - Worker address.Address // Must be an ID-address. - NewWorker address.Address // Must be an ID-address. - WorkerChangeEpoch abi.ChainEpoch - PeerId peer.ID - Multiaddrs []abi.Multiaddrs - SealProofType abi.RegisteredProof - SectorSize abi.SectorSize - WindowPoStPartitionSectors uint64 -} - -func NewApiMinerInfo(info miner.MinerInfo) MinerInfo { - mi := MinerInfo{ - Owner: info.Owner, - Worker: info.Worker, - NewWorker: address.Undef, - WorkerChangeEpoch: -1, - PeerId: peer.ID(info.PeerId), - Multiaddrs: info.Multiaddrs, - SealProofType: info.SealProofType, - SectorSize: info.SectorSize, - WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, - } - - if info.PendingWorkerKey != nil { - mi.NewWorker = info.PendingWorkerKey.NewWorker - mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt - } - - return mi -} - type QueryOffer struct { Err string diff --git a/api/types.go b/api/types.go index fcc013441..f5a595353 100644 --- a/api/types.go +++ b/api/types.go @@ -2,6 +2,9 @@ package api import ( "encoding/json" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/libp2p/go-libp2p-core/peer" ma "github.com/multiformats/go-multiaddr" @@ -39,3 +42,36 @@ type PubsubScore struct { ID peer.ID Score float64 } + +type MinerInfo struct { + Owner address.Address // Must be an ID-address. + Worker address.Address // Must be an ID-address. + NewWorker address.Address // Must be an ID-address. + WorkerChangeEpoch abi.ChainEpoch + PeerId peer.ID + Multiaddrs []abi.Multiaddrs + SealProofType abi.RegisteredProof + SectorSize abi.SectorSize + WindowPoStPartitionSectors uint64 +} + +func NewApiMinerInfo(info miner.MinerInfo) MinerInfo { + mi := MinerInfo{ + Owner: info.Owner, + Worker: info.Worker, + NewWorker: address.Undef, + WorkerChangeEpoch: -1, + PeerId: peer.ID(info.PeerId), + Multiaddrs: info.Multiaddrs, + SealProofType: info.SealProofType, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + } + + if info.PendingWorkerKey != nil { + mi.NewWorker = info.PendingWorkerKey.NewWorker + mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt + } + + return mi +} From a00df0da900980891117107adb5a2a48fec3d45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 8 Jun 2020 23:25:49 +0200 Subject: [PATCH 092/379] FFI v27 --- cmd/lotus-bench/main.go | 4 ++-- extern/filecoin-ffi | 2 +- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 7f6d0c5de..41af08352 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -412,7 +412,7 @@ var sealBenchCmd = &cli.Command{ fmt.Println(string(data)) } else { - fmt.Printf("----\nresults (v26) (%d)\n", sectorSize) + fmt.Printf("----\nresults (v27) (%d)\n", sectorSize) if robench == "" { fmt.Printf("seal: addPiece: %s (%s)\n", bo.SealingResults[0].AddPiece, bps(bo.SectorSize, bo.SealingResults[0].AddPiece)) // TODO: average across multiple sealings fmt.Printf("seal: preCommit phase 1: %s (%s)\n", bo.SealingResults[0].PreCommit1, bps(bo.SectorSize, bo.SealingResults[0].PreCommit1)) @@ -569,7 +569,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid } } - err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.UnpaddedPieceSize(sectorSize), ticket, cids.Unsealed) + err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed) if err != nil { return nil, nil, err } diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 6109b6ad2..61c02f6be 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 6109b6ad2fa9968941c206161dd01ac059011d4e +Subproject commit 61c02f6bea8d69bb79c70daa1d62f26c486643aa diff --git a/go.mod b/go.mod index 39f5bff3d..03122bb73 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200608203246-bccaf697129c + github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d github.com/filecoin-project/specs-actors v0.5.6 github.com/filecoin-project/specs-storage v0.1.0 github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa diff --git a/go.sum b/go.sum index f86e293ef..99285c5c8 100644 --- a/go.sum +++ b/go.sum @@ -219,8 +219,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= -github.com/filecoin-project/sector-storage v0.0.0-20200608203246-bccaf697129c h1:xWl+lxNnPmRhHPvcIM10AJHHhdAEo8lrJjWdd7kpQzA= -github.com/filecoin-project/sector-storage v0.0.0-20200608203246-bccaf697129c/go.mod h1:SfaVNw/A6LwqqEt6wEMVBN5Grn3XC50j+yjmegHIe7Y= +github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d h1:q7KC8/yIirwVX7JCLgjEmo5LX77V8tYV0EzVCnCwrE8= +github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d/go.mod h1:SfaVNw/A6LwqqEt6wEMVBN5Grn3XC50j+yjmegHIe7Y= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= From d4b230c1372193902ea33318bd9538479b9ef15f Mon Sep 17 00:00:00 2001 From: Rob Quist Date: Wed, 10 Jun 2020 10:24:38 +0200 Subject: [PATCH 093/379] Update Ubuntu installation documentation + bump required go version to 1.14 --- documentation/en/install-lotus-ubuntu.md | 32 +++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/documentation/en/install-lotus-ubuntu.md b/documentation/en/install-lotus-ubuntu.md index 236033794..b458113b3 100644 --- a/documentation/en/install-lotus-ubuntu.md +++ b/documentation/en/install-lotus-ubuntu.md @@ -2,7 +2,7 @@ These steps will install the following dependencies: -- go (1.13 or higher) +- go (1.14 or higher) - gcc (7.4.0 or higher) - git (version 2 or higher) - bzr (some go dependency needs this) @@ -15,29 +15,28 @@ These steps will install the following dependencies: - llvm (proofs build) - clang (proofs build) -Run - -```sh -sudo apt update -sudo apt install mesa-opencl-icd ocl-icd-opencl-dev -``` - -Build +Install dependencies ```sh sudo add-apt-repository ppa:longsleep/golang-backports sudo apt update -sudo apt install golang-go gcc git bzr jq pkg-config mesa-opencl-icd ocl-icd-opencl-dev +sudo apt install mesa-opencl-icd ocl-icd-opencl-dev gcc git bzr jq pkg-config golang-go ``` -Clone +Install Rust +_(this is an interactive installer)_ +```sh +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +Clone the Lotus repository ```sh git clone https://github.com/filecoin-project/lotus.git cd lotus/ ``` -Install +Build the Lotus binaries from source and install ```sh make clean && make all @@ -45,3 +44,12 @@ sudo make install ``` After installing Lotus, you can run the `lotus` command directly from your CLI to see usage documentation. Next, you can join the [Lotus Testnet](https://docs.lotu.sh/en+join-testnet). + +### Interopnet + +If you seek a smaller network to test, you can join the `interopnet`. Please note that this network is meant for developers - it resets much more often, and is much smaller. To join this network, checkout the branch `interopnet` instead of `master` before building and installing; +``` +git checkout interopnet +``` + +Please also note that this documentation (if viewed on the website) might not be up to date with the interopnet. For the latest documentation on the interopnet branch, see the [Lotus Documentation Interopnet Branch on GitHub](https://github.com/filecoin-project/lotus/tree/interopnet/documentation/en) From 159a1a4645afce1ba6aaa8da58b8a4abdf25a6c2 Mon Sep 17 00:00:00 2001 From: RobQuistNL Date: Wed, 10 Jun 2020 10:29:57 +0200 Subject: [PATCH 094/379] Update other docs + bump go.mod version --- documentation/en/install-lotus-arch.md | 2 +- documentation/en/install-lotus-fedora.md | 2 +- go.mod | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/en/install-lotus-arch.md b/documentation/en/install-lotus-arch.md index 4927d063b..e5131424b 100644 --- a/documentation/en/install-lotus-arch.md +++ b/documentation/en/install-lotus-arch.md @@ -2,7 +2,7 @@ These steps will install the following dependencies: -- go (1.13 or higher) +- go (1.14 or higher) - gcc (7.4.0 or higher) - git (version 2 or higher) - bzr (some go dependency needs this) diff --git a/documentation/en/install-lotus-fedora.md b/documentation/en/install-lotus-fedora.md index 9f5864496..8473ef88b 100644 --- a/documentation/en/install-lotus-fedora.md +++ b/documentation/en/install-lotus-fedora.md @@ -6,7 +6,7 @@ These steps will install the following dependencies: -- go (1.13 or higher) +- go (1.14 or higher) - gcc (7.4.0 or higher) - git (version 2 or higher) - bzr (some go dependency needs this) diff --git a/go.mod b/go.mod index 21fea095f..e44543c87 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/filecoin-project/lotus -go 1.13 +go 1.14 require ( contrib.go.opencensus.io/exporter/jaeger v0.1.0 From 6d06bfb452a6be9393340fd6904a4f4057efc59c Mon Sep 17 00:00:00 2001 From: RobQuistNL Date: Wed, 10 Jun 2020 11:41:58 +0200 Subject: [PATCH 095/379] Update documentation --- documentation/en/hardware-mining.md | 2 ++ documentation/en/mining-lotus-seal-worker.md | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/documentation/en/hardware-mining.md b/documentation/en/hardware-mining.md index 16bffaf9c..5578f7d62 100644 --- a/documentation/en/hardware-mining.md +++ b/documentation/en/hardware-mining.md @@ -16,6 +16,8 @@ The setup below is a minimal example for sealing 32 GiB sectors on Lotus: Note that 1GB sectors don't require as high of specs, but are likely to be removed as we improve the performance of 32GB sector sealing. +AMD CPU's are **highly recommended**, because of the `Intel SHA Extensions` instruction set that is available there since the `Zen` microarchitecture. Hence, AMD CPU's seem to perform much better on the testnet than other CPU's. Contrary to what the name implies, this extended instruction set is not available on recent Intel desktop/server chips. + ## Testnet discoveries - If you only have 128GiB of ram, enabling 256GB of **NVMe** swap on an SSD will help you avoid out-of-memory issues while mining. diff --git a/documentation/en/mining-lotus-seal-worker.md b/documentation/en/mining-lotus-seal-worker.md index da87293a5..6cd7b2c7a 100644 --- a/documentation/en/mining-lotus-seal-worker.md +++ b/documentation/en/mining-lotus-seal-worker.md @@ -68,3 +68,14 @@ Worker 1, host othercomputer VMEM: [|||||||||||||| ] 23% 14 GiB/62.7 GiB GPU: GeForce RTX 2080, not used ``` + +### Running locally for manually managing process priority + +You can also run the **Lotus Seal Worker** on the same machine as your **Lotus Storage Miner**, so you can manually manage the process priority. +To do so you have to first **disable all seal task types** in the miner config. This is important to prevent conflicts between the two processes. + +You can then run the storage miner on your local-loopback interface; + +```sh +lotus-seal-worker run --address 127.0.0.1:2345 +``` \ No newline at end of file From af4c4d4f1f96a7c4dba01522a50222632856a476 Mon Sep 17 00:00:00 2001 From: RobQuistNL Date: Wed, 10 Jun 2020 11:44:35 +0200 Subject: [PATCH 096/379] Prevent words from being marked as glossary links --- documentation/en/hardware-mining.md | 2 +- documentation/en/mining-lotus-seal-worker.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/en/hardware-mining.md b/documentation/en/hardware-mining.md index 5578f7d62..a7c410184 100644 --- a/documentation/en/hardware-mining.md +++ b/documentation/en/hardware-mining.md @@ -16,7 +16,7 @@ The setup below is a minimal example for sealing 32 GiB sectors on Lotus: Note that 1GB sectors don't require as high of specs, but are likely to be removed as we improve the performance of 32GB sector sealing. -AMD CPU's are **highly recommended**, because of the `Intel SHA Extensions` instruction set that is available there since the `Zen` microarchitecture. Hence, AMD CPU's seem to perform much better on the testnet than other CPU's. Contrary to what the name implies, this extended instruction set is not available on recent Intel desktop/server chips. +AMD CPU's are __highly recommended__, because of the `Intel SHA Extensions` instruction set that is available there since the `Zen` microarchitecture. Hence, AMD CPU's seem to perform much better on the testnet than other CPU's. Contrary to what the name implies, this extended instruction set is not available on recent Intel desktop/server chips. ## Testnet discoveries diff --git a/documentation/en/mining-lotus-seal-worker.md b/documentation/en/mining-lotus-seal-worker.md index 6cd7b2c7a..aba115661 100644 --- a/documentation/en/mining-lotus-seal-worker.md +++ b/documentation/en/mining-lotus-seal-worker.md @@ -72,7 +72,7 @@ Worker 1, host othercomputer ### Running locally for manually managing process priority You can also run the **Lotus Seal Worker** on the same machine as your **Lotus Storage Miner**, so you can manually manage the process priority. -To do so you have to first **disable all seal task types** in the miner config. This is important to prevent conflicts between the two processes. +To do so you have to first __disable all seal task types__ in the miner config. This is important to prevent conflicts between the two processes. You can then run the storage miner on your local-loopback interface; From e2d2af3afadb16756347541b7389a229a5f960bc Mon Sep 17 00:00:00 2001 From: waynewyang Date: Wed, 10 Jun 2020 20:34:04 +0800 Subject: [PATCH 097/379] error check --- cli/chain.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/chain.go b/cli/chain.go index 9d6856dd2..0bf7741cb 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -883,6 +883,9 @@ var slashConsensusFault = &cli.Command{ BlockHeader1: bh1, BlockHeader2: bh2, }) + if err != nil { + return err + } if cctx.String("miner") == "" { return xerrors.Errorf("--miner flag is required") From 68959582b9b78cbd4973e3b5284b8e85c0e0eb1b Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Thu, 11 Jun 2020 00:09:48 +0200 Subject: [PATCH 098/379] docs: add a note about open files limit --- documentation/en/join-testnet.md | 2 ++ documentation/en/setup-troubleshooting.md | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/documentation/en/join-testnet.md b/documentation/en/join-testnet.md index bdd1b4a56..d01d7eafa 100644 --- a/documentation/en/join-testnet.md +++ b/documentation/en/join-testnet.md @@ -28,6 +28,8 @@ lotus net peers | wc -l In order to connect to the network, you need to be connected to at least 1 peer. If you’re seeing 0 peers, read our [troubleshooting notes](https://docs.lotu.sh/en+setup-troubleshooting). +Make sure that you have a reasonable "open files limit" set on your machine, such as 10000. If you're seeing a lower value, such as 256 (default on macOS), read our [troubleshooting notes](https://docs.lotu.sh/en+setup-troubleshooting) on how to update it prior to starting the Lotus daemon. + ## Chain sync While the daemon is running, the next requirement is to sync the chain. Run the command below to view the chain sync progress. To see current chain height, visit the [network stats page](https://stats.testnet.filecoin.io/). diff --git a/documentation/en/setup-troubleshooting.md b/documentation/en/setup-troubleshooting.md index 055a9c501..8a23544d9 100644 --- a/documentation/en/setup-troubleshooting.md +++ b/documentation/en/setup-troubleshooting.md @@ -29,4 +29,18 @@ ERROR hello hello/hello.go:81 other peer has different genesis! - repo is already locked ``` -- You already have another lotus daemon running. \ No newline at end of file +- You already have another lotus daemon running. + +## Config: Open files limit + +On most systems you can check the open files limit with: + +```sh +ulimit -n +``` + +You can also modify this number by using the `ulimit` command. It gives you the ability to control the resources available for the shell or process started by it. If the number is below 10000, you can change it with the following command prior to starting the Lotus daemon: + +```sh +ulimit -n 10000 +``` From 295c0861c408faef2832f754006fc922c9bc7fd4 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 10 Jun 2020 22:15:46 -0700 Subject: [PATCH 099/379] fix chain index seeking through long ranges of null rounds --- chain/store/index.go | 12 +++++-- chain/store/index_test.go | 76 +++++++++++++++++++++++++++++++++++++++ chain/types/mock/chain.go | 7 +++- 3 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 chain/store/index_test.go diff --git a/chain/store/index.go b/chain/store/index.go index 15d5d7025..8747c79c6 100644 --- a/chain/store/index.go +++ b/chain/store/index.go @@ -97,9 +97,15 @@ func (ci *ChainIndex) fillCache(tsk types.TipSetKey) (*lbEntry, error) { rheight -= ci.skipLength - skipTarget, err := ci.walkBack(parent, rheight) - if err != nil { - return nil, err + var skipTarget *types.TipSet + if parent.Height() < rheight { + skipTarget = parent + + } else { + skipTarget, err = ci.walkBack(parent, rheight) + if err != nil { + return nil, xerrors.Errorf("fillCache walkback: %w", err) + } } lbe := &lbEntry{ diff --git a/chain/store/index_test.go b/chain/store/index_test.go new file mode 100644 index 000000000..6b97a8614 --- /dev/null +++ b/chain/store/index_test.go @@ -0,0 +1,76 @@ +package store_test + +import ( + "bytes" + "context" + "testing" + + "github.com/filecoin-project/lotus/chain/gen" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types/mock" + "github.com/filecoin-project/specs-actors/actors/abi" + datastore "github.com/ipfs/go-datastore" + syncds "github.com/ipfs/go-datastore/sync" + blockstore "github.com/ipfs/go-ipfs-blockstore" + "github.com/stretchr/testify/assert" +) + +func TestIndexSeeks(t *testing.T) { + cg, err := gen.NewGenerator() + if err != nil { + t.Fatal(err) + } + + gencar, err := cg.GenesisCar() + if err != nil { + t.Fatal(err) + } + + gen := cg.Genesis() + + ctx := context.TODO() + + nbs := blockstore.NewBlockstore(syncds.MutexWrap(datastore.NewMapDatastore())) + cs := store.NewChainStore(nbs, syncds.MutexWrap(datastore.NewMapDatastore()), nil) + + _, err = cs.Import(bytes.NewReader(gencar)) + if err != nil { + t.Fatal(err) + } + + cur := mock.TipSet(gen) + if err := cs.PutTipSet(ctx, mock.TipSet(gen)); err != nil { + t.Fatal(err) + } + cs.SetGenesis(gen) + + for i := 0; i < 100; i++ { + nextts := mock.TipSet(mock.MkBlock(cur, 1, 1)) + + if err := cs.PutTipSet(ctx, nextts); err != nil { + t.Fatal(err) + } + cur = nextts + } + + skip := mock.MkBlock(cur, 1, 1) + skip.Height += 50 + + skipts := mock.TipSet(skip) + + if err := cs.PutTipSet(ctx, skipts); err != nil { + t.Fatal(err) + } + + ts, err := cs.GetTipsetByHeight(ctx, skip.Height-10, skipts, false) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, abi.ChainEpoch(151), ts.Height()) + + ts2, err := cs.GetTipsetByHeight(ctx, 90, skipts, false) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, abi.ChainEpoch(90), ts2.Height()) +} diff --git a/chain/types/mock/chain.go b/chain/types/mock/chain.go index 5154ab115..00d0eecc9 100644 --- a/chain/types/mock/chain.go +++ b/chain/types/mock/chain.go @@ -49,6 +49,11 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types panic(err) } + pstateRoot := c + if parents != nil { + pstateRoot = parents.Blocks()[0].ParentStateRoot + } + var pcids []cid.Cid var height abi.ChainEpoch weight := types.NewInt(weightInc) @@ -72,7 +77,7 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types ParentWeight: weight, Messages: c, Height: height, - ParentStateRoot: c, + ParentStateRoot: pstateRoot, BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")}, } } From 1aff04faab5826d1256889335ba627085dbcf03e Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 10 Jun 2020 22:17:29 -0700 Subject: [PATCH 100/379] test a few more cases --- chain/store/index_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/chain/store/index_test.go b/chain/store/index_test.go index 6b97a8614..b1a85996f 100644 --- a/chain/store/index_test.go +++ b/chain/store/index_test.go @@ -68,9 +68,11 @@ func TestIndexSeeks(t *testing.T) { } assert.Equal(t, abi.ChainEpoch(151), ts.Height()) - ts2, err := cs.GetTipsetByHeight(ctx, 90, skipts, false) - if err != nil { - t.Fatal(err) + for i := 0; i <= 100; i++ { + ts3, err := cs.GetTipsetByHeight(ctx, abi.ChainEpoch(i), skipts, false) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, abi.ChainEpoch(i), ts3.Height()) } - assert.Equal(t, abi.ChainEpoch(90), ts2.Height()) } From e0a8e993bc9667187e2f5dd9b043aa2ea57fb4b2 Mon Sep 17 00:00:00 2001 From: yaohcn Date: Thu, 11 Jun 2020 16:35:46 +0800 Subject: [PATCH 101/379] bench prove nedd miner-addr flag --- cmd/lotus-bench/main.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 41af08352..7d7991636 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -598,6 +598,11 @@ var proveCmd = &cli.Command{ Name: "no-gpu", Usage: "disable gpu usage for the benchmark run", }, + &cli.StringFlag{ + Name: "miner-addr", + Usage: "pass miner address (only necessary if using existing sectorbuilder)", + Value: "t01000", + }, }, Action: func(c *cli.Context) error { if c.Bool("no-gpu") { @@ -659,7 +664,7 @@ var proveCmd = &cli.Command{ fmt.Printf("proof: %x\n", proof) - fmt.Printf("----\nresults (v23) (%d)\n", c2in.SectorSize) + fmt.Printf("----\nresults (v27) (%d)\n", c2in.SectorSize) dur := sealCommit2.Sub(start) fmt.Printf("seal: commit phase 2: %s (%s)\n", dur, bps(abi.SectorSize(c2in.SectorSize), dur)) From 2cd6347a134f0364de3a547360fb26e42ef3bbd7 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 4 Jun 2020 18:18:14 -0400 Subject: [PATCH 102/379] Express block validation, cpu/mem usage via OpenCensus --- chain/sync.go | 9 +++++++++ cmd/lotus/daemon.go | 8 ++++++++ metrics/metrics.go | 26 ++++++++++++++++---------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/chain/sync.go b/chain/sync.go index f8a73356f..960ee1ea1 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -528,8 +528,17 @@ func blockSanityChecks(h *types.BlockHeader) error { // ValidateBlock should match up with 'Semantical Validation' in validation.md in the spec func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { + validationStart := time.Now() + defer func() { + dur := time.Since(validationStart) + durMilli := dur.Seconds() * float64(1000) + stats.Record(ctx, metrics.BlockValidationDurationMilliseconds.M(durMilli)) + log.Infow("block validation", "took", dur, "height", b.Header.Height) + }() + ctx, span := trace.StartSpan(ctx, "validateBlock") defer span.End() + if build.InsecurePoStValidation { log.Warn("insecure test validation is enabled, if you see this outside of a test, it is a severe bug!") } diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index fd9ceea85..912e65253 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -19,6 +19,7 @@ import ( "github.com/mitchellh/go-homedir" "github.com/multiformats/go-multiaddr" "github.com/urfave/cli/v2" + "go.opencensus.io/plugin/runmetrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" @@ -114,6 +115,13 @@ var DaemonCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { + err := runmetrics.Enable(runmetrics.RunMetricOptions{ + EnableCPU: true, + EnableMemory: true, + }) + if err != nil { + return xerrors.Errorf("enabling runtime metrics: %w", err) + } if prof := cctx.String("pprof"); prof != "" { profile, err := os.Create(prof) if err != nil { diff --git a/metrics/metrics.go b/metrics/metrics.go index 340d57536..0ef63de4f 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -22,16 +22,17 @@ var ( // Measures var ( - LotusInfo = stats.Int64("info", "Arbitrary counter to tag lotus info to", stats.UnitDimensionless) - ChainNodeHeight = stats.Int64("chain/node_height", "Current Height of the node", stats.UnitDimensionless) - ChainNodeWorkerHeight = stats.Int64("chain/node_worker_height", "Current Height of workers on the node", stats.UnitDimensionless) - MessageReceived = stats.Int64("message/received", "Counter for total received messages", stats.UnitDimensionless) - MessageValidationFailure = stats.Int64("message/failure", "Counter for message validation failures", stats.UnitDimensionless) - MessageValidationSuccess = stats.Int64("message/success", "Counter for message validation successes", stats.UnitDimensionless) - BlockReceived = stats.Int64("block/received", "Counter for total received blocks", stats.UnitDimensionless) - BlockValidationFailure = stats.Int64("block/failure", "Counter for block validation failures", stats.UnitDimensionless) - BlockValidationSuccess = stats.Int64("block/success", "Counter for block validation successes", stats.UnitDimensionless) - PeerCount = stats.Int64("peer/count", "Current number of FIL peers", stats.UnitDimensionless) + LotusInfo = stats.Int64("info", "Arbitrary counter to tag lotus info to", stats.UnitDimensionless) + ChainNodeHeight = stats.Int64("chain/node_height", "Current Height of the node", stats.UnitDimensionless) + ChainNodeWorkerHeight = stats.Int64("chain/node_worker_height", "Current Height of workers on the node", stats.UnitDimensionless) + MessageReceived = stats.Int64("message/received", "Counter for total received messages", stats.UnitDimensionless) + MessageValidationFailure = stats.Int64("message/failure", "Counter for message validation failures", stats.UnitDimensionless) + MessageValidationSuccess = stats.Int64("message/success", "Counter for message validation successes", stats.UnitDimensionless) + BlockReceived = stats.Int64("block/received", "Counter for total received blocks", stats.UnitDimensionless) + BlockValidationFailure = stats.Int64("block/failure", "Counter for block validation failures", stats.UnitDimensionless) + BlockValidationSuccess = stats.Int64("block/success", "Counter for block validation successes", stats.UnitDimensionless) + BlockValidationDurationMilliseconds = stats.Float64("block/validation_ms", "Duration for Block Validation in ms", stats.UnitMilliseconds) + PeerCount = stats.Int64("peer/count", "Current number of FIL peers", stats.UnitDimensionless) ) var ( @@ -63,6 +64,10 @@ var ( Measure: BlockValidationSuccess, Aggregation: view.Count(), } + BlockValidationDurationView = &view.View{ + Measure: BlockValidationDurationMilliseconds, + Aggregation: view.Sum(), + } MessageReceivedView = &view.View{ Measure: MessageReceived, Aggregation: view.Count(), @@ -90,6 +95,7 @@ var DefaultViews = append([]*view.View{ BlockReceivedView, BlockValidationFailureView, BlockValidationSuccessView, + BlockValidationDurationView, MessageReceivedView, MessageValidationFailureView, MessageValidationSuccessView, From 512270593b77bd53224c67095762ffc8d565b85f Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 9 Jun 2020 12:49:31 -0700 Subject: [PATCH 103/379] clean up some of the more spammy logs --- chain/store/store.go | 5 ----- chain/sub/incoming.go | 5 +---- chain/sync_manager.go | 2 +- chain/vm/runtime.go | 4 ++-- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/chain/store/store.go b/chain/store/store.go index 8f15b568f..7f552313f 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -18,7 +18,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/metrics" @@ -964,10 +963,6 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t return ts, nil } - if ts.Height()-h > build.ForkLengthThreshold { - log.Warnf("expensive call to GetTipsetByHeight, seeking %d levels", ts.Height()-h) - } - lbts, err := cs.cindex.GetTipsetByHeight(ctx, ts, h) if err != nil { return nil, err diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index 8b5643de7..ba61dc5c5 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -60,8 +60,6 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha src := msg.GetFrom() go func() { - log.Infof("New block over pubsub: %s", blk.Cid()) - start := time.Now() log.Debug("about to fetch messages for block from pubsub") bmsgs, err := s.Bsync.FetchMessagesByCids(context.TODO(), blk.BlsMessages) @@ -145,8 +143,7 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub // track validation time begin := time.Now() defer func() { - end := time.Now() - log.Infof("block validation time: %s", end.Sub(begin)) + log.Debugf("block validation time: %s", time.Since(begin)) }() stats.Record(ctx, metrics.BlockReceived.M(1)) diff --git a/chain/sync_manager.go b/chain/sync_manager.go index e00063961..deb626fda 100644 --- a/chain/sync_manager.go +++ b/chain/sync_manager.go @@ -280,7 +280,7 @@ func (sm *SyncManager) syncScheduler() { } func (sm *SyncManager) scheduleIncoming(ts *types.TipSet) { - log.Info("scheduling incoming tipset sync: ", ts.Cids()) + log.Debug("scheduling incoming tipset sync: ", ts.Cids()) if sm.getBootstrapState() == BSStateSelected { sm.setBootstrapState(BSStateScheduled) sm.syncTargets <- ts diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index d9268afe4..6e425474c 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -139,7 +139,7 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act defer func() { if r := recover(); r != nil { if ar, ok := r.(aerrors.ActorError); ok { - log.Errorf("VM.Call failure: %+v", ar) + log.Warnf("VM.Call failure: %+v", ar) aerr = ar return } @@ -309,7 +309,7 @@ func (rt *Runtime) Context() context.Context { } func (rt *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) { - log.Error("Abortf: ", fmt.Sprintf(msg, args...)) + log.Warnf("Abortf: ", fmt.Sprintf(msg, args...)) panic(aerrors.NewfSkip(2, code, msg, args...)) } From fe60ffb6ff016d7e26f55c76c3bf6c6835a37a16 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 9 Jun 2020 11:04:17 -0700 Subject: [PATCH 104/379] display quantities of bytes in human-readable format - client commP - client local - client find - client query-ask - client list-deals - state sector-size --- cli/chain.go | 3 +-- cli/client.go | 10 +++++----- cli/state.go | 5 ++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/cli/chain.go b/cli/chain.go index d76335263..01714d850 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -12,7 +12,6 @@ import ( "strings" "time" - "github.com/docker/go-units" "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/specs-actors/actors/abi" @@ -230,7 +229,7 @@ var chainStatObjCmd = &cli.Command{ } fmt.Printf("Links: %d\n", stats.Links) - fmt.Printf("Size: %s (%d)\n", units.BytesSize(float64(stats.Size)), stats.Size) + fmt.Printf("Size: %s (%d)\n", types.SizeStr(types.NewInt(stats.Size)), stats.Size) return nil }, } diff --git a/cli/client.go b/cli/client.go index d6b59db53..e512f9bd9 100644 --- a/cli/client.go +++ b/cli/client.go @@ -143,7 +143,7 @@ var clientCommPCmd = &cli.Command{ } fmt.Println("CID: ", encoder.Encode(ret.Root)) - fmt.Println("Piece size: ", ret.Size) + fmt.Println("Piece size: ", types.SizeStr(types.NewInt(uint64(ret.Size)))) return nil }, } @@ -203,7 +203,7 @@ var clientLocalCmd = &cli.Command{ } for _, v := range list { - fmt.Printf("%s %s %d %s\n", encoder.Encode(v.Key), v.FilePath, v.Size, v.Status) + fmt.Printf("%s %s %s %s\n", encoder.Encode(v.Key), v.FilePath, types.SizeStr(types.NewInt(v.Size)), v.Status) } return nil }, @@ -371,7 +371,7 @@ var clientFindCmd = &cli.Command{ fmt.Printf("ERR %s@%s: %s\n", offer.Miner, offer.MinerPeerID, offer.Err) continue } - fmt.Printf("RETRIEVAL %s@%s-%sfil-%db\n", offer.Miner, offer.MinerPeerID, types.FIL(offer.MinPrice), offer.Size) + fmt.Printf("RETRIEVAL %s@%s-%sfil-%s\n", offer.Miner, offer.MinerPeerID, types.FIL(offer.MinPrice), types.SizeStr(types.NewInt(offer.Size))) } return nil @@ -520,7 +520,7 @@ var clientQueryAskCmd = &cli.Command{ fmt.Printf("Ask: %s\n", maddr) fmt.Printf("Price per GiB: %s\n", types.FIL(ask.Ask.Price)) - fmt.Printf("Max Piece size: %d\n", ask.Ask.MaxPieceSize) + fmt.Printf("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.Ask.MaxPieceSize)))) size := cctx.Int64("size") if size == 0 { @@ -597,7 +597,7 @@ var clientListDeals = &cli.Command{ slashed = fmt.Sprintf("Y (epoch %d)", d.OnChainDealState.SlashEpoch) } - fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\t%s\t%d\t%s\t%d\t%s\n", d.LocalDeal.ProposalCid, d.LocalDeal.DealID, d.LocalDeal.Provider, storagemarket.DealStates[d.LocalDeal.State], onChain, slashed, d.LocalDeal.PieceCID, d.LocalDeal.Size, d.LocalDeal.PricePerEpoch, d.LocalDeal.Duration, d.LocalDeal.Message) + fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%s\n", d.LocalDeal.ProposalCid, d.LocalDeal.DealID, d.LocalDeal.Provider, storagemarket.DealStates[d.LocalDeal.State], onChain, slashed, d.LocalDeal.PieceCID, types.SizeStr(types.NewInt(d.LocalDeal.Size)), d.LocalDeal.PricePerEpoch, d.LocalDeal.Duration, d.LocalDeal.Message) } return w.Flush() }, diff --git a/cli/state.go b/cli/state.go index 6720ceacd..b741ddcd1 100644 --- a/cli/state.go +++ b/cli/state.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/docker/go-units" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" "github.com/multiformats/go-multihash" @@ -153,7 +152,7 @@ var stateMinerInfo = &cli.Command{ fmt.Printf("Owner:\t%s\n", mi.Owner) fmt.Printf("Worker:\t%s\n", mi.Worker) fmt.Printf("PeerID:\t%s\n", mi.PeerId) - fmt.Printf("SectorSize:\t%s (%d)\n", units.BytesSize(float64(mi.SectorSize)), mi.SectorSize) + fmt.Printf("SectorSize:\t%s (%d)\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))), mi.SectorSize) return nil }, @@ -707,7 +706,7 @@ var stateSectorSizeCmd = &cli.Command{ return err } - fmt.Printf("%d\n", mi.SectorSize) + fmt.Printf("%s (%d)\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))), mi.SectorSize) return nil }, } From dc112a5a00d3f34c2e671d543fad48d420e9e1e3 Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Tue, 9 Jun 2020 20:17:28 -0300 Subject: [PATCH 105/379] Lotus architecture notes (#1768) Co-authored-by: Aayush Rajasekaran --- chain/sync.go | 2 + chain/sync_manager.go | 1 + documentation/en/.library.json | 6 + documentation/en/architecture.md | 394 ++++++++++++++++++ .../en/dev/WIP-arch-complementary-notes.md | 153 +++++++ 5 files changed, 556 insertions(+) create mode 100644 documentation/en/architecture.md create mode 100644 documentation/en/dev/WIP-arch-complementary-notes.md diff --git a/chain/sync.go b/chain/sync.go index 960ee1ea1..03ccc3ab7 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -429,6 +429,8 @@ func (syncer *Syncer) Sync(ctx context.Context, maybeHead *types.TipSet) error { return xerrors.Errorf("collectChain failed: %w", err) } + // At this point we have accepted and synced to the new `maybeHead` + // (`StageSyncComplete`). if err := syncer.store.PutTipSet(ctx, maybeHead); err != nil { span.AddAttributes(trace.StringAttribute("put_error", err.Error())) span.SetStatus(trace.Status{ diff --git a/chain/sync_manager.go b/chain/sync_manager.go index deb626fda..e3fbdf4e1 100644 --- a/chain/sync_manager.go +++ b/chain/sync_manager.go @@ -35,6 +35,7 @@ type SyncManager struct { syncStates []*SyncerState + // Normally this handler is set to `(*Syncer).Sync()`. doSync func(context.Context, *types.TipSet) error stop chan struct{} diff --git a/documentation/en/.library.json b/documentation/en/.library.json index 018e6189b..f637c813f 100644 --- a/documentation/en/.library.json +++ b/documentation/en/.library.json @@ -71,6 +71,12 @@ ] }, { + "title": "Architecture", + "slug": "en+arch", + "github": "en/architecture.md", + "value": null, + "posts": [] + }, { "title": "Storage Mining", "slug": "en+mining", "github": "en/mining.md", diff --git a/documentation/en/architecture.md b/documentation/en/architecture.md new file mode 100644 index 000000000..970f2a13d --- /dev/null +++ b/documentation/en/architecture.md @@ -0,0 +1,394 @@ +# Lotus + +Lotus is an implementation of the [Filecoin Distributed Storage Network](https://filecoin.io/). +A Lotus node syncs blockchains that follow the +Filecoin protocol, validating the blocks and state transitions. +The specification for the Filecoin protocol can be found [here](https://filecoin-project.github.io/specs/). + +For information on how to setup and operate a Lotus node, +please follow the instructions [here](https://lotu.sh/en+getting-started). + +# Components + +At a high level, a Lotus node comprises the following components: + +FIXME: No mention of block production here, cross-reference with schomatis's miner doc +- The Syncer, which manages the process of syncing the blockchain +- The State Manager, which can compute the state at any given point in the chain +- The Virtual Machine (VM), which executes messages +- The Repository, where all data is stored +- P2P stuff (FIXME missing libp2p listed under other PL dependencies)? allows hello, blocksync, retrieval, storage +- API / CLI (FIXME missing, in scratchpad) +- Other Filecoin dependencies (specs actors, proofs, storage, etc., FIXME missing) +- Is the Builder worth its own component? +- Other PL dependencies (IPFS, libp2p, IPLD? FIXME, missing) +- External libraries used by Lotus and other deps (FIXME, missing) + +# Preliminaries + +We discuss some key Filecoin concepts here, aiming to explain them by contrasting them with analogous concepts +in other well-known blockchains like Ethereum. We only provide brief descriptions here; elaboration +can be found in the [spec](https://filecoin-project.github.io/specs/). + +### Tipsets + +Unlike in Ethereum, a block can have multiple parents in Filecoin. We thus refer to the parent set of a block, +instead of a single parent. +A [tipset](https://filecoin-project.github.io/specs/#systems__filecoin_blockchain__struct__tipset) +is any set of blocks that share the same parent set. + +There is no concept of "block difficulty" in Filecoin. Instead, +the weight of a tipset is simply the number of blocks in the chain that ends in that tipset. Note that a longer chain +can have less weight than a shorter chain with more blocks per tipset. + +We also allow for "null" tipsets, which include zero blocks. This allows miners to "skip" a round, and build on top +of an imaginary empty tipset if they want to. + +We call the heaviest tipset in a chain the "head" of the chain. + +### Actors and Messages + +An [Actor](https://filecoin-project.github.io/specs/#systems__filecoin_vm__actor) + is analogous to a smart contract in Ethereum. Filecoin does not allow users to define their own +actors, but comes with several [builtin actors](https://github.com/filecoin-project/specs-actors), +which can be thought of as pre-compiled contracts. + +A [Message](https://filecoin-project.github.io/specs/#systems__filecoin_vm__message) +is analogous to transactions in Ethereum. + +# Sync + +Sync refers to the process by which a Lotus node synchronizes to the heaviest chain being advertised by its peers. +At a high-level, Lotus syncs in a manner similar to most other blockchains; a Lotus node listens to the various +chains its peers claim to be at, picks the heaviest one, requests the blocks in the chosen chain, +and validates each block in that chain, running all state transitions along the way. + +The majority of the sync functionality happens in the [`Syncer`](https://github.com/filecoin-project/lotus/blob/master/chain/sync.go), +internally managed by a [`SyncManager`](https://github.com/filecoin-project/lotus/blob/master/chain/sync_manager.go). + +We now discuss the various stages of the sync process. + +## Sync setup + +When a Lotus node connects to a new peer, we exchange the head of our chain +with the new peer through [the `hello` protocol](https://github.com/filecoin-project/lotus/blob/master/node/hello/hello.go). +If the peer's head is heavier than ours, we try to sync to it. Note +that we do NOT update our chain head at this stage. + +## Fetching and Persisting Block Headers + +Note: The API refers to these stages as `StageHeaders` and `StagePersistHeaders`. + +We proceed in the sync process by requesting block headers from the peer, +moving back from their head, until we reach a tipset that we have in common +(such a common tipset must exist, thought it may simply be the genesis block). +The functionality can be found in `Syncer::collectHeaders()`. + +If the common tipset is our head, we treat the sync as a "fast-forward", else we must +drop part of our chain to connect to the peer's head (referred to as "forking"). + +FIXME: This next para might be best replaced with a link to the validation doc +Some of the possible causes of failure in this stage include: + +- The chain is linked to a block that we have previously marked as bad, +and stored in a [`BadBlockCache`](https://github.com/filecoin-project/lotus/blob/master/chain/badtscache.go). +- The beacon entries in a block are inconsistent (FIXME: more details about what is validated here wouldn't be bad). +- Switching to this new chain would involve a chain reorganization beyond the allowed threshold (SPECK-CHECK). + +## Fetching and Validating Blocks + +Note: The API refers to this stage as `StageMessages`. + +Having acquired the headers and found a common tipset, we then move forward, requesting the full blocks, including the messages. + +For each block, we first confirm the syntactic validity of the block (SPECK-CHECK), +which includes the syntactic validity of messages included +in the block. +We then apply the messages, running all the state transitions, and compare the state root we calculate with the provided state root. + + +FIXME: This next para might be best replaced with a link to the validation doc +Some of the possible causes of failure in this stage include: + +- a block is syntactically invalid (including potentially containing syntactically invalid messages) +- the computed state root after applying the block doesn't match the block's state root +- FIXME: Check what's covered by syntactic validity, and add anything important that isn't (like proof validity, future checks, etc.) + +The core functionality can be found in `Syncer::ValidateTipset()`, with `Syncer::checkBlockMessages()` performing +syntactic validation of messages. + +## Setting the head + +Note: The API refers to this stage as `StageSyncComplete`. + +If all validations pass we will now set that head as our heaviest tipset in +[`ChainStore`](https://github.com/filecoin-project/lotus/blob/master/chain/store/store.go). +We already have the full state, since we calculated +it during the sync process. + +FIXME (aayush) I don't fuilly understand the next 2 paragraphs, but it seems important. Confirm and polish. +Relevant issue in IPFS: https://github.com/ipfs/ipfs-docs/issues/264 + +It is important to note at this point that similar to the IPFS architecture of addressing by content and not by location/address (FIXME: check and link to IPFS docs) the "actual" chain stored in the node repo is *relative* to which CID we look for. We always have stored a series of Filecoin blocks pointing to other blocks, each a potential chain in itself by following its parent's reference, and its parent's parent, and so on up to the genesis block. (FIXME: We need a diagram here, one of the Filecoin blog entries might have something similar to what we are describing here.) It only depends on *where* (location) do we start to look for. The *only* address/location reference we hold of the chain, a relative reference, is the `heaviest` pointer. This is reflected by the fact that we don't store it in the `Blockstore` by a fixed, *absolute*, CID that reflects its contents, as this will change each time we sync to a new head (FIXME: link to the immutability IPFS doc that I need to write). + +FIXME: Create a further reading appendix, move this next para to it, along with other +extraneous content +This is one of the few items we store in `Datastore` by key, location, allowing its contents to change on every sync. This is reflected in the `(*ChainStore) writeHead()` function (called by `takeHeaviestTipSet()` above) where we reference the pointer by the explicit `chainHeadKey` address (the string `"head"`, not a hash embedded in a CID), and similarly in `(*ChainStore).Load()` when we start the node and create the `ChainStore`. Compare this to a Filecoin block or message which are immutable, stored in the `Blockstore` by CID, once created they never change. + +## Keeping up with the chain + +A Lotus node also listens for new blocks broadcast by its peers over the `gossipsub` channel (see FIXME for more). +If we have validated such a block's parent tipset, and adding it to our tipset at its height would lead to a heavier +head, then we validate and add this block. The validation described is identical to that invoked during the sync +process (indeed, it's the same codepath). + +# State + +In Filecoin, the chain state at any given point is a collection of data stored under a root CID +encapsulated in the [`StateTree`](https://github.com/filecoin-project/lotus/blob/master/chain/state/statetree.go), +and accessed through the +[`StateManager`](https://github.com/filecoin-project/lotus/blob/master/chain/stmgr/stmgr.go). +The state at the chain's head is thus easily tracked and updated in a state root CID. +(FIXME: Talk about CIDs somewhere, we might want to explain some of the modify/flush/update-root mechanism here.)) + +## Calculating a Tipset State + +Recall that a tipset is a set of blocks that have identical parents (that is, that are built on top of the same tipset). +The genesis tipset comprises the genesis block(s), and has some state corresponding to it. + +The methods `TipSetState()` and `computeTipSetState()` in +[`StateManager`](https://github.com/filecoin-project/lotus/blob/master/chain/stmgr/stmgr.go) + are responsible for computing +the state that results from applying a tipset. This involves applying all the messages included +in the tipset, and performing implicit operations like awarding block rewards. + +Any valid block built on top of a tipset `ts` should have its Parent State Root equal to the result of +calculating the tipset state of `ts`. Note that this means that all blocks in a tipset must have the same Parent +State Root (which is to be expected, since they have the same parent tipset) + +### Preparing to apply a tipset + +When `StateManager::computeTipsetState()` is called with a tipset, `ts`, +it retrieves the parent state root of the blocks in `ts`. It also creates a list of `BlockMessages`, which wraps the BLS +and SecP messages in a block along with the miner that produced the block. + +Control then flows to `StateManager::ApplyBlocks()`, which builds a VM to apply the messages given to it. The VM +is initialized with the parent state root of the blocks in `ts`. We apply the blocks in `ts` in order (see FIXME for +ordering of blocks in a tipset). + +### Applying a block + +For each block, we prepare to apply the ordered messages (first BLS, then SecP). Before applying a message, we check if +we have already applied a message with that CID within the scope of this method. If so, we simply skip that message; +this is how duplicate messages included in the same tipset are skipped (with only the miner of the "first" block to +include the message getting the reward). For the actual process of message application, see FIXME (need an +internal link here), for now we +simply assume that the outcome of the VM applying a message is either an error, or a +[`MessageReceipt`](https://github.com/filecoin-project/lotus/blob/master/chain/types/message_receipt.go) + and some +other information. + +We treat an error from the VM as a showstopper; there is no recovery, and no meaningful state can be computed for `ts`. +Given a successful receipt, we add the rewards and penalties to what the miner has earned so far. Once all the messages +included in a block have been applied (or skipped if they're a duplicate), we use an implicit message to call +the Reward Actor. This awards the miner their reward for having won a block, and also awards / penalizes them based +on the message rewards and penalties we tracked. + +We then proceed to apply the next block in `ts`, using the same VM. This means that the state changes that result +from applying a message are visible when applying all subsequent messages, even if they are included in a different block. + +### Finishing up + +Having applied all the blocks, we send one more implicit message, to the Cron Actor, which handles operations that +must be performed at the end of every epoch (see FIXME for more). The resulting state after calling the Cron Actor +is the computed state of the tipset. + +# Virtual Machine + +The Virtual Machine (VM) is responsible for executing messages. +The [Lotus Virtual Machine](https://github.com/filecoin-project/lotus/blob/master/chain/vm/vm.go) +invokes the appropriate methods in the builtin actors, and provides +a [`Runtime`](https://github.com/filecoin-project/specs-actors/blob/master/actors/runtime/runtime.go) +interface to the [builtin actors](https://github.com/filecoin-project/specs-actors) +that exposes their state, allows them to take certain actions, and meters +their gas usage. The VM also performs balance transfers, creates new account actors as needed, and tracks the gas reward, +penalty, return value, and exit code. + +## Applying a Message + +The primary entrypoint of the VM is the `ApplyMessage()` method. This method should not return an error +unless something goes unrecoverably wrong. + +The first thing this method does is assess if the message provided meets any of the penalty criteria. +If so, a penalty is issued, and the method returns. Next, the entire gas cost of the message is transferred to +a temporary gas holder account. It is from this gas holder that gas will be deducted; if it runs out of gas, the message +fails. Any unused gas in this holder will be refunded to the message's sender at the end of message execution. + +The VM then increments the sender's nonce, takes a snapshot of the state, and invokes `VM::send()`. + +The `send()` method creates a [`Runtime`](https://github.com/filecoin-project/lotus/blob/master/chain/vm/runtime.go) + for the subsequent message execution. +It then transfers the message's value to the recipient, creating a new account actor if needed. + +### Method Invocation + +We use reflection to translate a Filecoin message for the VM to an actual Go function, relying on the VM's +[`invoker`](https://github.com/filecoin-project/lotus/blob/master/chain/vm/invoker.go) structure. +Each actor has its own set of codes defined in `specs-actors/actors/builtin/methods.go`. +The `invoker` structure maps the builtin actors' CIDs + to a list of `invokeFunc` (one per exported method), which each take the `Runtime` (for state manipulation) + and the serialized input parameters. + +FIXME (aayush) Polish this next para. + +The basic layout (without reflection details) of `(*invoker).transform()` is as follows. From each actor registered in `NewInvoker()` we take its `Exports()` methods converting them to `invokeFunc`s. The actual method is wrapped in another function that takes care of decoding the serialized parameters and the runtime, this function is passed to `shimCall()` that will encapsulate the actors code being run inside a `defer` function to `recover()` from panics (we fail in the actors code with panics to unwrap the stack). The return values will then be (CBOR) marshaled and returned to the VM. + +### Returning from the VM + +Once method invocation is complete (including any subcalls), we return to `ApplyMessage()`, which receives +the serialized response and the [`ActorError`](https://github.com/filecoin-project/lotus/blob/master/chain/actors/aerrors/error.go). +The sender will be charged the appropriate amount of gas for the returned response, which gets put into the +[`MessageReceipt`](https://github.com/filecoin-project/lotus/blob/master/chain/types/message_receipt.go). + +The method then refunds any unused gas to the sender, sets up the gas reward for the miner, and +wraps all of this into an `ApplyRet`, which is returned. + +# Building a Lotus node + +When we launch a Lotus node with the command `./lotus daemon` +(see [here](https://github.com/filecoin-project/lotus/blob/master/cmd/lotus/daemon.go) for more), +the node is created through [dependency injection](https://godoc.org/go.uber.org/fx). +This relies on reflection, which makes some of the references hard to follow. +The node sets up all of the subsystems it needs to run, such as the repository, the network connections, thechain sync +service, etc. +This setup is orchestrated through calls to the `node.Override` function. +The structure of each call indicates the type of component it will set up +(many defined in [`node/modules/dtypes/`](https://github.com/filecoin-project/lotus/tree/master/node/modules/dtypes)), +and the function that will provide it. +The dependency is implicit in the argument of the provider function. + +As an example, consider the `modules.ChainStore()` function that provides the +[`ChainStore`](https://github.com/filecoin-project/lotus/blob/master/chain/store/store.go) structure. +It takes as one of its parameters the [`ChainBlockstore`](https://github.com/filecoin-project/lotus/blob/master/node/modules/dtypes/storage.go) +type, which becomes one of its dependencies. +For the node to be built successfully the `ChainBlockstore` will need to be provided before `ChainStore`, a requirement +that is made explicit in another `Override()` call that sets the provider of that type as the `ChainBlockstore()` function. + +## The Repository + +The repo is the directory where all of a node's information is stored. The node is entirely defined by its repo, which +makes it easy to port to another location. This one-to-one relationship means we can speak +of the node as the repo it is associated with, instead of the daemon process that runs from that repo. + +Only one daemon can run be running with an associated repo at a time. +A process signals that it is running a node associated with a particular repo, by creating and acquiring +a `repo.lock`. + +```sh +lsof ~/.lotus/repo.lock +# COMMAND PID +# lotus 52356 +``` +Trying to launch a second daemon hooked to the same repo leads to a `repo is already locked (lotus daemon already running)` +error. + +The `node.Repo()` function (`node/builder.go`) contains most of the dependencies (specified as `Override()` calls) +needed to properly set up the node's repo. We list the most salient ones here. + +### Datastore + +`Datastore` and `ChainBlockstore`: Data related to the node state is saved in the repo's `Datastore`, +an IPFS interface defined [here](github.com/ipfs/go-datastore/datastore.go). +Lotus creates this interface from a [Badger DB](https://github.com/dgraph-io/badger) in + [`FsRepo`](https://github.com/filecoin-project/lotus/blob/master/node/repo/fsrepo.go). +Every piece of data is fundamentally a key-value pair in the `datastore` directory of the repo. +There are several abstractions laid on top of it that appear through the code depending on *how* we access it, +but it is important to remember that we're always accessing it from the same place. + +FIXME: Maybe mention the `Batching` interface as the developer will stumble upon it before reaching the `Datastore` one. + +#### Blocks + +FIXME: IPFS blocks vs Filecoin blocks ideally happens before this / here + +The [`Blockstore` interface](`github.com/ipfs/go-ipfs-blockstore/blockstore.go`) structures the key-value pair +into the CID format for the key and the [`Block` interface](`github.com/ipfs/go-block-format/blocks.go`) for the value. +The `Block` value is just a raw string of bytes addressed by its hash, which is included in the CID key. + +`ChainBlockstore` creates a `Blockstore` in the repo under the `/blocks` namespace. +Every key stored there will have the `blocks` prefix so that it does not collide with other stores that use the same repo. + +FIXME: Link to IPFS documentation about DAG, CID, and related, especially we need a diagram that shows how do we wrap each datastore inside the next layer (datastore, batching, block store, gc, etc). + +#### Metadata + +`modules.Datastore()` creates a `dtypes.MetadataDS`, which is an alias for the basic `Datastore` interface. +Metadata is stored here under the `/metadata` prefix. +(FIXME: Explain *what* is metadata in contrast with the block store, namely we store the pointer to the heaviest chain, we might just link to that unwritten section here later.) + +FIXME: Explain the key store related calls (maybe remove, per Schomatis) + +### LockedRepo + +`LockedRepo()`: This method doesn't create or initialize any new structures, but rather registers an + `OnStop` [hook](https://godoc.org/go.uber.org/fx/internal/lifecycle#Hook) + that will close the locked repository associated with it on shutdown. + + +### Repo types / Node types + +FIXME: This section needs to be clarified / corrected...I don't fully understand the config differences (what do they have in common, if anything?) + +At the end of the `Repo()` function we see two mutually exclusive configuration calls based on the `RepoType` (`node/repo/fsrepo.go`). +```Go + ApplyIf(isType(repo.FullNode), ConfigFullNode(c)), + ApplyIf(isType(repo.StorageMiner), ConfigStorageMiner(c)), +``` +As we said, the repo fully identifies the node so a repo type is also a *node* type, in this case a full node or a storage miner. (FIXME: What is the difference between the two, does *full* imply miner?) In this case the `daemon` command will create a `FullNode`, this is specified in the command logic itself in `main.DaemonCmd()`, the `FsRepo` created (and passed to `node.Repo()`) will be initiated with that type (see `(*FsRepo).Init(t RepoType)`). + +## Online + +FIXME: Much of this might need to be subsumed into the p2p section + +The `node.Online()` configuration function (`node/builder.go`) initializes components that involve connecting to, +or interacting with, the Filecoin network. These connections are managed through the libp2p stack (FIXME link to this section when it exists). +We discuss some of the components found in the full node type (that is, included in the `ApplyIf(isType(repo.FullNode),` call). + +#### Chainstore + +`modules.ChainStore()` creates the [`store.ChainStore`](https://github.com/filecoin-project/lotus/blob/master/chain/store/store.go)) +that wraps the stores + previously instantiated in `Repo()`. It is the main point of entry for the node to all chain-related data + (FIXME: this is incorrect, we sometimes access its underlying block store directly, and probably shouldn't). + It also holds the crucial `heaviest` pointer, which indicates the current head of the chain. + + #### ChainExchange and ChainBlockservice +`ChainExchange()` and `ChainBlockservice()` establish a BitSwap connection (FIXME libp2p link) +to exchange chain information in the form of `blocks.Block`s stored in the repo. (See sync section for more details, the Filecoin blocks and messages are backed by these raw IPFS blocks that together form the different structures that define the state of the current/heaviest chain.) + +#### Incoming handlers +`HandleIncomingBlocks()` and `HandleIncomingMessages()` start the services in charge of processing new Filecoin blocks +and messages from the network (see `` for more information about the topics the node is subscribed to, FIXME: should that be part of the libp2p section or should we expand on gossipsub separately?). + +#### Hello +`RunHello()`: starts the services to both send (`(*Service).SayHello()`) and receive (`(*Service).HandleStream()`, `node/hello/hello.go`) +`hello` messages. When nodes establish a new connection with each other, they exchange these messages +to share chain-related information (namely their genesis block and their heaviest tipset). + +#### Syncer +`NewSyncer()` creates the `Syncer` structure and starts the services related to the chain sync process (FIXME link). + +### Ordering the dependencies + +We can establish the dependency relations by looking at the parameters that each function needs and by understanding +the architecture of the node and how the different components relate to each other (the chief purpose of this document). + +As an example, the sync mechanism depends on the node being able to exchange different IPFS blocks with the network, +so as to be able to request the "missing pieces" needed to construct the chain. This dependency is reflected by `NewSyncer()` +having a `blocksync.BlockSync` parameter, which in turn depends on `ChainBlockservice()` and `ChainExchange()`. +The chain exchange service further depends on the chain store to save and retrieve chain data, which is reflected +in `ChainExchange()` having `ChainGCBlockstore` as a parameter (which is just a wrapper around `ChainBlockstore` capable + of garbage collection). + +This block store is the same store underlying the chain store, which is an indirect dependency of `NewSyncer()` (through the `StateManager`). +(FIXME: This last line is flaky, we need to resolve the hierarchy better, we sometimes refer to the chain store and sometimes to its underlying block store. We need a diagram to visualize all the different components just mentioned otherwise it is too hard to follow. We probably even need to skip some of the connections mentioned.) \ No newline at end of file diff --git a/documentation/en/dev/WIP-arch-complementary-notes.md b/documentation/en/dev/WIP-arch-complementary-notes.md new file mode 100644 index 000000000..00bedb56a --- /dev/null +++ b/documentation/en/dev/WIP-arch-complementary-notes.md @@ -0,0 +1,153 @@ +# Genesis block + +Seems a good way to start exploring the VM state though the instantiation of its different actors like the storage power. + +Explain where do we load the genesis block, the CAR entries, and we set the root of the state. Follow the daemon command option, `chain.LoadGenesis()` saves all the blocks of the CAR file into the store provided by `ChainBlockstore` (this should already be explained in the previous section). The CAR root (MT root?) of those blocks is decoded into the `BlockHeader` that will be the Filecoin (genesis) block of the chain, but most of the information was stored in the raw data (non-Filecoin, what's the correct term?) blocks forwarded directly to the chain, the block header just has a pointer to it. + +`SetGenesis` block with name 0. `(ChainStore).SetGenesis()` stores it there. + +`MakeInitialStateTree` (`chain/gen/genesis/genesis.go`, used to construct the genesis block (`MakeGenesisBlock()`), constructs the state tree (`NewStateTree`) which is just a "pointer" (root node in the HAMT) to the different actors. It will be continuously used in `(*StateTree).SetActor()` an `types.Actor` structure under a certain `Address` (in the HAMT). (How does the `stateSnaps` work? It has no comments.) + +From this point we can follow different setup function like: + +* `SetupInitActor()`: see the `AddressMap`. + +* `SetupStoragePowerActor`: initial (zero) power state of the chain, most important attributes. + +* Account actors in the `template.Accounts`: `SetActor`. + +Which other actor type could be helpful at this point? + +# Basic concepts + +What should be clear at this point either from this document or the spec. + +## Addresses + +## Accounts + +# Sync Topics PubSub + +Gossip sub spec and some introduction. + +# Look at the constructor of a miner + +Follow the `lotus-storage-miner` command to see how a miner is created, from the command to the message to the storage power logic. + +# Directory structure so far, main structures seen, their relation + +List what are the main directories we should be looking at (e.g., `chain/`) and the most important structures (e.g., `StateTree`, `Runtime`, etc.) + +# Tests + +Run a few messages and observe state changes. What is the easiest test that also let's us "interact" with it (modify something and observe the difference). + +### Filecoin blocks vs IPFS blocks + +The term *block* has different meanings depending on the context, many times both meanings coexist at once in the code and it is important to distinguish them. (FIXME: link to IPFS blocks and related doc throughout this explanation). In terms of the lower IPFS layer, in charge of storing and retrieving data, both present at the repo or accessible through the network (e.g., through the BitSwap protocol discussed later), a block is a string of raw bytes identified by its hash, embedded and fully qualified in a CID identifier. IPFS blocks are the "building blocks" of almost any other piece of (chain) data described in the Filecoin protocol. + +In contrast, in the higher Filecoin (application) layer, a block is roughly (FIXME: link to spec definition, if we have any) a set of zero or more messages grouped together by a single miner which is itself grouped with other blocks (from other miners) in the same round to form a tipset. The Filecoin blockchain is a series of "chained" tipsets, each referencing its parent by its header's *CID*, that is, its header as seen as a single IPFS block, this is where both layers interact. + +Using now the full Go package qualifiers to avoid any ambiguity, the Filecoin block, `github.com/filecoin-project/lotus/chain/types.FullBlock`, is defined as, + +```Go +package types + +import "github.com/ipfs/go-cid" + +type FullBlock struct { + Header *BlockHeader + BlsMessages []*Message + SecpkMessages []*SignedMessage +} + +func (fb *FullBlock) Cid() cid.Cid { + return fb.Header.Cid() +} +``` + +It has, besides the Filecoin messages, a header with protocol related information (e.g., its `Height`) which is (like virtually any other piece of data in the Filecoin protocol) stored, retrieved and shared as an IPFS block with its corresponding CID, + +```Go +func (b *BlockHeader) Cid() cid.Cid { + sb, err := b.ToStorageBlock() + + return sb.Cid() +} + +func (b *BlockHeader) ToStorageBlock() (block.Block, error) { + data, err := b.Serialize() + + return github.com/ipfs/go-block-format.block.NewBlockWithCid(data) +} +``` + +These edited extracts from the `BlockHeader` show how it's treated as an IPFS block, `github.com/ipfs/go-block-format.block.BasicBlock`, to be both stored and referenced by its block storage CID. + +This duality permeates the code (and the Filecoin spec for that matter) but it is usually clear within the context to which block we are referring to. Normally the unqualified *block* is reserved for the Filecoin block and we won't usually refer to the IPFS one but only implicitly through the concept of its CID. With enough understanding of both stack's architecture the two definitions can coexist without much confusion as we will abstract away the IPFS layer and just use the CID as an identifier that we now its unique for two sequences of different *raw* byte strings. + +(FIXME: We use to do this presentation when talking about `gossipsub` topics and incoming blocks, and had to deal with, besides the block ambiguity, a similar confusion with the *message* term, used in libp2p to name anything that comes through the network, needing to present the extremely confusing hierarchy of a libp2p message containing a Filecoin block, identified by a IPFS block CID, containing Filecoin messages.) + +FIXME: Move the following tipset definition to sync or wherever is most needed, to avoid making this more confusing. + +Messages from the same round are collected into a block set (`chain/store/fts.go`): + +```Go +type FullTipSet struct { + Blocks []*types.FullBlock + tipset *types.TipSet + cids []cid.Cid +} +``` + +The "tipset" denomination might be a bit misleading as it doesn't refer *only* to the tip, the block set from the last round in the chain, but to *any* set of blocks, depending on the context the tipset is the actual tip or not. From its own perspective any block set is always the tip because it assumes nothing from following blocks. + +# CLI, API + +Explain how do we communicate with the node, both in terms of the CLI and the programmatic way (to create our own tools). + +## Client/server architecture + +In terms of the Filecoin network the node is a peer on a distributed hierarchy, but in terms of how we interact with the node we have client/server architecture. + +The node itself was initiated with the `daemon` command, it already started syncing to the chain by default. Along with that service it also started a [JSON-RPC](https://en.wikipedia.org/wiki/JSON-RPC) server to allow a client to interact with it. (FIXME: Check if this client is local or can be remote, link to external documentation of connection API.) + +We can connect to this server through the Lotus CLI. Virtually any other command other than `daemon` will run a client that will connect (by default) to the address specified in the `api` file in the repo associated with the node (by default in `~/.lotus`), e.g., + +```sh +cat ~/.lotus/api && echo +# /ip4/127.0.0.1/tcp/1234/http + +# With `lotus daemon` running in another terminal. +nc -v -z 127.0.0.1 1234 + +# Start daemon and turn off the logs to not clutter the command line. +bash -c "lotus daemon &" && + lotus wait-api && + lotus log set-level error # Or a env.var in the daemon command. + +nc -v -z 127.0.0.1 1234 +# Connection to 127.0.0.1 1234 port [tcp/*] succeeded! + +killall lotus +# FIXME: We need a lotus stop command: +# https://github.com/filecoin-project/lotus/issues/1827 +``` + +FIXME: Link to more in-depth documentation of the CLI architecture, maybe some IPFS documentation (since they share some common logic). + +## Node API + +The JSON-RPC server exposes the node API, the `FullNode` interface (defined in `api/api_full.go`). When we issue a command like `lotus sync status` to query the progress of the node sync we don't access the node's internals, those are decoupled in a separate daemon process, we call the `SyncState` function (of the `FullNode` API interface) through the RPC client started by our own command (see `NewFullNodeRPC` in `api/client/client.go` for more details). + +FIXME: Link to (and create) documentation about API fulfillment. + +Because we rely heavily on reflection for this part of the code the call chain is not easily visible by just following the references through the symbolic analysis of the IDE. If we start by the `lotus sync` command definition (in `cli/sync.go`), we eventually end up in the method interface `SyncState`, and when we look for its implementation we will find two functions: + +* `(*SyncAPI).SyncState()` (in `node/impl/full/sync.go`): this is the actual implementation of the API function that shows what the node (here acting as the RPC server) will execute when it receives the RPC request issued from the CLI acting as the client. + +* `(*FullNodeStruct).SyncState()`: this is an "empty placeholder" structure that will get later connected to the JSON-RPC client logic (see `NewMergeClient` in `lib/jsonrpc/client.go`, which is called by `NewFullNodeRPC`). (FIXME: check if this is accurate). The CLI (JSON-RPC client) will actually execute this function which will connect to the server and send the corresponding JSON request that will trigger the call of `(*SyncAPI).SyncState()` with the node implementation. + +This means that when we are tracking the logic of a CLI command we will eventually find this bifurcation and need to study the code of the server-side implementation in `node/impl/full` (mostly in the `common/` and `full/` directories). If we understand this architecture going directly to that part of the code abstracts away the JSON-RPC client/server logic and we can think that the CLI is actually running the node's logic. + +FIXME: Explain that "*the* node" is actually an API structure like `impl.FullNodeAPI` with the different API subcomponents like `full.SyncAPI`. We won't see a *single* node structure, each API (full node, minder, etc) will gather the necessary subcomponents it needs to service its calls. \ No newline at end of file From 6ba5c5d0e151f5351dbf444ff103db447f170e33 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 9 Jun 2020 18:19:33 -0400 Subject: [PATCH 106/379] Doc fix: use correct file name --- documentation/en/.library.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/en/.library.json b/documentation/en/.library.json index f637c813f..545eb4a5b 100644 --- a/documentation/en/.library.json +++ b/documentation/en/.library.json @@ -58,8 +58,8 @@ }, { "title": "Use Lotus with systemd", - "slug": "en+install-system-services", - "github": "en/install-system-services.md", + "slug": "en+install-systemd-services", + "github": "en/install-systemd-services.md", "value": null }, { From 27858506fff9df92f0fc5a51d31ed92a2774a5ae Mon Sep 17 00:00:00 2001 From: waynewyang Date: Wed, 10 Jun 2020 20:34:04 +0800 Subject: [PATCH 107/379] error check --- cli/chain.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/chain.go b/cli/chain.go index 01714d850..da88df657 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -889,6 +889,9 @@ var slashConsensusFault = &cli.Command{ BlockHeader1: bh1, BlockHeader2: bh2, }) + if err != nil { + return err + } if cctx.String("miner") == "" { return xerrors.Errorf("--miner flag is required") From 2ce3a5f887034e8d4ba8f5b2859dfc6ab19807a0 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Thu, 11 Jun 2020 00:09:48 +0200 Subject: [PATCH 108/379] docs: add a note about open files limit --- documentation/en/join-testnet.md | 2 ++ documentation/en/setup-troubleshooting.md | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/documentation/en/join-testnet.md b/documentation/en/join-testnet.md index bdd1b4a56..d01d7eafa 100644 --- a/documentation/en/join-testnet.md +++ b/documentation/en/join-testnet.md @@ -28,6 +28,8 @@ lotus net peers | wc -l In order to connect to the network, you need to be connected to at least 1 peer. If you’re seeing 0 peers, read our [troubleshooting notes](https://docs.lotu.sh/en+setup-troubleshooting). +Make sure that you have a reasonable "open files limit" set on your machine, such as 10000. If you're seeing a lower value, such as 256 (default on macOS), read our [troubleshooting notes](https://docs.lotu.sh/en+setup-troubleshooting) on how to update it prior to starting the Lotus daemon. + ## Chain sync While the daemon is running, the next requirement is to sync the chain. Run the command below to view the chain sync progress. To see current chain height, visit the [network stats page](https://stats.testnet.filecoin.io/). diff --git a/documentation/en/setup-troubleshooting.md b/documentation/en/setup-troubleshooting.md index 055a9c501..8a23544d9 100644 --- a/documentation/en/setup-troubleshooting.md +++ b/documentation/en/setup-troubleshooting.md @@ -29,4 +29,18 @@ ERROR hello hello/hello.go:81 other peer has different genesis! - repo is already locked ``` -- You already have another lotus daemon running. \ No newline at end of file +- You already have another lotus daemon running. + +## Config: Open files limit + +On most systems you can check the open files limit with: + +```sh +ulimit -n +``` + +You can also modify this number by using the `ulimit` command. It gives you the ability to control the resources available for the shell or process started by it. If the number is below 10000, you can change it with the following command prior to starting the Lotus daemon: + +```sh +ulimit -n 10000 +``` From 14ea847ef63eb1b05625c2ebb9d61443ec059429 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 10 Jun 2020 22:15:46 -0700 Subject: [PATCH 109/379] fix chain index seeking through long ranges of null rounds --- chain/store/index.go | 12 +++++-- chain/store/index_test.go | 76 +++++++++++++++++++++++++++++++++++++++ chain/types/mock/chain.go | 7 +++- 3 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 chain/store/index_test.go diff --git a/chain/store/index.go b/chain/store/index.go index 15d5d7025..8747c79c6 100644 --- a/chain/store/index.go +++ b/chain/store/index.go @@ -97,9 +97,15 @@ func (ci *ChainIndex) fillCache(tsk types.TipSetKey) (*lbEntry, error) { rheight -= ci.skipLength - skipTarget, err := ci.walkBack(parent, rheight) - if err != nil { - return nil, err + var skipTarget *types.TipSet + if parent.Height() < rheight { + skipTarget = parent + + } else { + skipTarget, err = ci.walkBack(parent, rheight) + if err != nil { + return nil, xerrors.Errorf("fillCache walkback: %w", err) + } } lbe := &lbEntry{ diff --git a/chain/store/index_test.go b/chain/store/index_test.go new file mode 100644 index 000000000..6b97a8614 --- /dev/null +++ b/chain/store/index_test.go @@ -0,0 +1,76 @@ +package store_test + +import ( + "bytes" + "context" + "testing" + + "github.com/filecoin-project/lotus/chain/gen" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types/mock" + "github.com/filecoin-project/specs-actors/actors/abi" + datastore "github.com/ipfs/go-datastore" + syncds "github.com/ipfs/go-datastore/sync" + blockstore "github.com/ipfs/go-ipfs-blockstore" + "github.com/stretchr/testify/assert" +) + +func TestIndexSeeks(t *testing.T) { + cg, err := gen.NewGenerator() + if err != nil { + t.Fatal(err) + } + + gencar, err := cg.GenesisCar() + if err != nil { + t.Fatal(err) + } + + gen := cg.Genesis() + + ctx := context.TODO() + + nbs := blockstore.NewBlockstore(syncds.MutexWrap(datastore.NewMapDatastore())) + cs := store.NewChainStore(nbs, syncds.MutexWrap(datastore.NewMapDatastore()), nil) + + _, err = cs.Import(bytes.NewReader(gencar)) + if err != nil { + t.Fatal(err) + } + + cur := mock.TipSet(gen) + if err := cs.PutTipSet(ctx, mock.TipSet(gen)); err != nil { + t.Fatal(err) + } + cs.SetGenesis(gen) + + for i := 0; i < 100; i++ { + nextts := mock.TipSet(mock.MkBlock(cur, 1, 1)) + + if err := cs.PutTipSet(ctx, nextts); err != nil { + t.Fatal(err) + } + cur = nextts + } + + skip := mock.MkBlock(cur, 1, 1) + skip.Height += 50 + + skipts := mock.TipSet(skip) + + if err := cs.PutTipSet(ctx, skipts); err != nil { + t.Fatal(err) + } + + ts, err := cs.GetTipsetByHeight(ctx, skip.Height-10, skipts, false) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, abi.ChainEpoch(151), ts.Height()) + + ts2, err := cs.GetTipsetByHeight(ctx, 90, skipts, false) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, abi.ChainEpoch(90), ts2.Height()) +} diff --git a/chain/types/mock/chain.go b/chain/types/mock/chain.go index 5154ab115..00d0eecc9 100644 --- a/chain/types/mock/chain.go +++ b/chain/types/mock/chain.go @@ -49,6 +49,11 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types panic(err) } + pstateRoot := c + if parents != nil { + pstateRoot = parents.Blocks()[0].ParentStateRoot + } + var pcids []cid.Cid var height abi.ChainEpoch weight := types.NewInt(weightInc) @@ -72,7 +77,7 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types ParentWeight: weight, Messages: c, Height: height, - ParentStateRoot: c, + ParentStateRoot: pstateRoot, BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")}, } } From ac1048fcd7c3e1e616f7fedb4470bbd0ba159bae Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 10 Jun 2020 22:17:29 -0700 Subject: [PATCH 110/379] test a few more cases --- chain/store/index_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/chain/store/index_test.go b/chain/store/index_test.go index 6b97a8614..b1a85996f 100644 --- a/chain/store/index_test.go +++ b/chain/store/index_test.go @@ -68,9 +68,11 @@ func TestIndexSeeks(t *testing.T) { } assert.Equal(t, abi.ChainEpoch(151), ts.Height()) - ts2, err := cs.GetTipsetByHeight(ctx, 90, skipts, false) - if err != nil { - t.Fatal(err) + for i := 0; i <= 100; i++ { + ts3, err := cs.GetTipsetByHeight(ctx, abi.ChainEpoch(i), skipts, false) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, abi.ChainEpoch(i), ts3.Height()) } - assert.Equal(t, abi.ChainEpoch(90), ts2.Height()) } From 41066bd45e3bd73f2ee2c34e5681ec9241d97262 Mon Sep 17 00:00:00 2001 From: waynewyang Date: Thu, 11 Jun 2020 19:19:17 +0800 Subject: [PATCH 111/379] Add flag for cli slash-consensus --- cli/chain.go | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/cli/chain.go b/cli/chain.go index 0bf7741cb..cbdd957e9 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -835,6 +835,10 @@ var slashConsensusFault = &cli.Command{ Name: "miner", Usage: "Miner address", }, + &cli.StringFlag{ + Name: "extra", + Usage: "Extra block cid", + }, }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) @@ -879,10 +883,31 @@ var slashConsensusFault = &cli.Command{ return err } - params, err := actors.SerializeParams(&miner.ReportConsensusFaultParams{ + params := miner.ReportConsensusFaultParams{ BlockHeader1: bh1, BlockHeader2: bh2, - }) + } + + if cctx.String("extra") != "" { + cExtra, err := cid.Parse(cctx.String("extra")) + if err != nil { + return xerrors.Errorf("parsing cid extra: %w", err) + } + + bExtra, err := api.ChainGetBlock(ctx, cExtra) + if err != nil { + return xerrors.Errorf("getting block extra: %w", err) + } + + be, err := cborutil.Dump(bExtra) + if err != nil { + return err + } + + params.BlockHeaderExtra = be + } + + enc, err := actors.SerializeParams(¶ms) if err != nil { return err } @@ -903,7 +928,7 @@ var slashConsensusFault = &cli.Command{ GasPrice: types.NewInt(1), GasLimit: 10000000, Method: builtin.MethodsMiner.ReportConsensusFault, - Params: params, + Params: enc, } smsg, err := api.MpoolPushMessage(ctx, msg) From 8b308972a4ae483c48a9080dd66b8562b97ff41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 11 Jun 2020 14:49:48 +0200 Subject: [PATCH 112/379] chainstore index: Drop wrong check --- chain/store/index.go | 10 ++++------ chain/store/index_test.go | 8 +++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/chain/store/index.go b/chain/store/index.go index 8747c79c6..bb363ec18 100644 --- a/chain/store/index.go +++ b/chain/store/index.go @@ -91,16 +91,11 @@ func (ci *ChainIndex) fillCache(tsk types.TipSetKey) (*lbEntry, error) { return nil, err } - if parent.Height() > rheight { - return nil, xerrors.Errorf("cache is inconsistent") - } - rheight -= ci.skipLength var skipTarget *types.TipSet if parent.Height() < rheight { skipTarget = parent - } else { skipTarget, err = ci.walkBack(parent, rheight) if err != nil { @@ -119,8 +114,9 @@ func (ci *ChainIndex) fillCache(tsk types.TipSetKey) (*lbEntry, error) { return lbe, nil } +// floors to nearest skipLength multiple func (ci *ChainIndex) roundHeight(h abi.ChainEpoch) abi.ChainEpoch { - return abi.ChainEpoch(h/ci.skipLength) * ci.skipLength + return (h / ci.skipLength) * ci.skipLength } func (ci *ChainIndex) roundDown(ts *types.TipSet) (*types.TipSet, error) { @@ -152,6 +148,8 @@ func (ci *ChainIndex) walkBack(from *types.TipSet, to abi.ChainEpoch) (*types.Ti } if to > pts.Height() { + // in case pts is lower than the epoch we're looking for (null blocks) + // return a tipset above that height return ts, nil } if to == pts.Height() { diff --git a/chain/store/index_test.go b/chain/store/index_test.go index b1a85996f..73f4901f0 100644 --- a/chain/store/index_test.go +++ b/chain/store/index_test.go @@ -44,7 +44,8 @@ func TestIndexSeeks(t *testing.T) { } cs.SetGenesis(gen) - for i := 0; i < 100; i++ { + // Put 113 blocks from genesis + for i := 0; i < 113; i++ { nextts := mock.TipSet(mock.MkBlock(cur, 1, 1)) if err := cs.PutTipSet(ctx, nextts); err != nil { @@ -53,6 +54,7 @@ func TestIndexSeeks(t *testing.T) { cur = nextts } + // Put 50 null epochs + 1 block skip := mock.MkBlock(cur, 1, 1) skip.Height += 50 @@ -66,9 +68,9 @@ func TestIndexSeeks(t *testing.T) { if err != nil { t.Fatal(err) } - assert.Equal(t, abi.ChainEpoch(151), ts.Height()) + assert.Equal(t, abi.ChainEpoch(164), ts.Height()) - for i := 0; i <= 100; i++ { + for i := 0; i <= 113; i++ { ts3, err := cs.GetTipsetByHeight(ctx, abi.ChainEpoch(i), skipts, false) if err != nil { t.Fatal(err) From c3f23ddce829ddb9bac444f019d2e47d5ba85ac7 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 11 Jun 2020 02:47:28 +0200 Subject: [PATCH 113/379] Refactor ExecutionResult to ExecutionTrace Signed-off-by: Jakub Sztandera --- api/api_full.go | 10 ++--- api/docgen/docgen.go | 2 +- chain/stmgr/call.go | 10 ++--- chain/stmgr/stmgr.go | 8 ++-- chain/types/execresult.go | 4 +- chain/vm/runtime.go | 37 +++++------------ chain/vm/vm.go | 86 +++++++++++++++++++++++---------------- cli/state.go | 14 +++---- go.mod | 1 + go.sum | 3 ++ node/impl/full/state.go | 10 ++--- 11 files changed, 95 insertions(+), 90 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 63d9a5e5d..e9370a0b8 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -350,11 +350,11 @@ type RetrievalOrder struct { } type InvocResult struct { - Msg *types.Message - MsgRct *types.MessageReceipt - InternalExecutions []*types.ExecutionResult - Error string - Duration time.Duration + Msg *types.Message + MsgRct *types.MessageReceipt + ExecutionTrace types.ExecutionTrace + Error string + Duration time.Duration } type MethodCall struct { diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index eb4ab5fd9..d0b5d8558 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -93,7 +93,7 @@ func init() { addExample(build.APIVersion) addExample(api.PCHInbound) addExample(time.Minute) - addExample(&types.ExecutionResult{ + addExample(&types.ExecutionTrace{ Msg: exampleValue(reflect.TypeOf(&types.Message{})).(*types.Message), MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{})).(*types.MessageReceipt), }) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index b9635696f..32e502e95 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -62,11 +62,11 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate } return &api.InvocResult{ - Msg: msg, - MsgRct: &ret.MessageReceipt, - InternalExecutions: ret.InternalExecutions, - Error: errs, - Duration: ret.Duration, + Msg: msg, + MsgRct: &ret.MessageReceipt, + ExecutionTrace: ret.ExecutionTrace, + Error: errs, + Duration: ret.Duration, }, nil } diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index d6aaebab4..d4c12dffe 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -121,10 +121,10 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c var trace []*api.InvocResult st, _, err := sm.computeTipSetState(ctx, ts.Blocks(), func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error { ir := &api.InvocResult{ - Msg: msg, - MsgRct: &ret.MessageReceipt, - InternalExecutions: ret.InternalExecutions, - Duration: ret.Duration, + Msg: msg, + MsgRct: &ret.MessageReceipt, + ExecutionTrace: ret.ExecutionTrace, + Duration: ret.Duration, } if ret.ActorErr != nil { ir.Error = ret.ActorErr.Error() diff --git a/chain/types/execresult.go b/chain/types/execresult.go index 56f2ef143..dd5c8fa3e 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -2,11 +2,11 @@ package types import "time" -type ExecutionResult struct { +type ExecutionTrace struct { Msg *Message MsgRct *MessageReceipt Error string Duration time.Duration - Subcalls []*ExecutionResult + Subcalls []ExecutionTrace } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index d9268afe4..0067055d1 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -5,7 +5,6 @@ import ( "context" "encoding/binary" "fmt" - "time" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" @@ -51,10 +50,10 @@ type Runtime struct { origin address.Address originNonce uint64 - internalExecutions []*types.ExecutionResult - numActorsCreated uint64 - allowInternal bool - callerValidated bool + executionTrace types.ExecutionTrace + numActorsCreated uint64 + allowInternal bool + callerValidated bool } func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount { @@ -368,7 +367,6 @@ func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars } func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) { - start := time.Now() ctx, span := trace.StartSpan(rt.ctx, "vmc.Send") defer span.End() if span.IsRecordingEvents() { @@ -401,27 +399,10 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, } } - mr := types.MessageReceipt{ - ExitCode: aerrors.RetCode(errSend), - Return: ret, - GasUsed: 0, - } - - er := types.ExecutionResult{ - Msg: msg, - MsgRct: &mr, - Duration: time.Since(start), - } - - if errSend != nil { - er.Error = errSend.Error() - } - if subrt != nil { - er.Subcalls = subrt.internalExecutions rt.numActorsCreated = subrt.numActorsCreated } - rt.internalExecutions = append(rt.internalExecutions, &er) + rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace) //&er) return ret, errSend } @@ -504,13 +485,13 @@ func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError { } func (rt *Runtime) ChargeGas(toUse int64) { - err := rt.chargeGasSafe(toUse) + err := rt.chargeGasInternal(toUse) if err != nil { panic(err) } } -func (rt *Runtime) chargeGasSafe(toUse int64) aerrors.ActorError { +func (rt *Runtime) chargeGasInternal(toUse int64) aerrors.ActorError { if rt.gasUsed+toUse > rt.gasAvailable { rt.gasUsed = rt.gasAvailable return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d", rt.gasUsed, rt.gasAvailable) @@ -519,6 +500,10 @@ func (rt *Runtime) chargeGasSafe(toUse int64) aerrors.ActorError { return nil } +func (rt *Runtime) chargeGasSafe(toUse int64) aerrors.ActorError { + return rt.chargeGasInternal(toUse) +} + func (rt *Runtime) Pricelist() Pricelist { return rt.pricelist } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index da38fcbf3..42d6d373e 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -102,6 +102,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres pricelist: PricelistByEpoch(vm.blockHeight), allowInternal: true, callerValidated: false, + executionTrace: types.ExecutionTrace{Msg: msg}, } rt.cst = &cbor.BasicIpldStore{ @@ -163,14 +164,16 @@ type Rand interface { type ApplyRet struct { types.MessageReceipt - ActorErr aerrors.ActorError - Penalty types.BigInt - InternalExecutions []*types.ExecutionResult - Duration time.Duration + ActorErr aerrors.ActorError + Penalty types.BigInt + ExecutionTrace types.ExecutionTrace + Duration time.Duration } func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, gasCharge int64) ([]byte, aerrors.ActorError, *Runtime) { + start := time.Now() + st := vm.cstate gasUsed := gasCharge @@ -191,35 +194,50 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, }() } - if aerr := rt.chargeGasSafe(rt.Pricelist().OnMethodInvocation(msg.Value, msg.Method)); aerr != nil { - return nil, aerrors.Wrap(aerr, "not enough gas for method invocation"), rt - } + ret, err := func() ([]byte, aerrors.ActorError) { + if aerr := rt.chargeGasSafe(rt.Pricelist().OnMethodInvocation(msg.Value, msg.Method)); aerr != nil { + return nil, aerrors.Wrap(aerr, "not enough gas for method invocation") + } - toActor, err := st.GetActor(msg.To) - if err != nil { - if xerrors.Is(err, init_.ErrAddressNotFound) { - a, err := TryCreateAccountActor(rt, msg.To) - if err != nil { - return nil, aerrors.Wrapf(err, "could not create account"), rt + toActor, err := st.GetActor(msg.To) + if err != nil { + if xerrors.Is(err, init_.ErrAddressNotFound) { + a, err := TryCreateAccountActor(rt, msg.To) + if err != nil { + return nil, aerrors.Wrapf(err, "could not create account") + } + toActor = a + } else { + return nil, aerrors.Escalate(err, "getting actor") } - toActor = a - } else { - return nil, aerrors.Escalate(err, "getting actor"), rt } - } - if types.BigCmp(msg.Value, types.NewInt(0)) != 0 { - if err := vm.transfer(msg.From, msg.To, msg.Value); err != nil { - return nil, aerrors.Wrap(err, "failed to transfer funds"), nil + if types.BigCmp(msg.Value, types.NewInt(0)) != 0 { + if err := vm.transfer(msg.From, msg.To, msg.Value); err != nil { + return nil, aerrors.Wrap(err, "failed to transfer funds") + } } + + if msg.Method != 0 { + var ret []byte + ret, err := vm.Invoke(toActor, rt, msg.Method, msg.Params) + return ret, err + } + return nil, nil + }() + + mr := types.MessageReceipt{ + ExitCode: aerrors.RetCode(err), + Return: ret, + GasUsed: rt.gasUsed, + } + rt.executionTrace.MsgRct = &mr + rt.executionTrace.Duration = time.Since(start) + if err != nil { + rt.executionTrace.Error = err.Error() } - if msg.Method != 0 { - ret, err := vm.Invoke(toActor, rt, msg.Method, msg.Params) - return ret, err, rt - } - - return nil, nil, rt + return ret, err, rt } func checkMessage(msg *types.Message) error { @@ -250,10 +268,10 @@ func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*Ap Return: ret, GasUsed: 0, }, - ActorErr: actorErr, - InternalExecutions: rt.internalExecutions, - Penalty: types.NewInt(0), - Duration: time.Since(start), + ActorErr: actorErr, + ExecutionTrace: rt.executionTrace, + Penalty: types.NewInt(0), + Duration: time.Since(start), }, actorErr } @@ -419,10 +437,10 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, Return: ret, GasUsed: gasUsed, }, - ActorErr: actorErr, - InternalExecutions: rt.internalExecutions, - Penalty: types.NewInt(0), - Duration: time.Since(start), + ActorErr: actorErr, + ExecutionTrace: rt.executionTrace, + Penalty: types.NewInt(0), + Duration: time.Since(start), }, nil } diff --git a/cli/state.go b/cli/state.go index 6720ceacd..5b13c43b9 100644 --- a/cli/state.go +++ b/cli/state.go @@ -931,14 +931,14 @@ var stateComputeStateCmd = &cli.Command{ if cctx.Bool("show-trace") { for _, ir := range stout.Trace { fmt.Printf("%s\t%s\t%s\t%d\t%x\t%d\t%x\n", ir.Msg.From, ir.Msg.To, ir.Msg.Value, ir.Msg.Method, ir.Msg.Params, ir.MsgRct.ExitCode, ir.MsgRct.Return) - printInternalExecutions("\t", ir.InternalExecutions) + printInternalExecutions("\t", ir.ExecutionTrace.Subcalls) } } return nil }, } -func printInternalExecutions(prefix string, trace []*types.ExecutionResult) { +func printInternalExecutions(prefix string, trace []types.ExecutionTrace) { for _, im := range trace { fmt.Printf("%s%s\t%s\t%s\t%d\t%x\t%d\t%x\n", prefix, im.Msg.From, im.Msg.To, im.Msg.Value, im.Msg.Method, im.Msg.Params, im.MsgRct.ExitCode, im.MsgRct.Return) printInternalExecutions(prefix+"\t", im.Subcalls) @@ -1028,11 +1028,9 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( fmt.Printf(`
Error:
%s
`, ir.Error) } - if len(ir.InternalExecutions) > 0 { - fmt.Println("
Internal executions:
") - if err := printInternalExecutionsHtml(cid.String(), ir.InternalExecutions, getCode); err != nil { - return err - } + fmt.Println("
Execution trace:
") + if err := printInternalExecutionsHtml(cid.String(), ir.ExecutionTrace.Subcalls, getCode); err != nil { + return err } fmt.Println("
") } @@ -1042,7 +1040,7 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( return nil } -func printInternalExecutionsHtml(hashName string, trace []*types.ExecutionResult, getCode func(addr address.Address) (cid.Cid, error)) error { +func printInternalExecutionsHtml(hashName string, trace []types.ExecutionTrace, getCode func(addr address.Address) (cid.Cid, error)) error { for i, im := range trace { hashName := fmt.Sprintf("%s-r%d", hashName, i) diff --git a/go.mod b/go.mod index 21fea095f..5a3cf4a07 100644 --- a/go.mod +++ b/go.mod @@ -104,6 +104,7 @@ require ( github.com/multiformats/go-multibase v0.0.2 github.com/multiformats/go-multihash v0.0.13 github.com/opentracing/opentracing-go v1.1.0 + github.com/prometheus/common v0.9.1 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 diff --git a/go.sum b/go.sum index 35395be66..e10972bb6 100644 --- a/go.sum +++ b/go.sum @@ -42,9 +42,11 @@ github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE= 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/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= @@ -1575,6 +1577,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/node/impl/full/state.go b/node/impl/full/state.go index fae2a7b67..1d68a1858 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -242,11 +242,11 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid. } return &api.InvocResult{ - Msg: m, - MsgRct: &r.MessageReceipt, - InternalExecutions: r.InternalExecutions, - Error: errstr, - Duration: r.Duration, + Msg: m, + MsgRct: &r.MessageReceipt, + ExecutionTrace: r.ExecutionTrace, + Error: errstr, + Duration: r.Duration, }, nil } From 500ddd65859c224dce2fb39a00bf9e151e1d4073 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 11 Jun 2020 16:07:04 +0200 Subject: [PATCH 114/379] go mod tidy Signed-off-by: Jakub Sztandera --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index 5a3cf4a07..21fea095f 100644 --- a/go.mod +++ b/go.mod @@ -104,7 +104,6 @@ require ( github.com/multiformats/go-multibase v0.0.2 github.com/multiformats/go-multihash v0.0.13 github.com/opentracing/opentracing-go v1.1.0 - github.com/prometheus/common v0.9.1 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 From d4dbfdbe9191a2b17a660d97060522dbe749d708 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 9 Jun 2020 15:04:11 -0700 Subject: [PATCH 115/379] rename Config to GetConfig --- node/builder.go | 2 +- node/repo/interface.go | 2 +- node/repo/memrepo.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/builder.go b/node/builder.go index f503bff5c..87b39ba41 100644 --- a/node/builder.go +++ b/node/builder.go @@ -412,7 +412,7 @@ func Repo(r repo.Repo) Option { if err != nil { return err } - c, err := lr.Config() + c, err := lr.GetConfig() if err != nil { return err } diff --git a/node/repo/interface.go b/node/repo/interface.go index d81d644c7..002373e0e 100644 --- a/node/repo/interface.go +++ b/node/repo/interface.go @@ -37,7 +37,7 @@ type LockedRepo interface { Datastore(namespace string) (datastore.Batching, error) // Returns config in this repo - Config() (interface{}, error) + GetConfig() (interface{}, error) GetStorage() (stores.StorageConfig, error) SetStorage(func(*stores.StorageConfig)) error diff --git a/node/repo/memrepo.go b/node/repo/memrepo.go index 17eeb0253..1b1c716c2 100644 --- a/node/repo/memrepo.go +++ b/node/repo/memrepo.go @@ -217,7 +217,7 @@ func (lmem *lockedMemRepo) Datastore(ns string) (datastore.Batching, error) { return namespace.Wrap(lmem.mem.datastore, datastore.NewKey(ns)), nil } -func (lmem *lockedMemRepo) Config() (interface{}, error) { +func (lmem *lockedMemRepo) GetConfig() (interface{}, error) { if err := lmem.checkToken(); err != nil { return nil, err } From 2d6b2e381148241e3def4ce1f7058fc04bb08fc6 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 9 Jun 2020 16:30:30 -0700 Subject: [PATCH 116/379] fix a spelling error --- node/config/load.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/config/load.go b/node/config/load.go index 1590efedb..b0786643f 100644 --- a/node/config/load.go +++ b/node/config/load.go @@ -12,7 +12,7 @@ import ( ) // FromFile loads config from a specified file overriding defaults specified in -// the def parameter. If file does not exist or is empty defaults are asummed. +// the def parameter. If file does not exist or is empty defaults are assumed. func FromFile(path string, def interface{}) (interface{}, error) { file, err := os.Open(path) switch { From cf321f76678ab3850c4d1471c10ce3dfc9cedab7 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 9 Jun 2020 16:37:18 -0700 Subject: [PATCH 117/379] add support for replacing config after node starts - TODO: does a "locked repo" need fine-grained (i.e. field-level) locking? --- node/builder.go | 2 +- node/repo/fsrepo.go | 24 ++++++++++++++++++++++++ node/repo/interface.go | 3 ++- node/repo/memrepo.go | 22 +++++++++++++++++++--- node/repo/repo_test.go | 18 ++++++++++++++++-- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/node/builder.go b/node/builder.go index 87b39ba41..f503bff5c 100644 --- a/node/builder.go +++ b/node/builder.go @@ -412,7 +412,7 @@ func Repo(r repo.Repo) Option { if err != nil { return err } - c, err := lr.GetConfig() + c, err := lr.Config() if err != nil { return err } diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 6733b0868..a0530f0f7 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -11,6 +11,7 @@ import ( "strings" "sync" + "github.com/BurntSushi/toml" "github.com/ipfs/go-datastore" fslock "github.com/ipfs/go-fs-lock" logging "github.com/ipfs/go-log/v2" @@ -271,6 +272,29 @@ func (fsr *fsLockedRepo) Config() (interface{}, error) { return config.FromFile(fsr.join(fsConfig), defConfForType(fsr.repoType)) } +func (fsr *fsLockedRepo) SetConfig(cfg interface{}) error { + if err := fsr.stillValid(); err != nil { + return err + } + + tmp, err := ioutil.TempFile("", "lotus-config-temp") + if err != nil { + return err + } + + err = toml.NewEncoder(tmp).Encode(cfg) + if err != nil { + return err + } + + err = os.Rename(tmp.Name(), fsr.join(fsConfig)) + if err != nil { + return err + } + + return nil +} + func (fsr *fsLockedRepo) GetStorage() (stores.StorageConfig, error) { fsr.storageLk.Lock() defer fsr.storageLk.Unlock() diff --git a/node/repo/interface.go b/node/repo/interface.go index 002373e0e..560cd969c 100644 --- a/node/repo/interface.go +++ b/node/repo/interface.go @@ -37,7 +37,8 @@ type LockedRepo interface { Datastore(namespace string) (datastore.Batching, error) // Returns config in this repo - GetConfig() (interface{}, error) + Config() (interface{}, error) + SetConfig(interface{}) error GetStorage() (stores.StorageConfig, error) SetStorage(func(*stores.StorageConfig)) error diff --git a/node/repo/memrepo.go b/node/repo/memrepo.go index 1b1c716c2..d942b6bd9 100644 --- a/node/repo/memrepo.go +++ b/node/repo/memrepo.go @@ -30,8 +30,13 @@ type MemRepo struct { token *byte datastore datastore.Datastore - configF func(t RepoType) interface{} keystore map[string]types.KeyInfo + + // given a repo type, produce the default config + configF func(t RepoType) interface{} + + // holds the current config value + config interface{} } type lockedMemRepo struct { @@ -217,11 +222,22 @@ func (lmem *lockedMemRepo) Datastore(ns string) (datastore.Batching, error) { return namespace.Wrap(lmem.mem.datastore, datastore.NewKey(ns)), nil } -func (lmem *lockedMemRepo) GetConfig() (interface{}, error) { +func (lmem *lockedMemRepo) Config() (interface{}, error) { if err := lmem.checkToken(); err != nil { return nil, err } - return lmem.mem.configF(lmem.t), nil + + if lmem.mem.config == nil { + lmem.mem.config = lmem.mem.configF(lmem.t) + } + + return lmem.mem.config, nil +} + +func (lmem *lockedMemRepo) SetConfig(cfg interface{}) error { + lmem.mem.config = cfg + + return nil } func (lmem *lockedMemRepo) Storage() (stores.StorageConfig, error) { diff --git a/node/repo/repo_test.go b/node/repo/repo_test.go index 9c43e8f4b..5da4bcadc 100644 --- a/node/repo/repo_test.go +++ b/node/repo/repo_test.go @@ -9,6 +9,8 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/config" + + "github.com/stretchr/testify/require" ) func basicTest(t *testing.T, repo Repo) { @@ -47,10 +49,22 @@ func basicTest(t *testing.T, repo Repo) { assert.NoError(t, err, "setting multiaddr shouldn't error") assert.Equal(t, ma, apima, "returned API multiaddr should be the same") - cfg, err := lrepo.Config() - assert.Equal(t, config.DefaultFullNode(), cfg, "there should be a default config") + c1, err := lrepo.Config() + assert.Equal(t, config.DefaultFullNode(), c1, "there should be a default config") assert.NoError(t, err, "config should not error") + // mutate config and persist back to repo + cfg1 := c1.(*config.FullNode) + cfg1.Client.IpfsMAddr = "duvall" + err = lrepo.SetConfig(cfg1) + assert.NoError(t, err) + + // load config and verify changes + c2, err := lrepo.Config() + require.NoError(t, err) + cfg2 := c2.(*config.FullNode) + require.Equal(t, cfg2.Client.IpfsMAddr, "duvall") + err = lrepo.Close() assert.NoError(t, err, "should be able to close") From fb1d5197fa8a39cae762c43e2c72566d455794ff Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 10 Jun 2020 09:07:47 -0700 Subject: [PATCH 118/379] pass SetConfig a mutator func, as per PR feedback - fsLockedRepo.config gets a mutex - add missing checkToken call to lockedMemRepo#GetStorage and lockedMemRepo#SetStorage - LockedRepo#SetConfig accepts a mutating function as per @magik --- node/repo/fsrepo.go | 30 +++++++++++++++++++++++------- node/repo/interface.go | 2 +- node/repo/memrepo.go | 41 +++++++++++++++++++++++++++++++---------- node/repo/repo_test.go | 7 ++++--- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index a0530f0f7..b223731d9 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -230,6 +230,7 @@ type fsLockedRepo struct { dsOnce sync.Once storageLk sync.Mutex + configLk sync.Mutex } func (fsr *fsLockedRepo) Path() string { @@ -266,28 +267,43 @@ func (fsr *fsLockedRepo) stillValid() error { } func (fsr *fsLockedRepo) Config() (interface{}, error) { - if err := fsr.stillValid(); err != nil { - return nil, err - } + fsr.configLk.Lock() + defer fsr.configLk.Unlock() + + return fsr.loadConfigFromDisk() +} + +func (fsr *fsLockedRepo) loadConfigFromDisk() (interface{}, error) { return config.FromFile(fsr.join(fsConfig), defConfForType(fsr.repoType)) } -func (fsr *fsLockedRepo) SetConfig(cfg interface{}) error { +func (fsr *fsLockedRepo) SetConfig(c func(interface{})) error { if err := fsr.stillValid(); err != nil { return err } - tmp, err := ioutil.TempFile("", "lotus-config-temp") + fsr.configLk.Lock() + defer fsr.configLk.Unlock() + + cfg, err := fsr.loadConfigFromDisk() if err != nil { return err } - err = toml.NewEncoder(tmp).Encode(cfg) + // mutate in-memory representation of config + c(cfg) + + // buffer into which we write TOML bytes + buf := new(bytes.Buffer) + + // encode now-mutated config as TOML and write to buffer + err = toml.NewEncoder(buf).Encode(cfg) if err != nil { return err } - err = os.Rename(tmp.Name(), fsr.join(fsConfig)) + // write buffer of TOML bytes to config file + err = ioutil.WriteFile(fsr.join(fsConfig), buf.Bytes(), 0644) if err != nil { return err } diff --git a/node/repo/interface.go b/node/repo/interface.go index 560cd969c..5950f813f 100644 --- a/node/repo/interface.go +++ b/node/repo/interface.go @@ -38,7 +38,7 @@ type LockedRepo interface { // Returns config in this repo Config() (interface{}, error) - SetConfig(interface{}) error + SetConfig(func(interface{})) error GetStorage() (stores.StorageConfig, error) SetStorage(func(*stores.StorageConfig)) error diff --git a/node/repo/memrepo.go b/node/repo/memrepo.go index d942b6bd9..399b239c1 100644 --- a/node/repo/memrepo.go +++ b/node/repo/memrepo.go @@ -36,7 +36,10 @@ type MemRepo struct { configF func(t RepoType) interface{} // holds the current config value - config interface{} + config struct { + sync.Mutex + val interface{} + } } type lockedMemRepo struct { @@ -50,6 +53,10 @@ type lockedMemRepo struct { } func (lmem *lockedMemRepo) GetStorage() (stores.StorageConfig, error) { + if err := lmem.checkToken(); err != nil { + return stores.StorageConfig{}, err + } + if lmem.sc == nil { lmem.sc = &stores.StorageConfig{StoragePaths: []stores.LocalPath{ {Path: lmem.Path()}, @@ -60,6 +67,10 @@ func (lmem *lockedMemRepo) GetStorage() (stores.StorageConfig, error) { } func (lmem *lockedMemRepo) SetStorage(c func(*stores.StorageConfig)) error { + if err := lmem.checkToken(); err != nil { + return err + } + _, _ = lmem.GetStorage() c(lmem.sc) @@ -227,23 +238,33 @@ func (lmem *lockedMemRepo) Config() (interface{}, error) { return nil, err } - if lmem.mem.config == nil { - lmem.mem.config = lmem.mem.configF(lmem.t) + lmem.mem.config.Lock() + defer lmem.mem.config.Unlock() + + if lmem.mem.config.val == nil { + lmem.mem.config.val = lmem.mem.configF(lmem.t) } - return lmem.mem.config, nil + return lmem.mem.config.val, nil } -func (lmem *lockedMemRepo) SetConfig(cfg interface{}) error { - lmem.mem.config = cfg +func (lmem *lockedMemRepo) SetConfig(c func(interface{})) error { + if err := lmem.checkToken(); err != nil { + return err + } + + lmem.mem.config.Lock() + defer lmem.mem.config.Unlock() + + if lmem.mem.config.val == nil { + lmem.mem.config.val = lmem.mem.configF(lmem.t) + } + + c(lmem.mem.config.val) return nil } -func (lmem *lockedMemRepo) Storage() (stores.StorageConfig, error) { - panic("implement me") -} - func (lmem *lockedMemRepo) SetAPIEndpoint(ma multiaddr.Multiaddr) error { if err := lmem.checkToken(); err != nil { return err diff --git a/node/repo/repo_test.go b/node/repo/repo_test.go index 5da4bcadc..444fab267 100644 --- a/node/repo/repo_test.go +++ b/node/repo/repo_test.go @@ -54,9 +54,10 @@ func basicTest(t *testing.T, repo Repo) { assert.NoError(t, err, "config should not error") // mutate config and persist back to repo - cfg1 := c1.(*config.FullNode) - cfg1.Client.IpfsMAddr = "duvall" - err = lrepo.SetConfig(cfg1) + err = lrepo.SetConfig(func(c interface{}) { + cfg := c.(*config.FullNode) + cfg.Client.IpfsMAddr = "duvall" + }) assert.NoError(t, err) // load config and verify changes From 8354bd91db08764128f8d0d2abba576a5c3d9f9c Mon Sep 17 00:00:00 2001 From: waynewyang Date: Thu, 11 Jun 2020 23:52:44 +0800 Subject: [PATCH 119/379] fix:the condition of time-offset mining fault --- chain/vm/syscalls.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index 143807ab4..2349bc324 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -115,7 +115,7 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.Consen // (b) time-offset mining fault // strictly speaking no need to compare heights based on double fork mining check above, // but at same height this would be a different fault. - if !types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height { + if types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height { consensusFault = &runtime.ConsensusFault{ Target: blockA.Miner, Epoch: blockB.Height, @@ -159,7 +159,7 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.Consen } if sigErr := ss.VerifyBlockSig(&blockB); sigErr != nil { - return nil, xerrors.Errorf("cannot verify first block sig: %w", sigErr) + return nil, xerrors.Errorf("cannot verify second block sig: %w", sigErr) } return consensusFault, nil From d6b2519843ffe12657b8b9c2d7f5fd89cb57223c Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 11 Jun 2020 11:29:59 -0700 Subject: [PATCH 120/379] config-driven IsAcceptingStorageDeals flag Makes incremental progress towards #1920. --- node/builder.go | 1 + node/config/def.go | 7 ++++++- node/modules/dtypes/miner.go | 4 ++++ node/modules/storageminer.go | 34 ++++++++++++++++++++++++++++++++-- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/node/builder.go b/node/builder.go index f503bff5c..adbb25efe 100644 --- a/node/builder.go +++ b/node/builder.go @@ -313,6 +313,7 @@ func Online() Option { Override(HandleDealsKey, modules.HandleDeals), Override(new(gen.WinningPoStProver), storage.NewWinningPoStProver), Override(new(*miner.Miner), modules.SetupBlockProducer), + Override(new(dtypes.IsAcceptingStorageDealsFunc), modules.NewIsAcceptingStorageDealsFunc), ), ) } diff --git a/node/config/def.go b/node/config/def.go index 9ca97bb47..a1b03b899 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -27,7 +27,12 @@ type FullNode struct { type StorageMiner struct { Common - Storage sectorstorage.SealerConfig + StorageDeals StorageDealConfig + Storage sectorstorage.SealerConfig +} + +type StorageDealConfig struct { + IsAcceptingStorageDeals bool } // API contains configs for API endpoint diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index c872fdf69..9a3fcc2cd 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -7,3 +7,7 @@ import ( type MinerAddress address.Address type MinerID abi.ActorID + +// IsAcceptingStorageDealsFunc is a function which reads from miner config to +// determine if the user has disabled storage deals (or not). +type IsAcceptingStorageDealsFunc func() (bool, error) diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 1d358628b..4fd1443d1 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -35,6 +35,7 @@ import ( paramfetch "github.com/filecoin-project/go-paramfetch" "github.com/filecoin-project/go-statestore" "github.com/filecoin-project/go-storedcounter" + "github.com/filecoin-project/lotus/node/config" sectorstorage "github.com/filecoin-project/sector-storage" "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/sector-storage/stores" @@ -304,14 +305,27 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return storedAsk, nil } -func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode) (storagemarket.StorageProvider, error) { +func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingStorageDealsFunc dtypes.IsAcceptingStorageDealsFunc) (storagemarket.StorageProvider, error) { net := smnet.NewFromLibp2pHost(h) store, err := piecefilestore.NewLocalFileStore(piecefilestore.OsPath(r.Path())) if err != nil { return nil, err } - p, err := storageimpl.NewProvider(net, namespace.Wrap(ds, datastore.NewKey("/deals/provider")), ibs, store, pieceStore, dataTransfer, spn, address.Address(minerAddress), ffiConfig.SealProofType, storedAsk) + opt := storageimpl.CustomDealDecisionLogic(func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) { + willEntertainProposals, err := isAcceptingStorageDealsFunc() + if err != nil { + return false, "IsAcceptingStorageDealsFunc error", err + } + + if !willEntertainProposals { + return false, "user has disabled storage deals", nil + } + + return true, "", nil + }) + + p, err := storageimpl.NewProvider(net, namespace.Wrap(ds, datastore.NewKey("/deals/provider")), ibs, store, pieceStore, dataTransfer, spn, address.Address(minerAddress), ffiConfig.SealProofType, storedAsk, opt) if err != nil { return p, err } @@ -361,3 +375,19 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA headers.Add("Authorization", "Bearer "+string(token)) return sectorstorage.StorageAuth(headers), nil } + +func NewIsAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.IsAcceptingStorageDealsFunc, error) { + return func() (bool, error) { + raw, err := r.Config() + if err != nil { + return false, err + } + + cfg, ok := raw.(*config.StorageMiner) + if !ok { + return false, xerrors.New("expected address of config.StorageMiner") + } + + return cfg.StorageDeals.IsAcceptingStorageDeals, nil + }, nil +} From 6acc9a62f83450eb51e22c5062b82730d482f41b Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 11 Jun 2020 20:37:14 +0200 Subject: [PATCH 121/379] Split gas internally into compute gas and storage gas Signed-off-by: Jakub Sztandera --- chain/vm/gas.go | 53 ++++++++++++++++++++++++++++++------------ chain/vm/gas_v0.go | 56 +++++++++++++++++++++++---------------------- chain/vm/runtime.go | 11 +++++---- chain/vm/vm.go | 4 ++-- 4 files changed, 75 insertions(+), 49 deletions(-) diff --git a/chain/vm/gas.go b/chain/vm/gas.go index f1cf89845..c030621f6 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -12,34 +12,57 @@ import ( "github.com/ipfs/go-cid" ) +const ( + GasStorageMulti = 1 + GasComputeMulti = 1 +) + +type GasCharge struct { + Name string + ComputeGas int64 + StorageGas int64 +} + +func (g GasCharge) Total() int64 { + return g.ComputeGas*GasComputeMulti + g.StorageGas*GasStorageMulti +} + +func newGasCharge(name string, computeGas int64, storageGas int64) GasCharge { + return GasCharge{ + Name: name, + ComputeGas: computeGas, + StorageGas: storageGas, + } +} + // Pricelist provides prices for operations in the VM. // // Note: this interface should be APPEND ONLY since last chain checkpoint type Pricelist interface { // OnChainMessage returns the gas used for storing a message of a given size in the chain. - OnChainMessage(msgSize int) int64 + OnChainMessage(msgSize int) GasCharge // OnChainReturnValue returns the gas used for storing the response of a message in the chain. - OnChainReturnValue(dataSize int) int64 + OnChainReturnValue(dataSize int) GasCharge // OnMethodInvocation returns the gas used when invoking a method. - OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) int64 + OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge // OnIpldGet returns the gas used for storing an object - OnIpldGet(dataSize int) int64 + OnIpldGet(dataSize int) GasCharge // OnIpldPut returns the gas used for storing an object - OnIpldPut(dataSize int) int64 + OnIpldPut(dataSize int) GasCharge // OnCreateActor returns the gas used for creating an actor - OnCreateActor() int64 + OnCreateActor() GasCharge // OnDeleteActor returns the gas used for deleting an actor - OnDeleteActor() int64 + OnDeleteActor() GasCharge - OnVerifySignature(sigType crypto.SigType, planTextSize int) (int64, error) - OnHashing(dataSize int) int64 - OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) int64 - OnVerifySeal(info abi.SealVerifyInfo) int64 - OnVerifyPost(info abi.WindowPoStVerifyInfo) int64 - OnVerifyConsensusFault() int64 + OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error) + OnHashing(dataSize int) GasCharge + OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) GasCharge + OnVerifySeal(info abi.SealVerifyInfo) GasCharge + OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge + OnVerifyConsensusFault() GasCharge } var prices = map[abi.ChainEpoch]Pricelist{ @@ -93,7 +116,7 @@ func PricelistByEpoch(epoch abi.ChainEpoch) Pricelist { type pricedSyscalls struct { under vmr.Syscalls pl Pricelist - chargeGas func(int64) + chargeGas func(GasCharge) } // Verifies that a signature is valid for an address and plaintext. @@ -146,6 +169,6 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte } func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { - ps.chargeGas(0) // TODO: this is only called by the cron actor. Should we even charge gas? + ps.chargeGas(newGasCharge("BatchVerifySeals", 0, 0)) // TODO: this is only called by the cron actor. Should we even charge gas? return ps.under.BatchVerifySeals(inp) } diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index a20ac927d..0b6196377 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -2,6 +2,7 @@ package vm import ( "fmt" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/crypto" @@ -84,17 +85,17 @@ type pricelistV0 struct { var _ Pricelist = (*pricelistV0)(nil) // OnChainMessage returns the gas used for storing a message of a given size in the chain. -func (pl *pricelistV0) OnChainMessage(msgSize int) int64 { - return pl.onChainMessageBase + pl.onChainMessagePerByte*int64(msgSize) +func (pl *pricelistV0) OnChainMessage(msgSize int) GasCharge { + return newGasCharge("OnChainMessage", 0, pl.onChainMessageBase+pl.onChainMessagePerByte*int64(msgSize)) } // OnChainReturnValue returns the gas used for storing the response of a message in the chain. -func (pl *pricelistV0) OnChainReturnValue(dataSize int) int64 { - return int64(dataSize) * pl.onChainReturnValuePerByte +func (pl *pricelistV0) OnChainReturnValue(dataSize int) GasCharge { + return newGasCharge("OnChainReturnValue", 0, int64(dataSize)*pl.onChainReturnValuePerByte) } // OnMethodInvocation returns the gas used when invoking a method. -func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) int64 { +func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge { ret := pl.sendBase if value != abi.NewTokenAmount(0) { ret += pl.sendTransferFunds @@ -102,62 +103,63 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M if methodNum != builtin.MethodSend { ret += pl.sendInvokeMethod } - return ret + return newGasCharge("OnMethodInvocation", ret, 0) } // OnIpldGet returns the gas used for storing an object -func (pl *pricelistV0) OnIpldGet(dataSize int) int64 { - return pl.ipldGetBase + int64(dataSize)*pl.ipldGetPerByte +func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge { + return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0) } // OnIpldPut returns the gas used for storing an object -func (pl *pricelistV0) OnIpldPut(dataSize int) int64 { - return pl.ipldPutBase + int64(dataSize)*pl.ipldPutPerByte +func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge { + return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte) } // OnCreateActor returns the gas used for creating an actor -func (pl *pricelistV0) OnCreateActor() int64 { - return pl.createActorBase + pl.createActorExtra +func (pl *pricelistV0) OnCreateActor() GasCharge { + return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra) } // OnDeleteActor returns the gas used for deleting an actor -func (pl *pricelistV0) OnDeleteActor() int64 { - return pl.deleteActor +func (pl *pricelistV0) OnDeleteActor() GasCharge { + return newGasCharge("OnDeleteActor", 0, pl.deleteActor) } // OnVerifySignature -func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize int) (int64, error) { +func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error) { costFn, ok := pl.verifySignature[sigType] if !ok { - return 0, fmt.Errorf("cost function for signature type %d not supported", sigType) + return GasCharge{}, fmt.Errorf("cost function for signature type %d not supported", sigType) } - return costFn(int64(planTextSize)), nil + sigName, _ := sigType.Name() + return newGasCharge("OnVerifySignature/"+sigName, costFn(int64(planTextSize)), 0), nil } // OnHashing -func (pl *pricelistV0) OnHashing(dataSize int) int64 { - return pl.hashingBase + int64(dataSize)*pl.hashingPerByte +func (pl *pricelistV0) OnHashing(dataSize int) GasCharge { + return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0) } // OnComputeUnsealedSectorCid -func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) int64 { +func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return pl.computeUnsealedSectorCidBase + return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0) } // OnVerifySeal -func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) int64 { +func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return pl.verifySealBase + return newGasCharge("OnVerifySeal", pl.verifySealBase, 0) } // OnVerifyPost -func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) int64 { +func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return pl.verifyPostBase + return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0) } // OnVerifyConsensusFault -func (pl *pricelistV0) OnVerifyConsensusFault() int64 { - return pl.verifyConsensusFault +func (pl *pricelistV0) OnVerifyConsensusFault() GasCharge { + return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0) } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 70583e47f..ae3a60616 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -484,14 +484,15 @@ func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError { return nil } -func (rt *Runtime) ChargeGas(toUse int64) { - err := rt.chargeGasInternal(toUse) +func (rt *Runtime) ChargeGas(gas GasCharge) { + err := rt.chargeGasInternal(gas) if err != nil { panic(err) } } -func (rt *Runtime) chargeGasInternal(toUse int64) aerrors.ActorError { +func (rt *Runtime) chargeGasInternal(gas GasCharge) aerrors.ActorError { + toUse := gas.Total() if rt.gasUsed+toUse > rt.gasAvailable { rt.gasUsed = rt.gasAvailable return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d", rt.gasUsed, rt.gasAvailable) @@ -500,8 +501,8 @@ func (rt *Runtime) chargeGasInternal(toUse int64) aerrors.ActorError { return nil } -func (rt *Runtime) chargeGasSafe(toUse int64) aerrors.ActorError { - return rt.chargeGasInternal(toUse) +func (rt *Runtime) chargeGasSafe(gas GasCharge) aerrors.ActorError { + return rt.chargeGasInternal(gas) } func (rt *Runtime) Pricelist() Pricelist { diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 42d6d373e..11db0d419 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -62,7 +62,7 @@ func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Ad var _ cbor.IpldBlockstore = (*gasChargingBlocks)(nil) type gasChargingBlocks struct { - chargeGas func(int64) + chargeGas func(GasCharge) pricelist Pricelist under cbor.IpldBlockstore } @@ -294,7 +294,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, pl := PricelistByEpoch(vm.blockHeight) - msgGasCost := pl.OnChainMessage(cmsg.ChainLength()) + msgGasCost := pl.OnChainMessage(cmsg.ChainLength()).Total() // this should never happen, but is currently still exercised by some tests if msgGasCost > msg.GasLimit { return &ApplyRet{ From 0200e3def59c0f4bd7a942694503b9368d5b647c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 11 Jun 2020 20:33:15 +0200 Subject: [PATCH 122/379] wdpost: Submit recoveries for sectors within a deadline --- storage/wdpost_run.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 8cd9fdc5f..3a55356ba 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -111,7 +111,7 @@ func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check *abi.BitFi return &sbf, nil } -func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, deadline uint64, ts *types.TipSet) error { +func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, deadline uint64, deadlineSectors *abi.BitField, ts *types.TipSet) error { faults, err := s.api.StateMinerFaults(ctx, s.actor, ts.Key()) if err != nil { return xerrors.Errorf("getting on-chain faults: %w", err) @@ -136,6 +136,11 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, deadline return xerrors.Errorf("subtracting recovered set from fault set: %w", err) } + unrecovered, err = bitfield.IntersectBitField(unrecovered, deadlineSectors) + if err != nil { + return xerrors.Errorf("intersect unrecovered set with deadlineSectors: %w", err) + } + uc, err := unrecovered.Count() if err != nil { return xerrors.Errorf("counting unrecovered sectors: %w", err) @@ -326,7 +331,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo // late to declare them for this deadline declDeadline := (di.Index + 1) % miner.WPoStPeriodDeadlines - if err := s.checkNextRecoveries(ctx, declDeadline, ts); err != nil { + if err := s.checkNextRecoveries(ctx, declDeadline, deadlines.Due[declDeadline], ts); err != nil { // TODO: This is potentially quite bad, but not even trying to post when this fails is objectively worse log.Errorf("checking sector recoveries: %v", err) } From c458b4712a806639ba9dcdb3c64c0133d19f31a2 Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 11 Jun 2020 12:06:38 -0700 Subject: [PATCH 123/379] better rejection messages --- node/modules/storageminer.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 4fd1443d1..0b3f12586 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -315,11 +315,12 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con opt := storageimpl.CustomDealDecisionLogic(func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) { willEntertainProposals, err := isAcceptingStorageDealsFunc() if err != nil { - return false, "IsAcceptingStorageDealsFunc error", err + return false, "miner error", err } if !willEntertainProposals { - return false, "user has disabled storage deals", nil + log.Warnf("storage deal acceptance disabled; rejecting storage deal proposal from client: %s", deal.Client.String()) + return false, "miner is not accepting storage deals", nil } return true, "", nil From 5421d0d1c58093ba5fb2b6e20ce522dce1627994 Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 11 Jun 2020 12:15:28 -0700 Subject: [PATCH 124/379] better field and struct names + set default appropriately Storage miners, by default, should be configured to accept storage deals. --- node/config/def.go | 10 +++++++--- node/modules/storageminer.go | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/node/config/def.go b/node/config/def.go index a1b03b899..3debfd64e 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -27,11 +27,11 @@ type FullNode struct { type StorageMiner struct { Common - StorageDeals StorageDealConfig - Storage sectorstorage.SealerConfig + Dealmaking DealmakingConfig + Storage sectorstorage.SealerConfig } -type StorageDealConfig struct { +type DealmakingConfig struct { IsAcceptingStorageDeals bool } @@ -114,6 +114,10 @@ func DefaultStorageMiner() *StorageMiner { AllowCommit: true, AllowUnseal: true, }, + + Dealmaking: DealmakingConfig{ + IsAcceptingStorageDeals: true, + }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" cfg.Common.API.RemoteListenAddress = "127.0.0.1:2345" diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 0b3f12586..3719f621a 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -389,6 +389,6 @@ func NewIsAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.IsAcceptingStorag return false, xerrors.New("expected address of config.StorageMiner") } - return cfg.StorageDeals.IsAcceptingStorageDeals, nil + return cfg.Dealmaking.IsAcceptingStorageDeals, nil }, nil } From 67110ce739a11f9e6e35598ea156bd7381a90938 Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 11 Jun 2020 12:20:11 -0700 Subject: [PATCH 125/379] stub enable/disable storage deal commands --- cmd/lotus-storage-miner/main.go | 2 ++ cmd/lotus-storage-miner/market.go | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index ba7722e4e..9ade0a41b 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -33,6 +33,8 @@ func main() { setPriceCmd, workersCmd, provingCmd, + enableCmd, + disableCmd, } jaeger := tracing.SetupJaegerTracing("lotus") defer func() { diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 68b626360..cc0b84298 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -10,6 +10,24 @@ import ( "github.com/urfave/cli/v2" ) +var enableCmd = &cli.Command{ + Name: "enable", + Usage: "Configure the miner to consider storage deal proposals", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + panic("enable storage deals") + }, +} + +var disableCmd = &cli.Command{ + Name: "disable", + Usage: "Configure the miner to reject all storage deal proposals", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + panic("disable storage deals") + }, +} + var setPriceCmd = &cli.Command{ Name: "set-price", Usage: "Set price that miner will accept storage deals at (FIL / GiB / Epoch)", From c90d35869bd74ab1992971a9f1ed62419313838b Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 11 Jun 2020 21:59:39 +0200 Subject: [PATCH 126/379] Add gas tracing Signed-off-by: Jakub Sztandera --- chain/sync.go | 2 +- chain/types/execresult.go | 55 +++++++++++++++++++++++++++++++++++---- chain/vm/runtime.go | 38 +++++++++++++++++++++++---- chain/vm/vm.go | 40 +++++++++++++++++++--------- cli/state.go | 15 +++++++++++ miner/miner.go | 2 +- 6 files changed, 127 insertions(+), 25 deletions(-) diff --git a/chain/sync.go b/chain/sync.go index 03ccc3ab7..f4b32f2bc 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -857,7 +857,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock // Phase 1: syntactic validation, as defined in the spec minGas := vm.PricelistByEpoch(baseTs.Height()).OnChainMessage(msg.ChainLength()) - if err := m.ValidForBlockInclusion(minGas); err != nil { + if err := m.ValidForBlockInclusion(minGas.Total()); err != nil { return err } diff --git a/chain/types/execresult.go b/chain/types/execresult.go index dd5c8fa3e..41372b832 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -1,12 +1,57 @@ package types -import "time" +import ( + "encoding/json" + "fmt" + "runtime" + "strings" + "time" +) type ExecutionTrace struct { - Msg *Message - MsgRct *MessageReceipt - Error string - Duration time.Duration + Msg *Message + MsgRct *MessageReceipt + Error string + Duration time.Duration + GasCharges []*GasTrace Subcalls []ExecutionTrace } + +type GasTrace struct { + Name string + Location string + TotalGas int64 + ComputeGas int64 + StorageGas int64 + + TimeTaken time.Duration + + Callers []uintptr `json:"-"` +} + +func (gt *GasTrace) MarshalJSON() ([]byte, error) { + type GasTraceCopy GasTrace + if gt.Location == "" { + if len(gt.Callers) != 0 { + frames := runtime.CallersFrames(gt.Callers) + for { + frame, more := frames.Next() + fn := strings.Split(frame.Function, "/") + + split := strings.Split(frame.File, "/") + file := strings.Join(split[len(split)-2:], "/") + gt.Location += fmt.Sprintf("%s@%s:%d", fn[len(fn)-1], file, frame.Line) + if !more { + break + } + gt.Location += "|" + } + } else { + gt.Location = "n/a" + } + } + + cpy := (*GasTraceCopy)(gt) + return json.Marshal(cpy) +} diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index ae3a60616..902ef94bb 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -5,6 +5,8 @@ import ( "context" "encoding/binary" "fmt" + gruntime "runtime" + "time" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" @@ -50,10 +52,12 @@ type Runtime struct { origin address.Address originNonce uint64 - executionTrace types.ExecutionTrace - numActorsCreated uint64 - allowInternal bool - callerValidated bool + executionTrace types.ExecutionTrace + numActorsCreated uint64 + allowInternal bool + callerValidated bool + lastGasChargeTime time.Time + lastGasCharge *types.GasTrace } func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount { @@ -392,7 +396,7 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, } defer st.ClearSnapshot() - ret, errSend, subrt := rt.vm.send(ctx, msg, rt, 0) + ret, errSend, subrt := rt.vm.send(ctx, msg, rt, nil) if errSend != nil { if errRevert := st.Revert(); errRevert != nil { return nil, aerrors.Escalate(errRevert, "failed to revert state tree after failed subcall") @@ -490,9 +494,33 @@ func (rt *Runtime) ChargeGas(gas GasCharge) { panic(err) } } +func (rt *Runtime) finilizeGasTracing() { + if rt.lastGasCharge != nil { + rt.lastGasCharge.TimeTaken = time.Since(rt.lastGasChargeTime) + } +} func (rt *Runtime) chargeGasInternal(gas GasCharge) aerrors.ActorError { toUse := gas.Total() + var callers [3]uintptr + cout := gruntime.Callers(3, callers[:]) + + now := time.Now() + if rt.lastGasCharge != nil { + rt.lastGasCharge.TimeTaken = now.Sub(rt.lastGasChargeTime) + } + + gasTrace := types.GasTrace{ + Name: gas.Name, + TotalGas: toUse, + ComputeGas: gas.ComputeGas, + StorageGas: gas.StorageGas, + Callers: callers[:cout], + } + rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace) + rt.lastGasChargeTime = now + rt.lastGasCharge = &gasTrace + if rt.gasUsed+toUse > rt.gasAvailable { rt.gasUsed = rt.gasAvailable return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d", rt.gasUsed, rt.gasAvailable) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 11db0d419..75bbdfedb 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -96,13 +96,14 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres originNonce: originNonce, height: vm.blockHeight, - gasUsed: usedGas, - gasAvailable: msg.GasLimit, - numActorsCreated: nac, - pricelist: PricelistByEpoch(vm.blockHeight), - allowInternal: true, - callerValidated: false, - executionTrace: types.ExecutionTrace{Msg: msg}, + gasUsed: usedGas, + gasAvailable: msg.GasLimit, + numActorsCreated: nac, + pricelist: PricelistByEpoch(vm.blockHeight), + allowInternal: true, + callerValidated: false, + executionTrace: types.ExecutionTrace{Msg: msg}, + lastGasChargeTime: time.Now(), } rt.cst = &cbor.BasicIpldStore{ @@ -171,17 +172,17 @@ type ApplyRet struct { } func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, - gasCharge int64) ([]byte, aerrors.ActorError, *Runtime) { + gasCharge *GasCharge) ([]byte, aerrors.ActorError, *Runtime) { start := time.Now() st := vm.cstate - gasUsed := gasCharge origin := msg.From on := msg.Nonce var nac uint64 = 0 + var gasUsed int64 if parent != nil { - gasUsed = parent.gasUsed + gasUsed + gasUsed = parent.gasUsed origin = parent.origin on = parent.originNonce nac = parent.numActorsCreated @@ -189,11 +190,22 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac) if parent != nil { + rt.lastGasChargeTime = parent.lastGasChargeTime + rt.lastGasCharge = parent.lastGasCharge defer func() { parent.gasUsed = rt.gasUsed + parent.lastGasChargeTime = rt.lastGasChargeTime + parent.lastGasCharge = rt.lastGasCharge }() } + if gasCharge != nil { + if err := rt.chargeGasSafe(*gasCharge); err != nil { + // this should never happen + return nil, aerrors.Wrap(err, "not enough gas for initial message charge, this should not happen"), rt + } + } + ret, err := func() ([]byte, aerrors.ActorError) { if aerr := rt.chargeGasSafe(rt.Pricelist().OnMethodInvocation(msg.Value, msg.Method)); aerr != nil { return nil, aerrors.Wrap(aerr, "not enough gas for method invocation") @@ -261,7 +273,7 @@ func checkMessage(msg *types.Message) error { func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) { start := time.Now() - ret, actorErr, rt := vm.send(ctx, msg, nil, 0) + ret, actorErr, rt := vm.send(ctx, msg, nil, nil) return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: aerrors.RetCode(actorErr), @@ -294,7 +306,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, pl := PricelistByEpoch(vm.blockHeight) - msgGasCost := pl.OnChainMessage(cmsg.ChainLength()).Total() + msgGas := pl.OnChainMessage(cmsg.ChainLength()) + msgGasCost := msgGas.Total() // this should never happen, but is currently still exercised by some tests if msgGasCost > msg.GasLimit { return &ApplyRet{ @@ -377,7 +390,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, } defer st.ClearSnapshot() - ret, actorErr, rt := vm.send(ctx, msg, nil, msgGasCost) + ret, actorErr, rt := vm.send(ctx, msg, nil, &msgGas) + rt.finilizeGasTracing() if aerrors.IsFatal(actorErr) { return nil, xerrors.Errorf("[from=%s,to=%s,n=%d,m=%d,h=%d] fatal error: %w", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr) } diff --git a/cli/state.go b/cli/state.go index 1b6f676f2..c65eb1713 100644 --- a/cli/state.go +++ b/cli/state.go @@ -975,6 +975,7 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( } .slow-true-false { color: #660; } .slow-true-true { color: #f80; } + table { font-size: 12px; } @@ -1026,6 +1027,13 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( if ir.MsgRct.ExitCode != 0 { fmt.Printf(`
Error:
%s
`, ir.Error) } + fmt.Printf("\n
Gas Trace" + + "") + for _, gc := range ir.ExecutionTrace.GasCharges { + fmt.Printf("", + gc.Name, gc.TotalGas, gc.ComputeGas, gc.StorageGas, gc.TimeTaken, gc.Location) + } + fmt.Printf("
NameTotal/Compute/StorageTime TakenLocation
%s%d/%d/%d%s%s
\n") fmt.Println("
Execution trace:
") if err := printInternalExecutionsHtml(cid.String(), ir.ExecutionTrace.Subcalls, getCode); err != nil { @@ -1082,6 +1090,13 @@ func printInternalExecutionsHtml(hashName string, trace []types.ExecutionTrace, if im.MsgRct.ExitCode != 0 { fmt.Printf(`
Error:
%s
`, im.Error) } + fmt.Printf("\n
Gas Trace" + + "") + for _, gc := range im.GasCharges { + fmt.Printf("", + gc.Name, gc.TotalGas, gc.ComputeGas, gc.StorageGas, gc.TimeTaken, gc.Location) + } + fmt.Printf("
NameTotal/Compute/StorageTime TakenLocation
%s%d/%d/%d%s%s
\n") if len(im.Subcalls) > 0 { fmt.Println("
Subcalls:
") if err := printInternalExecutionsHtml(hashName, im.Subcalls, getCode); err != nil { diff --git a/miner/miner.go b/miner/miner.go index f2059ef7f..23f40338d 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -485,7 +485,7 @@ func SelectMessages(ctx context.Context, al ActorLookup, ts *types.TipSet, msgs vmstart := time.Now() minGas := vm.PricelistByEpoch(ts.Height()).OnChainMessage(msg.ChainLength()) // TODO: really should be doing just msg.ChainLength() but the sync side of this code doesnt seem to have access to that - if err := msg.VMMessage().ValidForBlockInclusion(minGas); err != nil { + if err := msg.VMMessage().ValidForBlockInclusion(minGas.Total()); err != nil { log.Warnf("invalid message in message pool: %s", err) continue } From 7587e6c08bc8048802616212dfc14bb8c0d396fe Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 11 Jun 2020 12:59:50 -0700 Subject: [PATCH 127/379] get and set storage deal acceptance through CLI --- api/api_storage.go | 1 + api/apistruct/struct.go | 9 +++++++-- cmd/lotus-storage-miner/main.go | 2 -- cmd/lotus-storage-miner/market.go | 18 ++++++++++++++++-- node/builder.go | 1 + node/impl/storminer.go | 7 +++++++ node/modules/dtypes/miner.go | 4 ++++ node/modules/storageminer.go | 20 ++++++++++++++++++++ 8 files changed, 56 insertions(+), 6 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 7d3c78b48..e414ed353 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -54,6 +54,7 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) + DealsSetIsAcceptingStorageDeals(ctx context.Context, b bool) error StorageAddLocal(ctx context.Context, path string) error } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 31cd6badd..23164a993 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -220,8 +220,9 @@ type StorageMinerStruct struct { StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` - DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` - DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` + DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsSetIsAcceptingStorageDeals func(ctx context.Context, b bool) error `perm:"admin"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -852,6 +853,10 @@ func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.Sto return c.Internal.DealsList(ctx) } +func (c *StorageMinerStruct) DealsSetIsAcceptingStorageDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetIsAcceptingStorageDeals(ctx, b) +} + func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error { return c.Internal.StorageAddLocal(ctx, path) } diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index 9ade0a41b..ba7722e4e 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -33,8 +33,6 @@ func main() { setPriceCmd, workersCmd, provingCmd, - enableCmd, - disableCmd, } jaeger := tracing.SetupJaegerTracing("lotus") defer func() { diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index cc0b84298..4b9f903c8 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -15,7 +15,13 @@ var enableCmd = &cli.Command{ Usage: "Configure the miner to consider storage deal proposals", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { - panic("enable storage deals") + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + return api.DealsSetIsAcceptingStorageDeals(lcli.DaemonContext(cctx), true) }, } @@ -24,7 +30,13 @@ var disableCmd = &cli.Command{ Usage: "Configure the miner to reject all storage deal proposals", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { - panic("disable storage deals") + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + return api.DealsSetIsAcceptingStorageDeals(lcli.DaemonContext(cctx), false) }, } @@ -60,6 +72,8 @@ var dealsCmd = &cli.Command{ Subcommands: []*cli.Command{ dealsImportDataCmd, dealsListCmd, + enableCmd, + disableCmd, }, } diff --git a/node/builder.go b/node/builder.go index adbb25efe..bf42eabd6 100644 --- a/node/builder.go +++ b/node/builder.go @@ -314,6 +314,7 @@ func Online() Option { Override(new(gen.WinningPoStProver), storage.NewWinningPoStProver), Override(new(*miner.Miner), modules.SetupBlockProducer), Override(new(dtypes.IsAcceptingStorageDealsFunc), modules.NewIsAcceptingStorageDealsFunc), + Override(new(dtypes.SetAcceptingStorageDealsFunc), modules.NewSetAcceptingStorageDealsFunc), ), ) } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index e48c9fcad..b88541886 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -25,6 +25,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node/impl/common" + "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage" "github.com/filecoin-project/lotus/storage/sectorblocks" ) @@ -41,6 +42,8 @@ type StorageMinerAPI struct { Full api.FullNode StorageMgr *sectorstorage.Manager `optional:"true"` *stores.Index + + SetAcceptingStorageDealsFunc dtypes.SetAcceptingStorageDealsFunc } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { @@ -206,6 +209,10 @@ func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.Stora return sm.StorageProvider.ListDeals(ctx) } +func (sm *StorageMinerAPI) DealsSetIsAcceptingStorageDeals(ctx context.Context, b bool) error { + return sm.SetAcceptingStorageDealsFunc(b) +} + func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fname string) error { fi, err := os.Open(fname) if err != nil { diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 9a3fcc2cd..d14a8775e 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -11,3 +11,7 @@ type MinerID abi.ActorID // IsAcceptingStorageDealsFunc is a function which reads from miner config to // determine if the user has disabled storage deals (or not). type IsAcceptingStorageDealsFunc func() (bool, error) + +// SetAcceptingStorageDealsFunc is a function which is used to disable or enable +// storage deal acceptance. +type SetAcceptingStorageDealsFunc func(bool) error diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 3719f621a..9847f7cc2 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -2,6 +2,7 @@ package modules import ( "context" + "errors" "net/http" "github.com/ipfs/go-bitswap" @@ -17,6 +18,7 @@ import ( "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/routing" "go.uber.org/fx" + "go.uber.org/multierr" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -392,3 +394,21 @@ func NewIsAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.IsAcceptingStorag return cfg.Dealmaking.IsAcceptingStorageDeals, nil }, nil } + +func NewSetAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.SetAcceptingStorageDealsFunc, error) { + return func(b bool) error { + var typeErr error + + setConfigErr := r.SetConfig(func(raw interface{}) { + cfg, ok := raw.(*config.StorageMiner) + if !ok { + typeErr = errors.New("expected storage miner config") + return + } + + cfg.Dealmaking.IsAcceptingStorageDeals = b + }) + + return multierr.Combine(typeErr, setConfigErr) + }, nil +} From 36b327b57b320d48db272812d186252c4d27695a Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 11 Jun 2020 13:18:18 -0700 Subject: [PATCH 128/379] various symbol renames --- api/api_storage.go | 2 +- api/apistruct/struct.go | 10 +++++----- cmd/lotus-storage-miner/market.go | 4 ++-- node/builder.go | 5 +++-- node/config/def.go | 4 ++-- node/impl/storminer.go | 6 +++--- node/modules/dtypes/miner.go | 6 +++--- node/modules/storageminer.go | 14 +++++++------- 8 files changed, 26 insertions(+), 25 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index e414ed353..04ff8311c 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -54,7 +54,7 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) - DealsSetIsAcceptingStorageDeals(ctx context.Context, b bool) error + DealsSetAcceptingStorageDeals(context.Context, bool) error StorageAddLocal(ctx context.Context, path string) error } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 23164a993..199ad2357 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -220,9 +220,9 @@ type StorageMinerStruct struct { StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` - DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` - DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` - DealsSetIsAcceptingStorageDeals func(ctx context.Context, b bool) error `perm:"admin"` + DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` + DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -853,8 +853,8 @@ func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.Sto return c.Internal.DealsList(ctx) } -func (c *StorageMinerStruct) DealsSetIsAcceptingStorageDeals(ctx context.Context, b bool) error { - return c.Internal.DealsSetIsAcceptingStorageDeals(ctx, b) +func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetAcceptingStorageDeals(ctx, b) } func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error { diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 4b9f903c8..c2f2555fa 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -21,7 +21,7 @@ var enableCmd = &cli.Command{ } defer closer() - return api.DealsSetIsAcceptingStorageDeals(lcli.DaemonContext(cctx), true) + return api.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), true) }, } @@ -36,7 +36,7 @@ var disableCmd = &cli.Command{ } defer closer() - return api.DealsSetIsAcceptingStorageDeals(lcli.DaemonContext(cctx), false) + return api.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), false) }, } diff --git a/node/builder.go b/node/builder.go index bf42eabd6..e628e999b 100644 --- a/node/builder.go +++ b/node/builder.go @@ -313,8 +313,9 @@ func Online() Option { Override(HandleDealsKey, modules.HandleDeals), Override(new(gen.WinningPoStProver), storage.NewWinningPoStProver), Override(new(*miner.Miner), modules.SetupBlockProducer), - Override(new(dtypes.IsAcceptingStorageDealsFunc), modules.NewIsAcceptingStorageDealsFunc), - Override(new(dtypes.SetAcceptingStorageDealsFunc), modules.NewSetAcceptingStorageDealsFunc), + + Override(new(dtypes.AcceptingStorageDealsConfigFunc), modules.NewAcceptingStorageDealsConfigFunc), + Override(new(dtypes.SetAcceptingStorageDealsConfigFunc), modules.NewSetAcceptingStorageDealsConfigFunc), ), ) } diff --git a/node/config/def.go b/node/config/def.go index 3debfd64e..651e99aed 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -32,7 +32,7 @@ type StorageMiner struct { } type DealmakingConfig struct { - IsAcceptingStorageDeals bool + AcceptingStorageDeals bool } // API contains configs for API endpoint @@ -116,7 +116,7 @@ func DefaultStorageMiner() *StorageMiner { }, Dealmaking: DealmakingConfig{ - IsAcceptingStorageDeals: true, + AcceptingStorageDeals: true, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/impl/storminer.go b/node/impl/storminer.go index b88541886..de80eb4cd 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -43,7 +43,7 @@ type StorageMinerAPI struct { StorageMgr *sectorstorage.Manager `optional:"true"` *stores.Index - SetAcceptingStorageDealsFunc dtypes.SetAcceptingStorageDealsFunc + SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { @@ -209,8 +209,8 @@ func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.Stora return sm.StorageProvider.ListDeals(ctx) } -func (sm *StorageMinerAPI) DealsSetIsAcceptingStorageDeals(ctx context.Context, b bool) error { - return sm.SetAcceptingStorageDealsFunc(b) +func (sm *StorageMinerAPI) DealsSetAcceptingStorageDeals(ctx context.Context, b bool) error { + return sm.SetAcceptingStorageDealsConfigFunc(b) } func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fname string) error { diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index d14a8775e..5c761d3e5 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -8,10 +8,10 @@ import ( type MinerAddress address.Address type MinerID abi.ActorID -// IsAcceptingStorageDealsFunc is a function which reads from miner config to +// AcceptingStorageDealsFunc is a function which reads from miner config to // determine if the user has disabled storage deals (or not). -type IsAcceptingStorageDealsFunc func() (bool, error) +type AcceptingStorageDealsConfigFunc func() (bool, error) // SetAcceptingStorageDealsFunc is a function which is used to disable or enable // storage deal acceptance. -type SetAcceptingStorageDealsFunc func(bool) error +type SetAcceptingStorageDealsConfigFunc func(bool) error diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 9847f7cc2..440aa8593 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -307,7 +307,7 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return storedAsk, nil } -func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingStorageDealsFunc dtypes.IsAcceptingStorageDealsFunc) (storagemarket.StorageProvider, error) { +func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc) (storagemarket.StorageProvider, error) { net := smnet.NewFromLibp2pHost(h) store, err := piecefilestore.NewLocalFileStore(piecefilestore.OsPath(r.Path())) if err != nil { @@ -315,12 +315,12 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con } opt := storageimpl.CustomDealDecisionLogic(func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) { - willEntertainProposals, err := isAcceptingStorageDealsFunc() + b, err := isAcceptingFunc() if err != nil { return false, "miner error", err } - if !willEntertainProposals { + if !b { log.Warnf("storage deal acceptance disabled; rejecting storage deal proposal from client: %s", deal.Client.String()) return false, "miner is not accepting storage deals", nil } @@ -379,7 +379,7 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA return sectorstorage.StorageAuth(headers), nil } -func NewIsAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.IsAcceptingStorageDealsFunc, error) { +func NewAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.AcceptingStorageDealsConfigFunc, error) { return func() (bool, error) { raw, err := r.Config() if err != nil { @@ -391,11 +391,11 @@ func NewIsAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.IsAcceptingStorag return false, xerrors.New("expected address of config.StorageMiner") } - return cfg.Dealmaking.IsAcceptingStorageDeals, nil + return cfg.Dealmaking.AcceptingStorageDeals, nil }, nil } -func NewSetAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.SetAcceptingStorageDealsFunc, error) { +func NewSetAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.SetAcceptingStorageDealsConfigFunc, error) { return func(b bool) error { var typeErr error @@ -406,7 +406,7 @@ func NewSetAcceptingStorageDealsFunc(r repo.LockedRepo) (dtypes.SetAcceptingStor return } - cfg.Dealmaking.IsAcceptingStorageDeals = b + cfg.Dealmaking.AcceptingStorageDeals = b }) return multierr.Combine(typeErr, setConfigErr) From 071ddf6563f37ef1d0a361102ed95f8411153c8a Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 11 Jun 2020 22:25:24 +0200 Subject: [PATCH 129/379] Add aggregate number, add number of bytes for storage calls Signed-off-by: Jakub Sztandera --- chain/vm/gas_v0.go | 4 ++-- cli/state.go | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index 0b6196377..c631beaee 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -108,12 +108,12 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M // OnIpldGet returns the gas used for storing an object func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge { - return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0) + return newGasCharge(fmt.Sprintf("OnIpldGet:%db", dataSize), pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0) } // OnIpldPut returns the gas used for storing an object func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge { - return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte) + return newGasCharge(fmt.Sprintf("OnIpldPut:%db", dataSize), pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte) } // OnCreateActor returns the gas used for creating an actor diff --git a/cli/state.go b/cli/state.go index c65eb1713..acc648c23 100644 --- a/cli/state.go +++ b/cli/state.go @@ -975,7 +975,11 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( } .slow-true-false { color: #660; } .slow-true-true { color: #f80; } - table { font-size: 12px; } + table { + font-size: 12px; + border-collapse: collapse; + } + tr.sum { border-top: 1px solid black; } @@ -1029,10 +1033,20 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func( } fmt.Printf("\n
Gas Trace" + "") + + var sumTotal, sumCompute, sumStorage int64 + var sumTime time.Duration for _, gc := range ir.ExecutionTrace.GasCharges { fmt.Printf("", gc.Name, gc.TotalGas, gc.ComputeGas, gc.StorageGas, gc.TimeTaken, gc.Location) + sumTotal += gc.TotalGas + sumCompute += gc.ComputeGas + sumStorage += gc.StorageGas + sumTime += gc.TimeTaken } + fmt.Printf("", + "Sum", sumTotal, sumCompute, sumStorage, sumTime, "") + fmt.Printf("
NameTotal/Compute/StorageTime TakenLocation
%s%d/%d/%d%s%s
%s%d/%d/%d%s%s
\n") fmt.Println("
Execution trace:
") @@ -1092,10 +1106,18 @@ func printInternalExecutionsHtml(hashName string, trace []types.ExecutionTrace, } fmt.Printf("\n
Gas Trace" + "") + var sumTotal, sumCompute, sumStorage int64 + var sumTime time.Duration for _, gc := range im.GasCharges { fmt.Printf("", gc.Name, gc.TotalGas, gc.ComputeGas, gc.StorageGas, gc.TimeTaken, gc.Location) + sumTotal += gc.TotalGas + sumCompute += gc.ComputeGas + sumStorage += gc.StorageGas + sumTime += gc.TimeTaken } + fmt.Printf("", + "Sum", sumTotal, sumCompute, sumStorage, sumTime, "") fmt.Printf("
NameTotal/Compute/StorageTime TakenLocation
%s%d/%d/%d%s%s
%s%d/%d/%d%s%s
\n") if len(im.Subcalls) > 0 { fmt.Println("
Subcalls:
") From c7e3a5cff4e3c3e0cec5027dde55610c054670bb Mon Sep 17 00:00:00 2001 From: Jeromy Date: Thu, 11 Jun 2020 17:11:38 -0700 Subject: [PATCH 130/379] fix null incrementing --- miner/miner.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/miner/miner.go b/miner/miner.go index 23f40338d..bdeed8ac5 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -188,6 +188,8 @@ func (m *Miner) mine(ctx context.Context) { log.Errorf("failed to submit newly mined block: %s", err) } } else { + base.NullRounds++ + // Wait until the next epoch, plus the propagation delay, so a new tipset // has enough time to form. // @@ -261,7 +263,6 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, return nil, xerrors.Errorf("failed to get mining base info: %w", err) } if mbi == nil { - base.NullRounds++ return nil, nil } @@ -278,7 +279,6 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, } if !hasPower { // slashed or just have no power yet - base.NullRounds++ return nil, nil } @@ -302,7 +302,6 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, } if winner == nil { - base.NullRounds++ return nil, nil } From 2c401f90419535543e8f811c9ff4062959ff2e6c Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 12 Jun 2020 01:13:11 -0400 Subject: [PATCH 131/379] Improve UX of fetch-params --- .circleci/config.yml | 2 +- cli/params.go | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ddcbd5481..fc9f495a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,7 +45,7 @@ commands: - 'v25-2k-lotus-params' paths: - /var/tmp/filecoin-proof-parameters/ - - run: ./lotus fetch-params --proving-params 2048 + - run: ./lotus fetch-params 2048 - save_cache: name: Save parameters cache key: 'v25-2k-lotus-params' diff --git a/cli/params.go b/cli/params.go index 95596ff57..47e1e3988 100644 --- a/cli/params.go +++ b/cli/params.go @@ -10,18 +10,16 @@ import ( ) var fetchParamCmd = &cli.Command{ - Name: "fetch-params", - Usage: "Fetch proving parameters", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "proving-params", - Usage: "download params used creating proofs for given size, i.e. 32GiB", - }, - }, + Name: "fetch-params", + Usage: "Fetch proving parameters", + ArgsUsage: "[sectorSize]", Action: func(cctx *cli.Context) error { - sectorSizeInt, err := units.RAMInBytes(cctx.String("proving-params")) + if !cctx.Args().Present() { + return xerrors.Errorf("must pass sector size to fetch params for (specify as \"32GiB\", for instance)") + } + sectorSizeInt, err := units.RAMInBytes(cctx.Args().First()) if err != nil { - return err + return xerrors.Errorf("error parsing sector size (specify as \"32GiB\", for instance): %w", err) } sectorSize := uint64(sectorSizeInt) From 227819dc1e43fd9c64022fc3b79cb2ca907bc62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 12 Jun 2020 10:03:31 +0200 Subject: [PATCH 132/379] docs: Update local-dev-net --- documentation/en/local-dev-net.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/en/local-dev-net.md b/documentation/en/local-dev-net.md index 0b352fe8a..e11d9b358 100644 --- a/documentation/en/local-dev-net.md +++ b/documentation/en/local-dev-net.md @@ -8,7 +8,7 @@ make 2k Download the 2048 byte parameters: ```sh -./lotus fetch-params --proving-params 2048 +./lotus fetch-params 2048 ``` Pre-seal some sectors: From bd25d6db06e5c7060a2884282c1ddbcd9a8cf959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 12 Jun 2020 13:24:38 +0200 Subject: [PATCH 133/379] compute-state html: Convert to templates --- cli/state.go | 285 ++++++++++++++++++++++++--------------------------- 1 file changed, 134 insertions(+), 151 deletions(-) diff --git a/cli/state.go b/cli/state.go index acc648c23..47a1624c4 100644 --- a/cli/state.go +++ b/cli/state.go @@ -5,10 +5,12 @@ import ( "context" "encoding/json" "fmt" + "os" "reflect" "sort" "strconv" "strings" + "text/template" "time" "github.com/ipfs/go-cid" @@ -31,6 +33,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/power" "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api" @@ -40,7 +43,7 @@ import ( ) type methodMeta struct { - name string + Name string params reflect.Type ret reflect.Type @@ -68,7 +71,7 @@ func init() { nf := rt.NumField() methods[c] = append(methods[c], methodMeta{ - name: "Send", + Name: "Send", params: reflect.TypeOf(new(adt.EmptyValue)), ret: reflect.TypeOf(new(adt.EmptyValue)), }) @@ -78,7 +81,7 @@ func init() { export := reflect.TypeOf(exports[i+1]) methods[c] = append(methods[c], methodMeta{ - name: rt.Field(i).Name, + Name: rt.Field(i).Name, params: export.In(1), ret: export.Out(0), }) @@ -923,7 +926,7 @@ var stateComputeStateCmd = &cli.Command{ return c.Code, nil } - return computeStateHtml(ts, stout, getCode) + return computeStateHtmlT(ts, stout, getCode) } fmt.Println("computed state cid: ", stout.Root) @@ -944,16 +947,8 @@ func printInternalExecutions(prefix string, trace []types.ExecutionTrace) { } } -func codeStr(c cid.Cid) string { - cmh, err := multihash.Decode(c.Hash()) - if err != nil { - panic(err) - } - return string(cmh.Digest) -} - -func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(addr address.Address) (cid.Cid, error)) error { - fmt.Printf(` +var compStateTemplate = ` + -
Tipset: %s
-
Height: %d
-
State CID: %s
-
Calls
`, ts.Key(), ts.Height(), o.Root) +
Tipset: {{.TipSet.Key}}
+
Epoch: {{.TipSet.Height}}
+
State CID: {{.Comp.Root}}
+
Calls
+ {{range .Comp.Trace}} + {{template "message" (Call .ExecutionTrace false .Msg.Cid.String)}} + {{end}} + + +` - for _, ir := range o.Trace { - toCode, err := getCode(ir.Msg.To) - if err != nil { - return xerrors.Errorf("getting code for %s: %w", toCode, err) - } +var compStateMsg = ` +
+ {{$code := GetCode .Msg.To}} + {{$h := "h2"}}{{if .Subcall}}{{$h = "h4"}}{{end}} - params, err := jsonParams(toCode, ir.Msg.Method, ir.Msg.Params) - if err != nil { - return xerrors.Errorf("decoding params: %w", err) - } + +
{{.Msg.From}} -> {{.Msg.To}} ({{ToFil .Msg.Value}} FIL), M{{.Msg.Method}}
+ {{if not .Subcall}}
Msg CID: {{.Msg.Cid}}
{{end}} + {{if gt (len .Msg.Params) 0}} +
{{JsonParams ($code) (.Msg.Method) (.Msg.Params) | html}}
+ {{end}} +
Took {{.Duration}}, Exit: {{.MsgRct.ExitCode}}{{if gt (len .MsgRct.Return) 0}}, Return{{end}}
+ + {{if gt (len .MsgRct.Return) 0}} +
{{JsonReturn ($code) (.Msg.Method) (.MsgRct.Return) | html}}
+ {{end}} - if len(ir.Msg.Params) != 0 { - params = `
` + params + `
` - } else { - params = "" - } + {{if ne .MsgRct.ExitCode 0}} +
Error:
{{.Error}}
+ {{end}} - ret, err := jsonReturn(toCode, ir.Msg.Method, ir.MsgRct.Return) - if err != nil { - return xerrors.Errorf("decoding return value: %w", err) - } +
+ Gas Trace + + + {{range .GasCharges}} + + {{end}} + {{with SumGas .GasCharges}} + + {{end}} +
NameTotal/Compute/StorageTime TakenLocation
{{.Name}}{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}{{.Location}}
Sum{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}
+
+ {{if gt (len .Subcalls) 0}} +
Subcalls:
+ {{$hash := .Hash}} + {{range .Subcalls}} + {{template "message" (Call . true (printf "%s-%s" $hash .Msg.Cid.String))}} + {{end}} + {{end}} +
` - if len(ir.MsgRct.Return) == 0 { - ret = "
" - } else { - ret = `, Return
` + ret + `
` - } - - slow := ir.Duration > 10*time.Millisecond - veryslow := ir.Duration > 50*time.Millisecond - - cid := ir.Msg.Cid() - - fmt.Printf(`
- -
%s -> %s (%s FIL), M%d
-
Msg CID: %s
-%s -
Took %s, Exit: %d%s -`, cid, cid, codeStr(toCode), methods[toCode][ir.Msg.Method].name, ir.Msg.From, ir.Msg.To, types.FIL(ir.Msg.Value), ir.Msg.Method, cid, params, slow, veryslow, ir.Duration, ir.MsgRct.ExitCode, ir.MsgRct.ExitCode, ret) - if ir.MsgRct.ExitCode != 0 { - fmt.Printf(`
Error:
%s
`, ir.Error) - } - fmt.Printf("\n
Gas Trace" + - "") - - var sumTotal, sumCompute, sumStorage int64 - var sumTime time.Duration - for _, gc := range ir.ExecutionTrace.GasCharges { - fmt.Printf("", - gc.Name, gc.TotalGas, gc.ComputeGas, gc.StorageGas, gc.TimeTaken, gc.Location) - sumTotal += gc.TotalGas - sumCompute += gc.ComputeGas - sumStorage += gc.StorageGas - sumTime += gc.TimeTaken - } - fmt.Printf("", - "Sum", sumTotal, sumCompute, sumStorage, sumTime, "") - - fmt.Printf("
NameTotal/Compute/StorageTime TakenLocation
%s%d/%d/%d%s%s
%s%d/%d/%d%s%s
\n") - - fmt.Println("
Execution trace:
") - if err := printInternalExecutionsHtml(cid.String(), ir.ExecutionTrace.Subcalls, getCode); err != nil { - return err - } - fmt.Println("
") - } - - fmt.Printf(` -`) - return nil +type compStateHtmlIn struct { + TipSet *types.TipSet + Comp *api.ComputeStateOutput } -func printInternalExecutionsHtml(hashName string, trace []types.ExecutionTrace, getCode func(addr address.Address) (cid.Cid, error)) error { - for i, im := range trace { - hashName := fmt.Sprintf("%s-r%d", hashName, i) - - toCode, err := getCode(im.Msg.To) - if err != nil { - return xerrors.Errorf("getting code for %s: %w", toCode, err) - } - - params, err := jsonParams(toCode, im.Msg.Method, im.Msg.Params) - if err != nil { - return xerrors.Errorf("decoding params: %w", err) - } - - if len(im.Msg.Params) != 0 { - params = `
` + params + `
` - } else { - params = "" - } - - ret, err := jsonReturn(toCode, im.Msg.Method, im.MsgRct.Return) - if err != nil { - return xerrors.Errorf("decoding return value: %w", err) - } - - if len(im.MsgRct.Return) == 0 { - ret = "
" - } else { - ret = `, Return
` + ret + `
` - } - - slow := im.Duration > 10*time.Millisecond - veryslow := im.Duration > 50*time.Millisecond - - fmt.Printf(`
- -
%s -> %s (%s FIL), M%d
-%s -
Took %s, Exit: %d%s -`, hashName, hashName, codeStr(toCode), methods[toCode][im.Msg.Method].name, im.Msg.From, im.Msg.To, types.FIL(im.Msg.Value), im.Msg.Method, params, slow, veryslow, im.Duration, im.MsgRct.ExitCode, im.MsgRct.ExitCode, ret) - if im.MsgRct.ExitCode != 0 { - fmt.Printf(`
Error:
%s
`, im.Error) - } - fmt.Printf("\n
Gas Trace" + - "") - var sumTotal, sumCompute, sumStorage int64 - var sumTime time.Duration - for _, gc := range im.GasCharges { - fmt.Printf("", - gc.Name, gc.TotalGas, gc.ComputeGas, gc.StorageGas, gc.TimeTaken, gc.Location) - sumTotal += gc.TotalGas - sumCompute += gc.ComputeGas - sumStorage += gc.StorageGas - sumTime += gc.TimeTaken - } - fmt.Printf("", - "Sum", sumTotal, sumCompute, sumStorage, sumTime, "") - fmt.Printf("
NameTotal/Compute/StorageTime TakenLocation
%s%d/%d/%d%s%s
%s%d/%d/%d%s%s
\n") - if len(im.Subcalls) > 0 { - fmt.Println("
Subcalls:
") - if err := printInternalExecutionsHtml(hashName, im.Subcalls, getCode); err != nil { - return err - } - } - fmt.Println("
") +func computeStateHtmlT(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(addr address.Address) (cid.Cid, error)) error { + t, err := template.New("compute_state").Funcs(map[string]interface{}{ + "GetCode": getCode, + "GetMethod": getMethod, + "ToFil": toFil, + "JsonParams": jsonParams, + "JsonReturn": jsonReturn, + "IsSlow": isSlow, + "IsVerySlow": isVerySlow, + "IntExit": func(i exitcode.ExitCode) int64 { return int64(i) }, + "SumGas": sumGas, + "CodeStr": codeStr, + "Call": call, + }).Parse(compStateTemplate) + if err != nil { + return err + } + t, err = t.New("message").Parse(compStateMsg) + if err != nil { + return err } - return nil + return t.ExecuteTemplate(os.Stdout, "compute_state", &compStateHtmlIn{ + TipSet: ts, + Comp: o, + }) +} + +type callMeta struct { + types.ExecutionTrace + Subcall bool + Hash string +} + +func call(e types.ExecutionTrace, subcall bool, hash string) callMeta { + return callMeta{ + ExecutionTrace: e, + Subcall: subcall, + Hash: hash, + } +} + +func codeStr(c cid.Cid) string { + cmh, err := multihash.Decode(c.Hash()) + if err != nil { + panic(err) + } + return string(cmh.Digest) +} + +func getMethod(code cid.Cid, method abi.MethodNum) string { + return methods[code][method].Name +} + +func toFil(f types.BigInt) types.FIL { + return types.FIL(f) +} + +func isSlow(t time.Duration) bool { + return t > 10*time.Millisecond +} + +func isVerySlow(t time.Duration) bool { + return t > 50*time.Millisecond +} + +func sumGas(changes []*types.GasTrace) types.GasTrace { + var out types.GasTrace + for _, gc := range changes { + out.TotalGas += gc.TotalGas + out.ComputeGas += gc.ComputeGas + out.StorageGas += gc.StorageGas + out.TimeTaken += gc.TimeTaken + } + + return out } func jsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, error) { From 813940762c58e26393e343f7f1f7b40fdfa03748 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 12 Jun 2020 14:46:50 +0200 Subject: [PATCH 134/379] Use html/template Signed-off-by: Jakub Sztandera --- cli/state.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/cli/state.go b/cli/state.go index 47a1624c4..3d92f9000 100644 --- a/cli/state.go +++ b/cli/state.go @@ -5,12 +5,12 @@ import ( "context" "encoding/json" "fmt" + "html/template" "os" "reflect" "sort" "strconv" "strings" - "text/template" "time" "github.com/ipfs/go-cid" @@ -992,9 +992,22 @@ var compStateTemplate = ` var compStateMsg = `
{{$code := GetCode .Msg.To}} - {{$h := "h2"}}{{if .Subcall}}{{$h = "h4"}}{{end}} + -
{{.Msg.From}} -> {{.Msg.To}} ({{ToFil .Msg.Value}} FIL), M{{.Msg.Method}}
{{if not .Subcall}}
Msg CID: {{.Msg.Cid}}
{{end}} {{if gt (len .Msg.Params) 0}} @@ -1049,6 +1062,9 @@ func computeStateHtmlT(ts *types.TipSet, o *api.ComputeStateOutput, getCode func "SumGas": sumGas, "CodeStr": codeStr, "Call": call, + "htmlSafeAttr": func(html string) template.HTMLAttr { + return template.HTMLAttr(html) + }, }).Parse(compStateTemplate) if err != nil { return err From 00385acc1d2561e49ec395086f7780c8e66706ab Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 12 Jun 2020 15:26:58 +0200 Subject: [PATCH 135/379] Remove htmlSafeAttr Signed-off-by: Jakub Sztandera --- cli/state.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cli/state.go b/cli/state.go index 3d92f9000..e2ec3b6d1 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1062,9 +1062,6 @@ func computeStateHtmlT(ts *types.TipSet, o *api.ComputeStateOutput, getCode func "SumGas": sumGas, "CodeStr": codeStr, "Call": call, - "htmlSafeAttr": func(html string) template.HTMLAttr { - return template.HTMLAttr(html) - }, }).Parse(compStateTemplate) if err != nil { return err From 82eb7786d464d963c9e2be23672608e09d07d918 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 12 Jun 2020 16:25:55 +0200 Subject: [PATCH 136/379] Cleanup lint warnings Signed-off-by: Jakub Sztandera --- cli/state.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/state.go b/cli/state.go index e2ec3b6d1..96114864f 100644 --- a/cli/state.go +++ b/cli/state.go @@ -926,7 +926,7 @@ var stateComputeStateCmd = &cli.Command{ return c.Code, nil } - return computeStateHtmlT(ts, stout, getCode) + return computeStateHTMLTempl(ts, stout, getCode) } fmt.Println("computed state cid: ", stout.Root) @@ -1044,12 +1044,12 @@ var compStateMsg = ` {{end}}
` -type compStateHtmlIn struct { +type compStateHTMLIn struct { TipSet *types.TipSet Comp *api.ComputeStateOutput } -func computeStateHtmlT(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(addr address.Address) (cid.Cid, error)) error { +func computeStateHTMLTempl(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(addr address.Address) (cid.Cid, error)) error { t, err := template.New("compute_state").Funcs(map[string]interface{}{ "GetCode": getCode, "GetMethod": getMethod, @@ -1071,7 +1071,7 @@ func computeStateHtmlT(ts *types.TipSet, o *api.ComputeStateOutput, getCode func return err } - return t.ExecuteTemplate(os.Stdout, "compute_state", &compStateHtmlIn{ + return t.ExecuteTemplate(os.Stdout, "compute_state", &compStateHTMLIn{ TipSet: ts, Comp: o, }) From d670257402f91e7c3bd3d87ddd06439b4f783ee6 Mon Sep 17 00:00:00 2001 From: Rob Quist Date: Fri, 12 Jun 2020 17:30:43 +0200 Subject: [PATCH 137/379] Add back installation of Go and Rust --- documentation/en/install-lotus-ubuntu.md | 27 ++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/documentation/en/install-lotus-ubuntu.md b/documentation/en/install-lotus-ubuntu.md index b458113b3..dda4fc84c 100644 --- a/documentation/en/install-lotus-ubuntu.md +++ b/documentation/en/install-lotus-ubuntu.md @@ -15,28 +15,43 @@ These steps will install the following dependencies: - llvm (proofs build) - clang (proofs build) -Install dependencies +### Install dependencies ```sh -sudo add-apt-repository ppa:longsleep/golang-backports sudo apt update -sudo apt install mesa-opencl-icd ocl-icd-opencl-dev gcc git bzr jq pkg-config golang-go +sudo apt install mesa-opencl-icd ocl-icd-opencl-dev gcc git bzr jq pkg-config curl +sudo apt upgrade ``` -Install Rust +### Install Go 1.14 + +Find the latest version of Go [on their website](https://golang.org/dl/) and follow the installation instructions. At the time of writing this document, thats 1.14.4. Extract it to `/usr/local`, and add the go binaries to your `$PATH`. + +```sh +wget -c https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local +echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile +source ~/.profile +``` + +Verify your go installation by running +```sh +go version +``` + +### Install Rust _(this is an interactive installer)_ ```sh curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -Clone the Lotus repository +### Clone the Lotus repository ```sh git clone https://github.com/filecoin-project/lotus.git cd lotus/ ``` -Build the Lotus binaries from source and install +### Build the Lotus binaries from source and install ```sh make clean && make all From 9077dea0cd061b920c47c1d20bb339db6e64ce87 Mon Sep 17 00:00:00 2001 From: Rob Quist Date: Fri, 12 Jun 2020 17:40:47 +0200 Subject: [PATCH 138/379] Update install-lotus-ubuntu.md --- documentation/en/install-lotus-ubuntu.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/en/install-lotus-ubuntu.md b/documentation/en/install-lotus-ubuntu.md index dda4fc84c..4d5ba77f9 100644 --- a/documentation/en/install-lotus-ubuntu.md +++ b/documentation/en/install-lotus-ubuntu.md @@ -42,6 +42,7 @@ go version _(this is an interactive installer)_ ```sh curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source ~/.profile ``` ### Clone the Lotus repository From ca8a00f8a15d2277c142310a448ec069ecbd6ad0 Mon Sep 17 00:00:00 2001 From: Rob Quist Date: Fri, 12 Jun 2020 18:19:04 +0200 Subject: [PATCH 139/379] Update hardware-mining.md --- documentation/en/hardware-mining.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/en/hardware-mining.md b/documentation/en/hardware-mining.md index a7c410184..0379cc4e1 100644 --- a/documentation/en/hardware-mining.md +++ b/documentation/en/hardware-mining.md @@ -16,7 +16,7 @@ The setup below is a minimal example for sealing 32 GiB sectors on Lotus: Note that 1GB sectors don't require as high of specs, but are likely to be removed as we improve the performance of 32GB sector sealing. -AMD CPU's are __highly recommended__, because of the `Intel SHA Extensions` instruction set that is available there since the `Zen` microarchitecture. Hence, AMD CPU's seem to perform much better on the testnet than other CPU's. Contrary to what the name implies, this extended instruction set is not available on recent Intel desktop/server chips. +For the first part of the sealing process, AMD CPU's are __highly recommended__, because of the `Intel SHA Extensions` instruction set that is available there ever since the `Zen` microarchitecture. Hence, AMD CPU's seem to perform much better on the testnet than other CPU's. Contrary to what the name implies, this extended instruction set is not available on recent Intel desktop/server chips. ## Testnet discoveries @@ -35,7 +35,7 @@ GPUs are a must for getting **block rewards**. Here are a few that have been con ## Testing other GPUs -If you want to test a GPU that is not explicitly supported, use the following global**environment variable**: +If you want to test a GPU that is not explicitly supported, use the following global **environment variable**: ```sh BELLMAN_CUSTOM_GPU=":" From cd69e57a33513089aaf142cd0a4fbab0c95cefdf Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 12 Jun 2020 18:49:29 +0200 Subject: [PATCH 140/379] Expose more callers, ellipsis unimportant ones Signed-off-by: Jakub Sztandera --- chain/types/execresult.go | 68 +++++++++++++++++++++++++++++++++------ chain/vm/runtime.go | 31 ++++++++++++------ chain/vm/vm.go | 4 +-- cli/state.go | 48 ++++++++++++++++++++++++--- 4 files changed, 125 insertions(+), 26 deletions(-) diff --git a/chain/types/execresult.go b/chain/types/execresult.go index 41372b832..57e14dcf9 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -19,36 +19,84 @@ type ExecutionTrace struct { } type GasTrace struct { - Name string - Location string + Name string + + Location []Loc TotalGas int64 ComputeGas int64 StorageGas int64 TimeTaken time.Duration + Extra interface{} Callers []uintptr `json:"-"` } +type Loc struct { + File string + Line int + Function string +} + +func (l Loc) Show() bool { + ignorePrefix := []string{ + "reflect.", + "github.com/filecoin-project/lotus/chain/vm.(*Invoker).transform", + "github.com/filecoin-project/go-amt-ipld/", + } + for _, pre := range ignorePrefix { + if strings.HasPrefix(l.Function, pre) { + return false + } + } + return true +} +func (l Loc) String() string { + file := strings.Split(l.File, "/") + + fn := strings.Split(l.Function, "/") + var fnpkg string + if len(fn) > 2 { + fnpkg = strings.Join(fn[len(fn)-2:], "/") + } else { + fnpkg = l.Function + } + + return fmt.Sprintf("%s@%s:%d", fnpkg, file[len(file)-1], l.Line) +} + +func (l Loc) Important() bool { + if strings.HasPrefix(l.Function, "github.com/filecoin-project/specs-actors/actors/builtin") { + return true + } + return false +} + func (gt *GasTrace) MarshalJSON() ([]byte, error) { type GasTraceCopy GasTrace - if gt.Location == "" { + if len(gt.Location) == 0 { if len(gt.Callers) != 0 { frames := runtime.CallersFrames(gt.Callers) for { frame, more := frames.Next() - fn := strings.Split(frame.Function, "/") + if frame.Function == "github.com/filecoin-project/lotus/chain/vm.(*VM).ApplyMessage" { + break + } + l := Loc{ + File: frame.File, + Line: frame.Line, + Function: frame.Function, + } + //fn := strings.Split(frame.Function, "/") - split := strings.Split(frame.File, "/") - file := strings.Join(split[len(split)-2:], "/") - gt.Location += fmt.Sprintf("%s@%s:%d", fn[len(fn)-1], file, frame.Line) + //split := strings.Split(frame.File, "/") + //file := strings.Join(split[len(split)-2:], "/") + //gt.Location += fmt.Sprintf("%s@%s:%d", fn[len(fn)-1], file, frame.Line) + gt.Location = append(gt.Location, l) if !more { break } - gt.Location += "|" } - } else { - gt.Location = "n/a" } } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 902ef94bb..67f7adc03 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -488,22 +488,33 @@ func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError { return nil } -func (rt *Runtime) ChargeGas(gas GasCharge) { - err := rt.chargeGasInternal(gas) - if err != nil { - panic(err) - } -} func (rt *Runtime) finilizeGasTracing() { if rt.lastGasCharge != nil { rt.lastGasCharge.TimeTaken = time.Since(rt.lastGasChargeTime) } } -func (rt *Runtime) chargeGasInternal(gas GasCharge) aerrors.ActorError { +func (rt *Runtime) ChargeGas(gas GasCharge) { + err := rt.chargeGasInternal(gas, 1) + if err != nil { + panic(err) + } +} + +func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) { + return func(gas GasCharge) { + err := rt.chargeGasInternal(gas, 1+skip) + if err != nil { + panic(err) + } + } + +} + +func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError { toUse := gas.Total() - var callers [3]uintptr - cout := gruntime.Callers(3, callers[:]) + var callers [10]uintptr + cout := gruntime.Callers(2+skip, callers[:]) now := time.Now() if rt.lastGasCharge != nil { @@ -530,7 +541,7 @@ func (rt *Runtime) chargeGasInternal(gas GasCharge) aerrors.ActorError { } func (rt *Runtime) chargeGasSafe(gas GasCharge) aerrors.ActorError { - return rt.chargeGasInternal(gas) + return rt.chargeGasInternal(gas, 1) } func (rt *Runtime) Pricelist() Pricelist { diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 75bbdfedb..acae3cde0 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -107,12 +107,12 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres } rt.cst = &cbor.BasicIpldStore{ - Blocks: &gasChargingBlocks{rt.ChargeGas, rt.pricelist, vm.cst.Blocks}, + Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks}, Atlas: vm.cst.Atlas, } rt.sys = pricedSyscalls{ under: vm.Syscalls, - chargeGas: rt.ChargeGas, + chargeGas: rt.chargeGasFunc(1), pl: rt.pricelist, } diff --git a/cli/state.go b/cli/state.go index 96114864f..f2185c4ab 100644 --- a/cli/state.go +++ b/cli/state.go @@ -972,9 +972,35 @@ var compStateTemplate = ` .slow-true-true { color: #f80; } table { font-size: 12px; - border-collapse: collapse; - } - tr.sum { border-top: 1px solid black; } + border-collapse: collapse; + } + tr { + border-top: 1px solid black; + border-bottom: 1px solid black; + } + tr.sum { border-top: 2px solid black; } + tr:first-child { border-top: none; } + tr:last-child { border-bottom: none; } + + + .ellipsis-content, + .ellipsis-toggle input { + display: none; + } + .ellipsis-toggle { + cursor: pointer; + } + /** + Checked State + **/ + + .ellipsis-toggle input:checked + .ellipsis { + display: none; + } + .ellipsis-toggle input:checked ~ .ellipsis-content { + display: inline; + background-color: #ddd; + } @@ -1028,7 +1054,21 @@ var compStateMsg = ` {{range .GasCharges}} - + + {{end}} {{with SumGas .GasCharges}} From 8ad2b3c3d946428bd10fb8f0cca2851601752838 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 12 Jun 2020 18:58:55 +0200 Subject: [PATCH 141/379] Removed commented out code Signed-off-by: Jakub Sztandera --- chain/types/execresult.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/chain/types/execresult.go b/chain/types/execresult.go index 57e14dcf9..7ffa8c219 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -87,11 +87,6 @@ func (gt *GasTrace) MarshalJSON() ([]byte, error) { Line: frame.Line, Function: frame.Function, } - //fn := strings.Split(frame.Function, "/") - - //split := strings.Split(frame.File, "/") - //file := strings.Join(split[len(split)-2:], "/") - //gt.Location += fmt.Sprintf("%s@%s:%d", fn[len(fn)-1], file, frame.Line) gt.Location = append(gt.Location, l) if !more { break From a2943a6b7ff963388c57e02ed2ad68806397b810 Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Fri, 12 Jun 2020 13:57:30 -0300 Subject: [PATCH 142/379] doc: active development branches --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b0d9867d9..cd64073a6 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,19 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more details about Filecoin, check out the [Filecoin Spec](https://github.com/filecoin-project/specs). -## Development - -All work is tracked via issues. An attempt at keeping an up-to-date view on remaining work is in the [lotus testnet github project board](https://github.com/filecoin-project/lotus/projects/1). - ## Building & Documentation For instructions on how to build lotus from source, please visit [https://docs.lotu.sh](https://docs.lotu.sh) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation). +## Development + +All work is tracked via issues. An attempt at keeping an up-to-date view on remaining work is in the [lotus testnet github project board](https://github.com/filecoin-project/lotus/projects/1). + +The main branches under development at the moment are: +* [`master`](https://github.com/filecoin-project/lotus): current testnet. +* [`next`](https://github.com/filecoin-project/lotus/tree/next): working branch with chain-breaking changes. +* [`interopnet`](https://github.com/filecoin-project/lotus/tree/interopnet): devnet running one of `next` commits. + ## License Dual-licensed under [MIT](https://github.com/filecoin-project/lotus/blob/master/LICENSE-MIT) + [Apache 2.0](https://github.com/filecoin-project/lotus/blob/master/LICENSE-APACHE) From 4e9293ba04946ab3b3ef7bb8b11af55c07b17878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 12 Jun 2020 19:16:54 +0100 Subject: [PATCH 143/379] fix a potential race with chain reorgs notifees. --- chain/store/store.go | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/chain/store/store.go b/chain/store/store.go index dba5995de..f0fb2a611 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -48,6 +48,9 @@ var log = logging.Logger("chainstore") var chainHeadKey = dstore.NewKey("head") +// ReorgNotifee represents a callback that gets called upon reorgs. +type ReorgNotifee func(rev, app []*types.TipSet) error + type ChainStore struct { bs bstore.Blockstore ds dstore.Datastore @@ -63,8 +66,8 @@ type ChainStore struct { cindex *ChainIndex - reorgCh chan<- reorg - headChangeNotifs []func(rev, app []*types.TipSet) error + reorgCh chan<- reorg + reorgNotifeeCh chan ReorgNotifee mmCache *lru.ARCCache tsCache *lru.ARCCache @@ -89,8 +92,6 @@ func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls runtime.Sys cs.cindex = ci - cs.reorgCh = cs.reorgWorker(context.TODO()) - hcnf := func(rev, app []*types.TipSet) error { cs.pubLk.Lock() defer cs.pubLk.Unlock() @@ -122,7 +123,8 @@ func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls runtime.Sys return nil } - cs.headChangeNotifs = append(cs.headChangeNotifs, hcnf, hcmetric) + cs.reorgNotifeeCh = make(chan ReorgNotifee) + cs.reorgCh = cs.reorgWorker(context.TODO(), []ReorgNotifee{hcnf, hcmetric}) return cs } @@ -211,8 +213,8 @@ func (cs *ChainStore) SubHeadChanges(ctx context.Context) chan []*api.HeadChange return out } -func (cs *ChainStore) SubscribeHeadChanges(f func(rev, app []*types.TipSet) error) { - cs.headChangeNotifs = append(cs.headChangeNotifs, f) +func (cs *ChainStore) SubscribeHeadChanges(f ReorgNotifee) { + cs.reorgNotifeeCh <- f } func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error { @@ -273,13 +275,19 @@ type reorg struct { new *types.TipSet } -func (cs *ChainStore) reorgWorker(ctx context.Context) chan<- reorg { +func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNotifee) chan<- reorg { out := make(chan reorg, 32) + notifees := make([]ReorgNotifee, len(initialNotifees)) + copy(notifees, initialNotifees) + go func() { defer log.Warn("reorgWorker quit") for { select { + case n := <-cs.reorgNotifeeCh: + notifees = append(notifees, n) + case r := <-out: revert, apply, err := cs.ReorgOps(r.old, r.new) if err != nil { @@ -293,7 +301,7 @@ func (cs *ChainStore) reorgWorker(ctx context.Context) chan<- reorg { apply[i], apply[opp] = apply[opp], apply[i] } - for _, hcf := range cs.headChangeNotifs { + for _, hcf := range notifees { if err := hcf(revert, apply); err != nil { log.Error("head change func errored (BAD): ", err) } From 91ea03907709e923ac9499144c40d6e44be37cab Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 12 Jun 2020 20:46:04 +0200 Subject: [PATCH 144/379] Change ellipsis, more accurate timing Signed-off-by: Jakub Sztandera --- chain/vm/runtime.go | 4 +- chain/vm/vm.go | 27 +++++++------- cli/state.go | 89 ++++++++++++++++++++++++++++++++------------- 3 files changed, 81 insertions(+), 39 deletions(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 67f7adc03..be34f075c 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -371,6 +371,8 @@ func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars } func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) { + + start := time.Now() ctx, span := trace.StartSpan(rt.ctx, "vmc.Send") defer span.End() if span.IsRecordingEvents() { @@ -396,7 +398,7 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, } defer st.ClearSnapshot() - ret, errSend, subrt := rt.vm.send(ctx, msg, rt, nil) + ret, errSend, subrt := rt.vm.send(ctx, msg, rt, nil, start) if errSend != nil { if errRevert := st.Revert(); errRevert != nil { return nil, aerrors.Escalate(errRevert, "failed to revert state tree after failed subcall") diff --git a/chain/vm/vm.go b/chain/vm/vm.go index acae3cde0..9a4c9991d 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -96,14 +96,13 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres originNonce: originNonce, height: vm.blockHeight, - gasUsed: usedGas, - gasAvailable: msg.GasLimit, - numActorsCreated: nac, - pricelist: PricelistByEpoch(vm.blockHeight), - allowInternal: true, - callerValidated: false, - executionTrace: types.ExecutionTrace{Msg: msg}, - lastGasChargeTime: time.Now(), + gasUsed: usedGas, + gasAvailable: msg.GasLimit, + numActorsCreated: nac, + pricelist: PricelistByEpoch(vm.blockHeight), + allowInternal: true, + callerValidated: false, + executionTrace: types.ExecutionTrace{Msg: msg}, } rt.cst = &cbor.BasicIpldStore{ @@ -172,8 +171,7 @@ type ApplyRet struct { } func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, - gasCharge *GasCharge) ([]byte, aerrors.ActorError, *Runtime) { - start := time.Now() + gasCharge *GasCharge, start time.Time) ([]byte, aerrors.ActorError, *Runtime) { st := vm.cstate @@ -189,6 +187,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, } rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac) + rt.lastGasChargeTime = start if parent != nil { rt.lastGasChargeTime = parent.lastGasChargeTime rt.lastGasCharge = parent.lastGasCharge @@ -273,7 +272,8 @@ func checkMessage(msg *types.Message) error { func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) { start := time.Now() - ret, actorErr, rt := vm.send(ctx, msg, nil, nil) + ret, actorErr, rt := vm.send(ctx, msg, nil, nil, start) + rt.finilizeGasTracing() return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: aerrors.RetCode(actorErr), @@ -390,8 +390,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, } defer st.ClearSnapshot() - ret, actorErr, rt := vm.send(ctx, msg, nil, &msgGas) - rt.finilizeGasTracing() + ret, actorErr, rt := vm.send(ctx, msg, nil, &msgGas, start) if aerrors.IsFatal(actorErr) { return nil, xerrors.Errorf("[from=%s,to=%s,n=%d,m=%d,h=%d] fatal error: %w", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr) } @@ -445,6 +444,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, return nil, xerrors.Errorf("gas handling math is wrong") } + rt.finilizeGasTracing() + return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: errcode, diff --git a/cli/state.go b/cli/state.go index f2185c4ab..d3d95675c 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1001,6 +1001,12 @@ var compStateTemplate = ` display: inline; background-color: #ddd; } + hr { + border: none; + height: 1px; + background-color: black; + margin: 0; + } @@ -1049,32 +1055,54 @@ var compStateMsg = `
Error:
{{.Error}}
{{end}} -
- Gas Trace -
NameTotal/Compute/StorageTime TakenLocation
{{.Name}}{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}{{.Location}}
{{.Name}}{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}} + {{ range $index, $ele := .Location }} + {{- if $index }}|​{{end -}} + {{- if .Show -}} + {{- if .Important }}{{end -}} + {{- . -}} + {{- if .Important }}{{end -}} + {{- else -}} + + {{- end -}} + {{end}} +
Sum{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}
- - {{range .GasCharges}} - - + {{end}} + {{with SumGas .GasCharges}} + + {{end}} +
NameTotal/Compute/StorageTime TakenLocation
{{.Name}}{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}} - {{ range $index, $ele := .Location }} - {{- if $index }}|​{{end -}} - {{- if .Show -}} - {{- if .Important }}{{end -}} - {{- . -}} - {{- if .Important }}{{end -}} - {{- else -}} - - {{- end -}} +
+Gas Trace + + + {{range .GasCharges}} + + - {{end}} - {{with SumGas .GasCharges}} - - {{end}} -
NameTotal/Compute/StorageTime TakenLocation
{{.Name}}{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}} + {{ $fImp := FirstImportant .Location }} + {{ if $fImp }} +
+ {{ $fImp }}
+ {{ $elipOn := false }} + {{ range $index, $ele := .Location -}} + {{- if $index }}
{{end -}} + {{- if .Show -}} + {{ if $elipOn }} + {{ $elipOn = false }} + + {{end}} + + {{- if .Important }}{{end -}} + {{- . -}} + {{if .Important }}{{end}} + {{else}} + {{ if not $elipOn }} + {{ $elipOn = true }} + {{end}} -
Sum{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}
-
+ + {{end}} +
Sum{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}
+ + + {{if gt (len .Subcalls) 0}}
Subcalls:
{{$hash := .Hash}} @@ -1102,6 +1130,17 @@ func computeStateHTMLTempl(ts *types.TipSet, o *api.ComputeStateOutput, getCode "SumGas": sumGas, "CodeStr": codeStr, "Call": call, + "FirstImportant": func(locs []types.Loc) *types.Loc { + if len(locs) != 0 { + for _, l := range locs { + if l.Important() { + return &l + } + } + return &locs[0] + } + return nil + }, }).Parse(compStateTemplate) if err != nil { return err From 82c6be14f44bc14c9667e264a0d35123cd09a6de Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Fri, 12 Jun 2020 22:34:00 -0300 Subject: [PATCH 145/379] unchecked errs Signed-off-by: Ignacio Hagopian --- chain/gen/genesis/miners.go | 3 +++ cli/chain.go | 3 +++ cli/state.go | 11 ++++++----- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 51a128d54..26f52eae0 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -239,6 +239,9 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid st.TotalQualityAdjPower = big.Sub(st.TotalQualityAdjPower, big.NewInt(1)) return nil }) + if err != nil { + return cid.Undef, xerrors.Errorf("mutating state: %w", err) + } c, err := vm.Flush(ctx) if err != nil { diff --git a/cli/chain.go b/cli/chain.go index cbdd957e9..0dfcb926a 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -221,6 +221,9 @@ var chainStatObjCmd = &cli.Command{ base := cid.Undef if cctx.IsSet("base") { base, err = cid.Decode(cctx.String("base")) + if err != nil { + return err + } } stats, err := api.ChainStatObj(ctx, obj, base) diff --git a/cli/state.go b/cli/state.go index 6b5c9035b..910b9557a 100644 --- a/cli/state.go +++ b/cli/state.go @@ -359,7 +359,7 @@ var stateReplaySetCmd = &cli.Command{ return fmt.Errorf("message cid was invalid: %s", err) } - api, closer, err := GetFullNodeAPI(cctx) + fapi, closer, err := GetFullNodeAPI(cctx) if err != nil { return err } @@ -381,7 +381,7 @@ var stateReplaySetCmd = &cli.Command{ if len(tscids) > 0 { var headers []*types.BlockHeader for _, c := range tscids { - h, err := api.ChainGetBlock(ctx, c) + h, err := fapi.ChainGetBlock(ctx, c) if err != nil { return err } @@ -391,12 +391,13 @@ var stateReplaySetCmd = &cli.Command{ ts, err = types.NewTipSet(headers) } else { - r, err := api.StateWaitMsg(ctx, mcid) + var r *api.MsgLookup + r, err = fapi.StateWaitMsg(ctx, mcid) if err != nil { return xerrors.Errorf("finding message in chain: %w", err) } - ts, err = api.ChainGetTipSet(ctx, r.TipSet.Parents()) + ts, err = fapi.ChainGetTipSet(ctx, r.TipSet.Parents()) } if err != nil { return err @@ -404,7 +405,7 @@ var stateReplaySetCmd = &cli.Command{ } - res, err := api.StateReplay(ctx, ts.Key(), mcid) + res, err := fapi.StateReplay(ctx, ts.Key(), mcid) if err != nil { return xerrors.Errorf("replay call failed: %w", err) } From 6d36c030e0cafcf99c17c2c77846a60ee9568981 Mon Sep 17 00:00:00 2001 From: chunqizhi <1558763837@qq.com> Date: Sat, 13 Jun 2020 18:05:30 +0800 Subject: [PATCH 146/379] Add usage information for provingInfoCmd --- cmd/lotus-storage-miner/proving.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 7cfa010b9..60e85e0d8 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -16,6 +16,7 @@ import ( var provingCmd = &cli.Command{ Name: "proving", + Usage:"View proving information", Subcommands: []*cli.Command{ provingInfoCmd, provingDeadlinesCmd, @@ -24,6 +25,7 @@ var provingCmd = &cli.Command{ var provingInfoCmd = &cli.Command{ Name: "info", + Usage:"View current state information", Action: func(cctx *cli.Context) error { nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { @@ -146,6 +148,7 @@ func epochTime(curr, e abi.ChainEpoch) string { var provingDeadlinesCmd = &cli.Command{ Name: "deadlines", + Usage:"View the current proving period deadlines information", Action: func(cctx *cli.Context) error { nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { From c822816f8ee3805c5ed620cbd098782c8fa20aac Mon Sep 17 00:00:00 2001 From: Howard Yeh Date: Sun, 14 Jun 2020 17:49:20 +0800 Subject: [PATCH 147/379] Cache tipset validation progress --- chain/store/store.go | 17 +++++++++++++++++ chain/sync.go | 25 +++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/chain/store/store.go b/chain/store/store.go index dba5995de..e3d6506e4 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -47,6 +47,7 @@ import ( var log = logging.Logger("chainstore") var chainHeadKey = dstore.NewKey("head") +var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation") type ChainStore struct { bs bstore.Blockstore @@ -215,6 +216,22 @@ func (cs *ChainStore) SubscribeHeadChanges(f func(rev, app []*types.TipSet) erro cs.headChangeNotifs = append(cs.headChangeNotifs, f) } +func (cs *ChainStore) IsBlockValidated(ctx context.Context, blkid cid.Cid) (bool, error) { + key := blockValidationCacheKeyPrefix.Instance(blkid.String()) + + return cs.ds.Has(key) +} + +func (cs *ChainStore) MarkBlockAsValidated(ctx context.Context, blkid cid.Cid) error { + key := blockValidationCacheKeyPrefix.Instance(blkid.String()) + + if err := cs.ds.Put(key, []byte{0}); err != nil { + return xerrors.Errorf("cache block validation: %w", err) + } + + return nil +} + func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error { ts, err := types.NewTipSet([]*types.BlockHeader{b}) if err != nil { diff --git a/chain/sync.go b/chain/sync.go index 07d470d28..a1315d82b 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -529,7 +529,24 @@ func blockSanityChecks(h *types.BlockHeader) error { } // Should match up with 'Semantical Validation' in validation.md in the spec -func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { +func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (err error) { + defer func() { + // b.Cid() could panic for empty blocks that are used in tests. + if rerr := recover(); rerr != nil { + err = xerrors.Errorf("validate block panic: %w", rerr) + return + } + }() + + isValidated, err := syncer.store.IsBlockValidated(ctx, b.Cid()) + if err != nil { + return xerrors.Errorf("check block validation cache %s: %w", b.Cid(), err) + } + + if isValidated { + return nil + } + validationStart := time.Now() defer func() { dur := time.Since(validationStart) @@ -759,7 +776,11 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err } } - return merr + if err := syncer.store.MarkBlockAsValidated(ctx, b.Cid()); err != nil { + return xerrors.Errorf("caching block validation %s: %w", b.Cid(), err) + } + + return nil } func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.BlockHeader, prevBeacon types.BeaconEntry, lbst cid.Cid, waddr address.Address) error { From 12056c8904a41fcf398a5eb0dd299551ef9a44c4 Mon Sep 17 00:00:00 2001 From: chunqizhi <1558763837@qq.com> Date: Mon, 15 Jun 2020 17:43:42 +0800 Subject: [PATCH 148/379] go fmt --- cmd/lotus-storage-miner/proving.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 60e85e0d8..d419efd7b 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -15,8 +15,8 @@ import ( ) var provingCmd = &cli.Command{ - Name: "proving", - Usage:"View proving information", + Name: "proving", + Usage: "View proving information", Subcommands: []*cli.Command{ provingInfoCmd, provingDeadlinesCmd, @@ -24,8 +24,8 @@ var provingCmd = &cli.Command{ } var provingInfoCmd = &cli.Command{ - Name: "info", - Usage:"View current state information", + Name: "info", + Usage: "View current state information", Action: func(cctx *cli.Context) error { nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { @@ -147,8 +147,8 @@ func epochTime(curr, e abi.ChainEpoch) string { } var provingDeadlinesCmd = &cli.Command{ - Name: "deadlines", - Usage:"View the current proving period deadlines information", + Name: "deadlines", + Usage: "View the current proving period deadlines information", Action: func(cctx *cli.Context) error { nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { From 464f6a6b08f3267fcf3b5d5aea2bf190c6578c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 15 Jun 2020 14:49:18 +0200 Subject: [PATCH 149/379] Update specs-actors to v0.6 --- extern/filecoin-ffi | 2 +- go.mod | 4 ++-- go.sum | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 61c02f6be..1bff7f456 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 61c02f6bea8d69bb79c70daa1d62f26c486643aa +Subproject commit 1bff7f4563370ada590a605b5459b91e1662ebaa diff --git a/go.mod b/go.mod index 21fea095f..5cfe55a8d 100644 --- a/go.mod +++ b/go.mod @@ -29,8 +29,8 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d - github.com/filecoin-project/specs-actors v0.5.6 + github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0 + github.com/filecoin-project/specs-actors v0.6.0 github.com/filecoin-project/specs-storage v0.1.0 github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index e10972bb6..5366cf6b6 100644 --- a/go.sum +++ b/go.sum @@ -223,6 +223,8 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d h1:q7KC8/yIirwVX7JCLgjEmo5LX77V8tYV0EzVCnCwrE8= github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d/go.mod h1:SfaVNw/A6LwqqEt6wEMVBN5Grn3XC50j+yjmegHIe7Y= +github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0 h1:DpdlpS3G2XN+F68rxOTAXsGL3cV7UkFr0TxdmKSiaJg= +github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= @@ -231,6 +233,8 @@ github.com/filecoin-project/specs-actors v0.5.5 h1:bDsowem6dLRc9B7g3sgFYvHgfWTH4 github.com/filecoin-project/specs-actors v0.5.5/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.5.6 h1:WlhtoXwFoKlP1b06NI4NJaxC4m9EXNV+qFVl43/xRN8= github.com/filecoin-project/specs-actors v0.5.6/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9kNbbHOcU/9oiC0= +github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= From a23a87a17fedaed8f3ff77a17f02e55aca5c2515 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 15 Jun 2020 16:18:05 +0200 Subject: [PATCH 150/379] Add virtual gas Signed-off-by: Jakub Sztandera --- chain/types/execresult.go | 11 +++++++---- chain/vm/gas.go | 9 +++++++++ chain/vm/runtime.go | 16 ++++++++++------ cli/state.go | 25 ++++++++++++++++++++++--- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/chain/types/execresult.go b/chain/types/execresult.go index 7ffa8c219..b0e1f760d 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -21,10 +21,13 @@ type ExecutionTrace struct { type GasTrace struct { Name string - Location []Loc - TotalGas int64 - ComputeGas int64 - StorageGas int64 + Location []Loc + TotalGas int64 + ComputeGas int64 + StorageGas int64 + TotalVirtualGas int64 + VirtualComputeGas int64 + VirtualStorageGas int64 TimeTaken time.Duration Extra interface{} diff --git a/chain/vm/gas.go b/chain/vm/gas.go index c030621f6..dc9966e57 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -21,11 +21,20 @@ type GasCharge struct { Name string ComputeGas int64 StorageGas int64 + + VirtualCompute int64 + VirtualStorage int64 } func (g GasCharge) Total() int64 { return g.ComputeGas*GasComputeMulti + g.StorageGas*GasStorageMulti } +func (g GasCharge) WithVirtual(compute, storage int64) GasCharge { + out := g + out.VirtualCompute = compute + out.VirtualStorage = storage + return out +} func newGasCharge(name string, computeGas int64, storageGas int64) GasCharge { return GasCharge{ diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index be34f075c..9b83593ab 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -524,11 +524,14 @@ func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError } gasTrace := types.GasTrace{ - Name: gas.Name, - TotalGas: toUse, - ComputeGas: gas.ComputeGas, - StorageGas: gas.StorageGas, - Callers: callers[:cout], + Name: gas.Name, + TotalGas: toUse, + ComputeGas: gas.ComputeGas, + StorageGas: gas.StorageGas, + TotalVirtualGas: gas.VirtualCompute*GasComputeMulti + gas.VirtualStorage*GasStorageMulti, + VirtualComputeGas: gas.VirtualCompute, + VirtualStorageGas: gas.VirtualStorage, + Callers: callers[:cout], } rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace) rt.lastGasChargeTime = now @@ -536,7 +539,8 @@ func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError if rt.gasUsed+toUse > rt.gasAvailable { rt.gasUsed = rt.gasAvailable - return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d", rt.gasUsed, rt.gasAvailable) + return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d", + rt.gasUsed, rt.gasAvailable) } rt.gasUsed += toUse return nil diff --git a/cli/state.go b/cli/state.go index bb5dd4277..753b0b017 100644 --- a/cli/state.go +++ b/cli/state.go @@ -971,6 +971,7 @@ var compStateTemplate = ` } .slow-true-false { color: #660; } .slow-true-true { color: #f80; } + .deemp { color: #444; } table { font-size: 12px; border-collapse: collapse; @@ -1060,8 +1061,20 @@ var compStateMsg = ` Gas Trace + {{define "virt" -}} + {{- if . -}} + +({{.}}) + {{- end -}} + {{- end}} + + {{define "gasC" -}} + + {{- end}} + {{range .GasCharges}} - + + {{template "gasC" .}} + {{end}} {{with SumGas .GasCharges}} - + + {{template "gasC" .}} + + {{end}}
NameTotal/Compute/StorageTime TakenLocation
{{.TotalGas}}{{template "virt" .TotalVirtualGas }}/{{.ComputeGas}}{{template "virt" .VirtualComputeGas}}/{{.StorageGas}}{{template "virt" .VirtualStorageGas}}
{{.Name}}{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}
{{.Name}}{{.TimeTaken}} {{ $fImp := FirstImportant .Location }} {{ if $fImp }} @@ -1098,7 +1111,10 @@ var compStateMsg = `
Sum{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}{{.TimeTaken}}
Sum{{.TimeTaken}}
@@ -1201,7 +1217,10 @@ func sumGas(changes []*types.GasTrace) types.GasTrace { out.TotalGas += gc.TotalGas out.ComputeGas += gc.ComputeGas out.StorageGas += gc.StorageGas - out.TimeTaken += gc.TimeTaken + + out.TotalVirtualGas += gc.TotalVirtualGas + out.VirtualComputeGas += gc.VirtualComputeGas + out.VirtualStorageGas += gc.VirtualStorageGas } return out From 2a78ebabd9117de39ac344cea12bd7845b528558 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 17 Apr 2020 20:16:36 +0200 Subject: [PATCH 151/379] Use HashVerify Signed-off-by: Jakub Sztandera --- chain/sync.go | 18 ++++-------------- lib/sigs/bls/init.go | 4 ++-- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/chain/sync.go b/chain/sync.go index f4b32f2bc..bfbca0ec1 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -8,7 +8,6 @@ import ( "os" "sort" "strings" - "sync" "time" "github.com/Gurpartap/async" @@ -949,23 +948,14 @@ func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig *crypto.Signat trace.Int64Attribute("msgCount", int64(len(msgs))), ) - var wg sync.WaitGroup - - digests := make([]bls.Digest, len(msgs)) - for i := 0; i < 10; i++ { - wg.Add(1) - go func(w int) { - defer wg.Done() - for j := 0; (j*10)+w < len(msgs); j++ { - digests[j*10+w] = bls.Hash(bls.Message(msgs[j*10+w].Bytes())) - } - }(i) + bmsgs := make([]bls.Message, len(msgs)) + for i, m := range msgs { + bmsgs[i] = m.Bytes() } - wg.Wait() var bsig bls.Signature copy(bsig[:], sig.Data) - if !bls.Verify(&bsig, digests, pubks) { + if !bls.HashVerify(&bsig, bmsgs, pubks) { return xerrors.New("bls aggregate signature failed to verify") } diff --git a/lib/sigs/bls/init.go b/lib/sigs/bls/init.go index fe916c446..66a5ade81 100644 --- a/lib/sigs/bls/init.go +++ b/lib/sigs/bls/init.go @@ -33,16 +33,16 @@ func (blsSigner) Sign(p []byte, msg []byte) ([]byte, error) { } func (blsSigner) Verify(sig []byte, a address.Address, msg []byte) error { - digests := []ffi.Digest{ffi.Hash(ffi.Message(msg))} var pubk ffi.PublicKey copy(pubk[:], a.Payload()) pubkeys := []ffi.PublicKey{pubk} + digests := []ffi.Message{msg} var s ffi.Signature copy(s[:], sig) - if !ffi.Verify(&s, digests, pubkeys) { + if !ffi.HashVerify(&s, digests, pubkeys) { return fmt.Errorf("bls signature failed to verify") } From 907364ce670c394ae3308e63728005f591468836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 15 Jun 2020 18:30:49 +0200 Subject: [PATCH 152/379] Update deps, fix more tests --- api/apistruct/struct.go | 26 +++++++++++++------------- api/docgen/docgen.go | 2 +- api/types.go | 2 +- build/params_testnet.go | 8 ++++---- chain/gen/gen.go | 10 +++++----- chain/gen/gen_test.go | 4 ++-- chain/gen/genesis/miners.go | 12 ++++++------ chain/stmgr/forks_test.go | 4 ++-- chain/stmgr/stmgr.go | 7 +++---- chain/stmgr/utils.go | 6 +++--- chain/store/store_test.go | 4 ++-- chain/sync_test.go | 4 ++-- chain/types/blockheader_test.go | 9 ++++----- chain/vm/gas.go | 4 ++-- chain/vm/gas_v0.go | 2 +- chain/vm/syscalls.go | 2 +- cmd/lotus-bench/main.go | 23 ++++++++++++++--------- cmd/lotus-seed/seed/seed.go | 11 +++-------- cmd/lotus-shed/proofs.go | 2 +- extern/filecoin-ffi | 2 +- genesis/types.go | 2 +- go.mod | 10 ++++++---- go.sum | 10 ++++++++++ lotuspond/spawn.go | 6 +++--- node/impl/full/state.go | 2 +- node/node_test.go | 6 +++--- storage/adapter_storage_miner.go | 2 +- storage/miner.go | 2 +- storage/wdpost_run.go | 6 +++--- storage/wdpost_sched.go | 2 +- 30 files changed, 101 insertions(+), 91 deletions(-) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 31cd6badd..c607c13a4 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -207,18 +207,18 @@ type StorageMinerStruct struct { WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"` - StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` - StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"` - StorageStat func(context.Context, stores.ID) (stores.FsStat, error) `perm:"admin"` - StorageAttach func(context.Context, stores.StorageInfo, stores.FsStat) error `perm:"admin"` - StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"` - StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"` - StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"` - StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` - StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"` - StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` - StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` - StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` + StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` + StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"` + StorageStat func(context.Context, stores.ID) (stores.FsStat, error) `perm:"admin"` + StorageAttach func(context.Context, stores.StorageInfo, stores.FsStat) error `perm:"admin"` + StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"` + StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"` + StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"` + StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` + StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"` + StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` + StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` + StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` @@ -812,7 +812,7 @@ func (c *StorageMinerStruct) StorageInfo(ctx context.Context, id stores.ID) (sto return c.Internal.StorageInfo(ctx, id) } -func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, pt stores.PathType) ([]stores.StorageInfo, error) { +func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, pt stores.PathType) ([]stores.StorageInfo, error) { return c.Internal.StorageBestAlloc(ctx, allocate, spt, pt) } diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index d0b5d8558..4cd982aa7 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -72,7 +72,7 @@ func init() { addExample(pid) addExample(bitfield.NewFromSet([]uint64{5})) - addExample(abi.RegisteredProof_StackedDRG32GiBPoSt) + addExample(abi.RegisteredSealProof_StackedDrg32GiBV1) addExample(abi.ChainEpoch(10101)) addExample(crypto.SigTypeBLS) addExample(int64(9)) diff --git a/api/types.go b/api/types.go index f5a595353..29bd7401c 100644 --- a/api/types.go +++ b/api/types.go @@ -50,7 +50,7 @@ type MinerInfo struct { WorkerChangeEpoch abi.ChainEpoch PeerId peer.ID Multiaddrs []abi.Multiaddrs - SealProofType abi.RegisteredProof + SealProofType abi.RegisteredSealProof SectorSize abi.SectorSize WindowPoStPartitionSectors uint64 } diff --git a/build/params_testnet.go b/build/params_testnet.go index 917b8059e..c222862eb 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -13,10 +13,10 @@ import ( func init() { power.ConsensusMinerMinPower = big.NewInt(1024 << 20) - miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG512MiBSeal: {}, - abi.RegisteredProof_StackedDRG32GiBSeal: {}, - abi.RegisteredProof_StackedDRG64GiBSeal: {}, + miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg512MiBV1: {}, + abi.RegisteredSealProof_StackedDrg32GiBV1: {}, + abi.RegisteredSealProof_StackedDrg64GiBV1: {}, } } diff --git a/chain/gen/gen.go b/chain/gen/gen.go index d58bbc28e..368240a04 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -89,8 +89,8 @@ func (m mybs) Get(c cid.Cid) (block.Block, error) { } func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { - saminer.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } mr := repo.NewMemory(nil) @@ -141,7 +141,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { return nil, err } - genm1, k1, err := seed.PreSeal(maddr1, abi.RegisteredProof_StackedDRG2KiBPoSt, 0, numSectors, m1temp, []byte("some randomness"), nil) + genm1, k1, err := seed.PreSeal(maddr1, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m1temp, []byte("some randomness"), nil) if err != nil { return nil, err } @@ -153,7 +153,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { return nil, err } - genm2, k2, err := seed.PreSeal(maddr2, abi.RegisteredProof_StackedDRG2KiBPoSt, 0, numSectors, m2temp, []byte("some randomness"), nil) + genm2, k2, err := seed.PreSeal(maddr2, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m2temp, []byte("some randomness"), nil) if err != nil { return nil, err } @@ -611,6 +611,6 @@ func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info abi.WindowPo panic("not supported") } -func (m genFakeVerifier) GenerateWinningPoStSectorChallenge(ctx context.Context, proof abi.RegisteredProof, id abi.ActorID, randomness abi.PoStRandomness, u uint64) ([]uint64, error) { +func (m genFakeVerifier) GenerateWinningPoStSectorChallenge(ctx context.Context, proof abi.RegisteredPoStProof, id abi.ActorID, randomness abi.PoStRandomness, u uint64) ([]uint64, error) { panic("not supported") } diff --git a/chain/gen/gen_test.go b/chain/gen/gen_test.go index 69c8587ef..7a4d73031 100644 --- a/chain/gen/gen_test.go +++ b/chain/gen/gen_test.go @@ -14,8 +14,8 @@ import ( ) func init() { - miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } power.ConsensusMinerMinPower = big.NewInt(2048) verifreg.MinVerifiedDealSize = big.NewInt(256) diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 685fc58cc..acc63c31c 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -204,12 +204,12 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid { newSectorInfo := &miner.SectorOnChainInfo{ Info: miner.SectorPreCommitInfo{ - RegisteredProof: preseal.ProofType, - SectorNumber: preseal.SectorID, - SealedCID: preseal.CommR, - SealRandEpoch: 0, - DealIDs: []abi.DealID{dealIDs[pi]}, - Expiration: preseal.Deal.EndEpoch, + SealProof: preseal.ProofType, + SectorNumber: preseal.SectorID, + SealedCID: preseal.CommR, + SealRandEpoch: 0, + DealIDs: []abi.DealID{dealIDs[pi]}, + Expiration: preseal.Deal.EndEpoch, }, ActivationEpoch: 0, DealWeight: dealWeight.DealWeight, diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index a3b01cd84..2fbcbbc99 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -37,8 +37,8 @@ import ( ) func init() { - miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } power.ConsensusMinerMinPower = big.NewInt(2048) verifreg.MinVerifiedDealSize = big.NewInt(256) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index d4c12dffe..917b5ca26 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -184,10 +184,9 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, pstate cid.Cid, bms []B var err error params, err := actors.SerializeParams(&reward.AwardBlockRewardParams{ - Miner: b.Miner, - Penalty: penalty, - GasReward: gasReward, - TicketCount: 1, // TODO: no longer need ticket count here. + Miner: b.Miner, + Penalty: penalty, + GasReward: gasReward, }) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to serialize award params: %w", err) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 308c30823..cf424b4eb 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -206,9 +206,9 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S out := make([]abi.SectorInfo, len(ids)) for i, n := range ids { out[i] = abi.SectorInfo{ - RegisteredProof: wpt, - SectorNumber: sectorSet[n].ID, - SealedCID: sectorSet[n].Info.Info.SealedCID, + SealProof: spt, + SectorNumber: sectorSet[n].ID, + SealedCID: sectorSet[n].Info.Info.SealedCID, } } diff --git a/chain/store/store_test.go b/chain/store/store_test.go index 41b875916..939c85d20 100644 --- a/chain/store/store_test.go +++ b/chain/store/store_test.go @@ -22,8 +22,8 @@ import ( ) func init() { - miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } power.ConsensusMinerMinPower = big.NewInt(2048) verifreg.MinVerifiedDealSize = big.NewInt(256) diff --git a/chain/sync_test.go b/chain/sync_test.go index e1c846d4e..92c0f72d7 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -34,8 +34,8 @@ import ( func init() { build.InsecurePoStValidation = true os.Setenv("TRUST_PARAMS", "1") - miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } power.ConsensusMinerMinPower = big.NewInt(2048) verifreg.MinVerifiedDealSize = big.NewInt(256) diff --git a/chain/types/blockheader_test.go b/chain/types/blockheader_test.go index 387fe86c2..a1ece308a 100644 --- a/chain/types/blockheader_test.go +++ b/chain/types/blockheader_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/hex" "fmt" + "github.com/stretchr/testify/require" "reflect" "testing" @@ -79,7 +80,7 @@ func TestInteropBH(t *testing.T) { } posts := []abi.PoStProof{ - {abi.RegisteredProof_StackedDRG2KiBWinningPoSt, []byte{0x07}}, + {abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, []byte{0x07}}, } bh := &BlockHeader{ @@ -116,10 +117,8 @@ func TestInteropBH(t *testing.T) { } // acquired from go-filecoin - gfc := "8f5501d04cb15021bf6bd003073d79e2238d4e61f1ad22814301020381420a0b818205410c818209410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f603" - if gfc != hex.EncodeToString(bhsb) { - t.Fatal("not equal!") - } + gfc := "8f5501d04cb15021bf6bd003073d79e2238d4e61f1ad22814301020381420a0b818205410c818200410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f603" + require.Equal(t, gfc, hex.EncodeToString(bhsb)) } func BenchmarkBlockHeaderMarshal(b *testing.B) { diff --git a/chain/vm/gas.go b/chain/vm/gas.go index c030621f6..66d74fb70 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -59,7 +59,7 @@ type Pricelist interface { OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error) OnHashing(dataSize int) GasCharge - OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) GasCharge + OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge OnVerifySeal(info abi.SealVerifyInfo) GasCharge OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge OnVerifyConsensusFault() GasCharge @@ -136,7 +136,7 @@ func (ps pricedSyscalls) HashBlake2b(data []byte) [32]byte { } // Computes an unsealed sector CID (CommD) from its constituent piece CIDs (CommPs) and sizes. -func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredProof, pieces []abi.PieceInfo) (cid.Cid, error) { +func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) { ps.chargeGas(ps.pl.OnComputeUnsealedSectorCid(reg, pieces)) return ps.under.ComputeUnsealedSectorCID(reg, pieces) } diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index c631beaee..b1b2c5c9d 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -142,7 +142,7 @@ func (pl *pricelistV0) OnHashing(dataSize int) GasCharge { } // OnComputeUnsealedSectorCid -func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) GasCharge { +func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0) } diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index 2349bc324..a5910121d 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -43,7 +43,7 @@ type syscallShim struct { verifier ffiwrapper.Verifier } -func (ss *syscallShim) ComputeUnsealedSectorCID(st abi.RegisteredProof, pieces []abi.PieceInfo) (cid.Cid, error) { +func (ss *syscallShim) ComputeUnsealedSectorCID(st abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) { var sum abi.PaddedPieceSize for _, p := range pieces { sum += p.Size diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 7d7991636..57f5241df 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -74,7 +74,7 @@ func main() { log.Info("Starting lotus-bench") - miner.SupportedProofTypes[abi.RegisteredProof_StackedDRG2KiBSeal] = struct{}{} + miner.SupportedProofTypes[abi.RegisteredSealProof_StackedDrg2KiBV1] = struct{}{} app := &cli.App{ Name: "lotus-bench", @@ -270,9 +270,9 @@ var sealBenchCmd = &cli.Command{ for _, s := range genm.Sectors { sealedSectors = append(sealedSectors, abi.SectorInfo{ - SealedCID: s.CommR, - SectorNumber: s.SectorID, - RegisteredProof: s.ProofType, + SealedCID: s.CommR, + SectorNumber: s.SectorID, + SealProof: s.ProofType, }) } } @@ -284,7 +284,12 @@ var sealBenchCmd = &cli.Command{ if !c.Bool("skip-commit2") { log.Info("generating winning post candidates") - fcandidates, err := ffiwrapper.ProofVerifier.GenerateWinningPoStSectorChallenge(context.TODO(), spt, mid, challenge[:], uint64(len(sealedSectors))) + wpt, err := spt.RegisteredWindowPoStProof() + if err != nil { + return err + } + + fcandidates, err := ffiwrapper.ProofVerifier.GenerateWinningPoStSectorChallenge(context.TODO(), wpt, mid, challenge[:], uint64(len(sealedSectors))) if err != nil { return err } @@ -485,9 +490,9 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid precommit2 := time.Now() sealedSectors = append(sealedSectors, abi.SectorInfo{ - RegisteredProof: sb.SealProofType(), - SectorNumber: i, - SealedCID: cids.Sealed, + SealProof: sb.SealProofType(), + SectorNumber: i, + SealedCID: cids.Sealed, }) seed := lapi.SealSeed{ @@ -536,7 +541,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid svi := abi.SealVerifyInfo{ SectorID: abi.SectorID{Miner: mid, Number: i}, SealedCID: cids.Sealed, - RegisteredProof: sb.SealProofType(), + SealProof: sb.SealProofType(), Proof: proof, DealIDs: nil, Randomness: ticket, diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 06cb011b4..ffb651c00 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -33,12 +33,7 @@ import ( var log = logging.Logger("preseal") -func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) { - spt, err := pt.RegisteredSealProof() - if err != nil { - return nil, nil, err - } - +func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) { mid, err := address.IDFromAddress(maddr) if err != nil { return nil, nil, err @@ -63,7 +58,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum return nil, nil, err } - ssize, err := pt.SectorSize() + ssize, err := spt.SectorSize() if err != nil { return nil, nil, err } @@ -102,7 +97,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum CommR: cids.Sealed, CommD: cids.Unsealed, SectorID: sid.Number, - ProofType: pt, + ProofType: spt, }) } diff --git a/cmd/lotus-shed/proofs.go b/cmd/lotus-shed/proofs.go index 3a4615658..f18dc93fb 100644 --- a/cmd/lotus-shed/proofs.go +++ b/cmd/lotus-shed/proofs.go @@ -88,7 +88,7 @@ var verifySealProofCmd = &cli.Command{ Number: snum, }, SealedCID: commr, - RegisteredProof: abi.RegisteredProof(cctx.Int64("proof-type")), + SealProof: abi.RegisteredSealProof(cctx.Int64("proof-type")), Proof: proof, DealIDs: nil, Randomness: abi.SealRandomness(ticket), diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 1bff7f456..5bb4a309b 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 1bff7f4563370ada590a605b5459b91e1662ebaa +Subproject commit 5bb4a309bce9d446ac618f34a8b9e2883af2002f diff --git a/genesis/types.go b/genesis/types.go index 4b95d3311..41d8a413c 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -22,7 +22,7 @@ type PreSeal struct { CommD cid.Cid SectorID abi.SectorNumber Deal market.DealProposal - ProofType abi.RegisteredProof + ProofType abi.RegisteredSealProof } type Miner struct { diff --git a/go.mod b/go.mod index 5cfe55a8d..df0c03c9f 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 - github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94 + github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5 github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 @@ -23,16 +23,16 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 - github.com/filecoin-project/go-fil-markets v0.2.7 + github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615162707-5dd6b2eb253b github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0 + github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6 github.com/filecoin-project/specs-actors v0.6.0 github.com/filecoin-project/specs-storage v0.1.0 - github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa + github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect @@ -127,3 +127,5 @@ require ( replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi + +replace github.com/filecoin-project/go-fil-markets => /home/magik6k/gohack/github.com/filecoin-project/go-fil-markets diff --git a/go.sum b/go.sum index 5366cf6b6..c4a07cf66 100644 --- a/go.sum +++ b/go.sum @@ -184,6 +184,8 @@ github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGj github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94 h1:svEal/usZ/REEjEz6ije3/ALn8duM2CckR0LjT1btx0= github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94/go.mod h1:aOmmdhO0xIRtWCwx3MyIv3tPCCorM1Bq7pNOJGMLndA= +github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5 h1:8Ytl1uk8/Sff7Z2vfb7MOEM3ZRlQKJPqn19FzDcr+bc= +github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5/go.mod h1:HEJn6kOXMNhCNBYNTO/lrEI7wSgqCOR6hN5ecfYUnC8= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= @@ -225,6 +227,10 @@ github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d h1 github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d/go.mod h1:SfaVNw/A6LwqqEt6wEMVBN5Grn3XC50j+yjmegHIe7Y= github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0 h1:DpdlpS3G2XN+F68rxOTAXsGL3cV7UkFr0TxdmKSiaJg= github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= +github.com/filecoin-project/sector-storage v0.0.0-20200615142857-3d1225bf3449 h1:aFXA4iI8WumN1pgEv5gtAyZs3mEX7AdV2xqHf76Dn6o= +github.com/filecoin-project/sector-storage v0.0.0-20200615142857-3d1225bf3449/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= +github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6 h1:NIcubpeasVs++K5EFelMXeURRb8sWCuXQNOSWnvTc14= +github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= @@ -241,6 +247,10 @@ github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sg github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa h1:kTCIBKMhhhVcjCh1ws72vpdDr4cdZjCyIUDFijuWuvA= github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= +github.com/filecoin-project/storage-fsm v0.0.0-20200615142724-95dbdc803c53 h1:mvvBaFPyYugJfmHgFHg0BgE0plwV2IhfgL6tLu02umM= +github.com/filecoin-project/storage-fsm v0.0.0-20200615142724-95dbdc803c53/go.mod h1:ZBID+J03DzANc0cv+sv03ROqfYYZbl62d3u8JftBH6k= +github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg= +github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index 32fc69b05..8100d784a 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -25,8 +25,8 @@ import ( ) func init() { - miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } } @@ -49,7 +49,7 @@ func (api *api) Spawn() (nodeInfo, error) { } sbroot := filepath.Join(dir, "preseal") - genm, ki, err := seed.PreSeal(genMiner, abi.RegisteredProof_StackedDRG2KiBSeal, 0, 2, sbroot, []byte("8"), nil) + genm, ki, err := seed.PreSeal(genMiner, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, 2, sbroot, []byte("8"), nil) if err != nil { return nodeInfo{}, xerrors.Errorf("preseal failed: %w", err) } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 1d68a1858..e39527201 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -750,7 +750,7 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr initialPledge := big.Zero() { - ssize, err := precommit.Info.RegisteredProof.SectorSize() + ssize, err := precommit.Info.SealProof.SectorSize() if err != nil { return types.EmptyInt, err } diff --git a/node/node_test.go b/node/node_test.go index 8b17fac2e..a3a37bdd3 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -54,8 +54,8 @@ func init() { _ = logging.SetLogLevel("*", "INFO") power.ConsensusMinerMinPower = big.NewInt(2048) - saminer.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } verifreg.MinVerifiedDealSize = big.NewInt(256) } @@ -189,7 +189,7 @@ func builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestN if err != nil { t.Fatal(err) } - genm, k, err := seed.PreSeal(maddr, abi.RegisteredProof_StackedDRG2KiBPoSt, 0, test.GenesisPreseals, tdir, []byte("make genesis mem random"), nil) + genm, k, err := seed.PreSeal(maddr, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, test.GenesisPreseals, tdir, []byte("make genesis mem random"), nil) if err != nil { t.Fatal(err) } diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 7821b009c..5fc811997 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -98,7 +98,7 @@ func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (seal }, nil } -func (s SealingAPIAdapter) StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredProof, deals []abi.DealID, tok sealing.TipSetToken) (cid.Cid, error) { +func (s SealingAPIAdapter) StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredSealProof, deals []abi.DealID, tok sealing.TipSetToken) (cid.Cid, error) { tsk, err := types.TipSetKeyFromBytes(tok) if err != nil { return cid.Undef, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err) diff --git a/storage/miner.go b/storage/miner.go index 171c166aa..514af527a 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -135,7 +135,7 @@ type StorageWpp struct { prover storage.Prover verifier ffiwrapper.Verifier miner abi.ActorID - winnRpt abi.RegisteredProof + winnRpt abi.RegisteredPoStProof } func NewWinningPoStProver(api api.FullNode, prover storage.Prover, verifier ffiwrapper.Verifier, miner dtypes.MinerID) (*StorageWpp, error) { diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 8cd9fdc5f..01d840848 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -464,9 +464,9 @@ func (s *WindowPoStScheduler) sortedSectorInfo(ctx context.Context, deadlineSect sbsi := make([]abi.SectorInfo, len(sset)) for k, sector := range sset { sbsi[k] = abi.SectorInfo{ - SectorNumber: sector.ID, - SealedCID: sector.Info.Info.SealedCID, - RegisteredProof: sector.Info.Info.RegisteredProof, + SectorNumber: sector.ID, + SealedCID: sector.Info.Info.SealedCID, + SealProof: sector.Info.Info.SealProof, } } diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index 8b405747e..077209a4e 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -24,7 +24,7 @@ type WindowPoStScheduler struct { api storageMinerApi prover storage.Prover faultTracker sectorstorage.FaultTracker - proofType abi.RegisteredProof + proofType abi.RegisteredPoStProof partitionSectors uint64 actor address.Address From c832c0bf3fdfe56b87932fc3ddcc9988c4112765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 15 Jun 2020 18:31:18 +0200 Subject: [PATCH 153/379] mod tidy --- go.mod | 2 -- go.sum | 26 ++------------------------ 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index df0c03c9f..3b35c53d3 100644 --- a/go.mod +++ b/go.mod @@ -127,5 +127,3 @@ require ( replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi - -replace github.com/filecoin-project/go-fil-markets => /home/magik6k/gohack/github.com/filecoin-project/go-fil-markets diff --git a/go.sum b/go.sum index c4a07cf66..4ae1fb3af 100644 --- a/go.sum +++ b/go.sum @@ -182,8 +182,6 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= -github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94 h1:svEal/usZ/REEjEz6ije3/ALn8duM2CckR0LjT1btx0= -github.com/filecoin-project/chain-validation v0.0.6-0.20200605221044-7f78284bbc94/go.mod h1:aOmmdhO0xIRtWCwx3MyIv3tPCCorM1Bq7pNOJGMLndA= github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5 h1:8Ytl1uk8/Sff7Z2vfb7MOEM3ZRlQKJPqn19FzDcr+bc= github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5/go.mod h1:HEJn6kOXMNhCNBYNTO/lrEI7wSgqCOR6hN5ecfYUnC8= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= @@ -193,7 +191,6 @@ github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef/go.m github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 h1:jamfsxfK0Q9yCMHt8MPWx7Aa/O9k2Lve8eSc6FILYGQ= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= -github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e h1:gkG/7G+iKy4He+IiQNeQn+nndFznb/vCoOR8iRQsm60= @@ -206,8 +203,8 @@ github.com/filecoin-project/go-data-transfer v0.3.0 h1:BwBrrXu9Unh9JjjX4GAc5FfzU github.com/filecoin-project/go-data-transfer v0.3.0/go.mod h1:cONglGP4s/d+IUQw5mWZrQK+FQATQxr3AXzi4dRh0l4= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= -github.com/filecoin-project/go-fil-markets v0.2.7 h1:bgdK/e+xW15aVZLtdFLzAHdrx1hqtGF9veg2lstLK6o= -github.com/filecoin-project/go-fil-markets v0.2.7/go.mod h1:LI3VFHse33aU0djAmFQ8+Hg39i0J8ibAoppGu6TbgkA= +github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615162707-5dd6b2eb253b h1:xhaFY+rdZMDErIkUHvkJWdN6H3h/dn/5U3GOX4HP/Cs= +github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615162707-5dd6b2eb253b/go.mod h1:nCjNrwgRsjX1TSiBUVgewa5PbP19x5Mq07uzlJD9YUw= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= @@ -222,33 +219,14 @@ github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIi github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= -github.com/filecoin-project/sector-storage v0.0.0-20200508203401-a74812ba12f3/go.mod h1:B+xzopr/oWZJz2hBL5Ekb7Obcum5ntmfbaAUlaaho28= -github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d h1:q7KC8/yIirwVX7JCLgjEmo5LX77V8tYV0EzVCnCwrE8= -github.com/filecoin-project/sector-storage v0.0.0-20200609231555-252c2b0c969d/go.mod h1:SfaVNw/A6LwqqEt6wEMVBN5Grn3XC50j+yjmegHIe7Y= -github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0 h1:DpdlpS3G2XN+F68rxOTAXsGL3cV7UkFr0TxdmKSiaJg= -github.com/filecoin-project/sector-storage v0.0.0-20200615123301-7d09fa88b4b0/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= -github.com/filecoin-project/sector-storage v0.0.0-20200615142857-3d1225bf3449 h1:aFXA4iI8WumN1pgEv5gtAyZs3mEX7AdV2xqHf76Dn6o= -github.com/filecoin-project/sector-storage v0.0.0-20200615142857-3d1225bf3449/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6 h1:NIcubpeasVs++K5EFelMXeURRb8sWCuXQNOSWnvTc14= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= -github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= -github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461/go.mod h1:r5btrNzZD0oBkEz1pohv80gSCXQnqGrD0kYwOTiExyE= -github.com/filecoin-project/specs-actors v0.5.5 h1:bDsowem6dLRc9B7g3sgFYvHgfWTH4D9q5ehWLGLdKCw= -github.com/filecoin-project/specs-actors v0.5.5/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= -github.com/filecoin-project/specs-actors v0.5.6 h1:WlhtoXwFoKlP1b06NI4NJaxC4m9EXNV+qFVl43/xRN8= -github.com/filecoin-project/specs-actors v0.5.6/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9kNbbHOcU/9oiC0= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= -github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE= -github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= -github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa h1:kTCIBKMhhhVcjCh1ws72vpdDr4cdZjCyIUDFijuWuvA= -github.com/filecoin-project/storage-fsm v0.0.0-20200605082304-aa405b2176aa/go.mod h1:S0u14Wr55mpe22lElCSKbXrhtWg/jquVTTMhefQ8f4Q= -github.com/filecoin-project/storage-fsm v0.0.0-20200615142724-95dbdc803c53 h1:mvvBaFPyYugJfmHgFHg0BgE0plwV2IhfgL6tLu02umM= -github.com/filecoin-project/storage-fsm v0.0.0-20200615142724-95dbdc803c53/go.mod h1:ZBID+J03DzANc0cv+sv03ROqfYYZbl62d3u8JftBH6k= github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg= github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= From 58a79773ee8467fe3ac323543146554e5c69682a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 15 Jun 2020 18:34:36 +0200 Subject: [PATCH 154/379] fix debug build --- build/params_2k.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/params_2k.go b/build/params_2k.go index 56e1ca2f8..046753678 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -12,8 +12,8 @@ import ( func init() { power.ConsensusMinerMinPower = big.NewInt(2048) - miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{ - abi.RegisteredProof_StackedDRG2KiBSeal: {}, + miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ + abi.RegisteredSealProof_StackedDrg2KiBV1: {}, } verifreg.MinVerifiedDealSize = big.NewInt(256) From 8039701f9ef8bbab42ceb9f4894c666cd320f123 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 15 Jun 2020 19:50:43 +0200 Subject: [PATCH 155/379] Use extra field in gastrace Signed-off-by: Jakub Sztandera --- chain/types/execresult.go | 2 +- chain/vm/gas.go | 10 +++++++++- chain/vm/gas_v0.go | 6 +++--- chain/vm/runtime.go | 14 +++++++++----- cli/state.go | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/chain/types/execresult.go b/chain/types/execresult.go index b0e1f760d..443147f9e 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -30,7 +30,7 @@ type GasTrace struct { VirtualStorageGas int64 TimeTaken time.Duration - Extra interface{} + Extra interface{} `json:",omitempty"` Callers []uintptr `json:"-"` } diff --git a/chain/vm/gas.go b/chain/vm/gas.go index dc9966e57..2540afbf0 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -18,7 +18,9 @@ const ( ) type GasCharge struct { - Name string + Name string + Extra interface{} + ComputeGas int64 StorageGas int64 @@ -36,6 +38,12 @@ func (g GasCharge) WithVirtual(compute, storage int64) GasCharge { return out } +func (g GasCharge) WithExtra(extra interface{}) GasCharge { + out := g + out.Extra = extra + return out +} + func newGasCharge(name string, computeGas int64, storageGas int64) GasCharge { return GasCharge{ Name: name, diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index c631beaee..e2a908a23 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -108,12 +108,12 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M // OnIpldGet returns the gas used for storing an object func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge { - return newGasCharge(fmt.Sprintf("OnIpldGet:%db", dataSize), pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0) + return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize) } // OnIpldPut returns the gas used for storing an object func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge { - return newGasCharge(fmt.Sprintf("OnIpldPut:%db", dataSize), pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte) + return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize) } // OnCreateActor returns the gas used for creating an actor @@ -133,7 +133,7 @@ func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize in return GasCharge{}, fmt.Errorf("cost function for signature type %d not supported", sigType) } sigName, _ := sigType.Name() - return newGasCharge("OnVerifySignature/"+sigName, costFn(int64(planTextSize)), 0), nil + return newGasCharge("OnVerifySignature", costFn(int64(planTextSize)), 0).WithExtra(sigName), nil } // OnHashing diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 9b83593ab..48563df64 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -524,14 +524,18 @@ func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError } gasTrace := types.GasTrace{ - Name: gas.Name, - TotalGas: toUse, - ComputeGas: gas.ComputeGas, - StorageGas: gas.StorageGas, + Name: gas.Name, + Extra: gas.Extra, + + TotalGas: toUse, + ComputeGas: gas.ComputeGas, + StorageGas: gas.StorageGas, + TotalVirtualGas: gas.VirtualCompute*GasComputeMulti + gas.VirtualStorage*GasStorageMulti, VirtualComputeGas: gas.VirtualCompute, VirtualStorageGas: gas.VirtualStorage, - Callers: callers[:cout], + + Callers: callers[:cout], } rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace) rt.lastGasChargeTime = now diff --git a/cli/state.go b/cli/state.go index 753b0b017..1aad85299 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1072,7 +1072,7 @@ var compStateMsg = ` {{- end}} {{range .GasCharges}} - {{.Name}} + {{.Name}}{{if .Extra}}:{{.Extra}}{{end}} {{template "gasC" .}} {{.TimeTaken}} From daca8651f41efacacd804b77db6c8b7959751f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 15 Jun 2020 19:53:21 +0200 Subject: [PATCH 156/379] Fix bench --- cmd/lotus-bench/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 57f5241df..a10c3c00e 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -284,12 +284,12 @@ var sealBenchCmd = &cli.Command{ if !c.Bool("skip-commit2") { log.Info("generating winning post candidates") - wpt, err := spt.RegisteredWindowPoStProof() + wipt, err := spt.RegisteredWinningPoStProof() if err != nil { return err } - fcandidates, err := ffiwrapper.ProofVerifier.GenerateWinningPoStSectorChallenge(context.TODO(), wpt, mid, challenge[:], uint64(len(sealedSectors))) + fcandidates, err := ffiwrapper.ProofVerifier.GenerateWinningPoStSectorChallenge(context.TODO(), wipt, mid, challenge[:], uint64(len(sealedSectors))) if err != nil { return err } From f8669d4e9547d0f322cc735baf22529e58360e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 15 Jun 2020 21:21:40 +0200 Subject: [PATCH 157/379] Update chain-val and sector-storage --- go.mod | 4 ++-- go.sum | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 3b35c53d3..89e2e2842 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 github.com/drand/kyber v1.0.2 github.com/fatih/color v1.8.0 - github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5 + github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09 github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6 + github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 github.com/filecoin-project/specs-actors v0.6.0 github.com/filecoin-project/specs-storage v0.1.0 github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 diff --git a/go.sum b/go.sum index 4ae1fb3af..83af4904c 100644 --- a/go.sum +++ b/go.sum @@ -182,8 +182,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= -github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5 h1:8Ytl1uk8/Sff7Z2vfb7MOEM3ZRlQKJPqn19FzDcr+bc= -github.com/filecoin-project/chain-validation v0.0.6-0.20200615142407-39c0fe23a3d5/go.mod h1:HEJn6kOXMNhCNBYNTO/lrEI7wSgqCOR6hN5ecfYUnC8= +github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09 h1:GuiNSEZ9nc05LUpKhABw/SO6t9wqCfsJX1D0ByWQjkc= +github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09/go.mod h1:HEJn6kOXMNhCNBYNTO/lrEI7wSgqCOR6hN5ecfYUnC8= github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= @@ -219,8 +219,9 @@ github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIi github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= -github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6 h1:NIcubpeasVs++K5EFelMXeURRb8sWCuXQNOSWnvTc14= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= +github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 h1:cjsOpQKvZosPx9/qqq2bucHVdRyXzvBR1f37atiR3/0= +github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9kNbbHOcU/9oiC0= From 01c4726fd5fca11aed50f25a8d6287e72487885d Mon Sep 17 00:00:00 2001 From: Jeromy Date: Mon, 15 Jun 2020 13:02:57 -0700 Subject: [PATCH 158/379] add some smartness to bench analyze gas output --- cmd/lotus-bench/import.go | 66 +++++++++++++++++++++++++++++++++ cmd/lotus-storage-miner/init.go | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 11d58d9b8..8d62ac0d8 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "math" "os" "runtime/pprof" "sort" @@ -162,6 +163,43 @@ type Invocation struct { Invoc *api.InvocResult } +const GasPerNs = 10 + +func countGasCosts(et *types.ExecutionTrace) (int64, int64) { + var cgas, vgas int64 + + for _, gc := range et.GasCharges { + cgas += gc.ComputeGas + vgas += gc.VirtualComputeGas + } + + for _, sub := range et.Subcalls { + c, v := countGasCosts(&sub) + cgas += c + vgas += v + } + + return cgas, vgas +} + +func compStats(vals []float64) (float64, float64) { + var sum float64 + + for _, v := range vals { + sum += v + } + + av := sum / float64(len(vals)) + + var varsum float64 + for _, v := range vals { + delta := av - v + varsum += delta * delta + } + + return av, math.Sqrt(varsum / float64(len(vals))) +} + var importAnalyzeCmd = &cli.Command{ Name: "analyze", Action: func(cctx *cli.Context) error { @@ -180,6 +218,8 @@ var importAnalyzeCmd = &cli.Command{ return err } + chargeDeltas := make(map[string][]float64) + var invocs []Invocation var totalTime time.Duration for i, r := range results { @@ -191,9 +231,35 @@ var importAnalyzeCmd = &cli.Command{ TipSet: r.TipSet, Invoc: inv, }) + + cgas, vgas := countGasCosts(&inv.ExecutionTrace) + fmt.Printf("Invocation: %d %s: %s %d -> %0.2f\n", inv.Msg.Method, inv.Msg.To, inv.Duration, cgas+vgas, float64(GasPerNs*inv.Duration.Nanoseconds())/float64(cgas+vgas)) + + for _, gc := range inv.ExecutionTrace.GasCharges { + + compGas := gc.ComputeGas + gc.VirtualComputeGas + ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) + + chargeDeltas[gc.Name] = append(chargeDeltas[gc.Name], 1/(ratio/GasPerNs)) + //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) + } } } + var keys []string + for k := range chargeDeltas { + keys = append(keys, k) + } + + fmt.Println("Gas Price Deltas") + sort.Strings(keys) + for _, k := range keys { + vals := chargeDeltas[k] + av, stdev := compStats(vals) + + fmt.Printf("%s: incr by %f (%f)\n", k, av, stdev) + } + sort.Slice(invocs, func(i, j int) bool { return invocs[i].Invoc.Duration > invocs[j].Invoc.Duration }) diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 29e82cc2f..14972c69a 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -460,7 +460,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, } if cerr != nil { - return xerrors.Errorf("failed to configure storage miner: %w", err) + return xerrors.Errorf("failed to configure storage miner: %w", cerr) } } From 9262661135706070325d8b9bfea9c5e72841c719 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Mon, 15 Jun 2020 15:43:47 -0700 Subject: [PATCH 159/379] chore(deps): update to fil-markets 0.3.0 Updates to latest fil markets with resumability and other fixes --- go.mod | 2 +- go.sum | 6 ++++-- node/builder.go | 2 -- node/impl/storminer.go | 2 +- node/modules/client.go | 3 +-- node/modules/services.go | 18 ------------------ node/modules/storageminer.go | 4 ++-- 7 files changed, 9 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 89e2e2842..ca503ce49 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 - github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615162707-5dd6b2eb253b + github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615223906-0fb36d5347bd github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca diff --git a/go.sum b/go.sum index 83af4904c..c6c69454b 100644 --- a/go.sum +++ b/go.sum @@ -203,8 +203,8 @@ github.com/filecoin-project/go-data-transfer v0.3.0 h1:BwBrrXu9Unh9JjjX4GAc5FfzU github.com/filecoin-project/go-data-transfer v0.3.0/go.mod h1:cONglGP4s/d+IUQw5mWZrQK+FQATQxr3AXzi4dRh0l4= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= -github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615162707-5dd6b2eb253b h1:xhaFY+rdZMDErIkUHvkJWdN6H3h/dn/5U3GOX4HP/Cs= -github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615162707-5dd6b2eb253b/go.mod h1:nCjNrwgRsjX1TSiBUVgewa5PbP19x5Mq07uzlJD9YUw= +github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615223906-0fb36d5347bd h1:yQqt+9CDKdZhg1VZEgV8O5tA+D1f0mairODT7dcwHtU= +github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615223906-0fb36d5347bd/go.mod h1:UXsXi43AyUQ5ieb4yIaLgk4PVt7TAbl1UCccuNw+7ds= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= @@ -215,6 +215,8 @@ github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca h github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9 h1:k9qVR9ItcziSB2rxtlkN/MDWNlbsI6yzec+zjUatLW0= github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= +github.com/filecoin-project/go-statemachine v0.0.0-20200612181802-4eb3d0c68eba h1:GEWb/6KQyNZt4jm8fgVcIFPH0ElAGXfHM59ZSiqPTvY= +github.com/filecoin-project/go-statemachine v0.0.0-20200612181802-4eb3d0c68eba/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= diff --git a/node/builder.go b/node/builder.go index 25b027145..536d81901 100644 --- a/node/builder.go +++ b/node/builder.go @@ -106,7 +106,6 @@ const ( HandleIncomingBlocksKey HandleIncomingMessagesKey - RunDealClientKey RegisterClientValidatorKey // storage miner @@ -266,7 +265,6 @@ func Online() Option { Override(new(storagemarket.StorageClient), modules.StorageClient), Override(new(storagemarket.StorageClientNode), storageadapter.NewClientNodeAdapter), Override(RegisterClientValidatorKey, modules.RegisterClientValidator), - Override(RunDealClientKey, modules.RunDealClient), Override(new(beacon.RandomBeacon), modules.RandomBeacon), Override(new(*paychmgr.Store), paychmgr.NewStore), diff --git a/node/impl/storminer.go b/node/impl/storminer.go index de80eb4cd..a01cad9c2 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -202,7 +202,7 @@ func (sm *StorageMinerAPI) MarketListIncompleteDeals(ctx context.Context) ([]sto } func (sm *StorageMinerAPI) MarketSetPrice(ctx context.Context, p types.BigInt) error { - return sm.StorageProvider.AddAsk(abi.TokenAmount(p), 60*60*24*100) // lasts for 100 days? + return sm.StorageProvider.SetAsk(abi.TokenAmount(p), 60*60*24*100) // lasts for 100 days? } func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) { diff --git a/node/modules/client.go b/node/modules/client.go index 12ec209b5..b4618015a 100644 --- a/node/modules/client.go +++ b/node/modules/client.go @@ -117,8 +117,7 @@ func StorageClient(lc fx.Lifecycle, h host.Host, ibs dtypes.ClientBlockstore, r } lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { - c.Run(ctx) - return nil + return c.Start(ctx) }, OnStop: func(context.Context) error { c.Stop() diff --git a/node/modules/services.go b/node/modules/services.go index f4a007c2b..27244ad3a 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -1,8 +1,6 @@ package modules import ( - "context" - "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" eventbus "github.com/libp2p/go-eventbus" @@ -15,7 +13,6 @@ import ( "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket/discovery" - "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/beacon" @@ -100,21 +97,6 @@ func HandleIncomingMessages(mctx helpers.MetricsCtx, lc fx.Lifecycle, ps *pubsub go sub.HandleIncomingMessages(ctx, mpool, msgsub) } -func RunDealClient(mctx helpers.MetricsCtx, lc fx.Lifecycle, c storagemarket.StorageClient) { - ctx := helpers.LifecycleCtx(mctx, lc) - - lc.Append(fx.Hook{ - OnStart: func(context.Context) error { - c.Run(ctx) - return nil - }, - OnStop: func(context.Context) error { - c.Stop() - return nil - }, - }) -} - func NewLocalDiscovery(ds dtypes.MetadataDS) *discovery.Local { return discovery.NewLocal(namespace.Wrap(ds, datastore.NewKey("/deals/local"))) } diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 440aa8593..fce9f9e1f 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -299,8 +299,8 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return nil, err } // Hacky way to set max piece size to the sector size - a := storedAsk.GetAsk(address.Address(minerAddress)).Ask - err = storedAsk.AddAsk(a.Price, a.Expiry-a.Timestamp, storagemarket.MaxPieceSize(abi.PaddedPieceSize(mi.SectorSize))) + a := storedAsk.GetAsk().Ask + err = storedAsk.SetAsk(a.Price, a.Expiry-a.Timestamp, storagemarket.MaxPieceSize(abi.PaddedPieceSize(mi.SectorSize))) if err != nil { return storedAsk, err } From a4226478198041b969b2f273bfa2d85266dfef3d Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Mon, 15 Jun 2020 15:53:39 -0700 Subject: [PATCH 160/379] fix(lint): fix lint error fix lint error and update to tagged package --- go.mod | 2 +- go.sum | 4 ++-- node/impl/storminer.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index ca503ce49..8457847a6 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 - github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615223906-0fb36d5347bd + github.com/filecoin-project/go-fil-markets v0.3.0 github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca diff --git a/go.sum b/go.sum index c6c69454b..47a405efa 100644 --- a/go.sum +++ b/go.sum @@ -203,8 +203,8 @@ github.com/filecoin-project/go-data-transfer v0.3.0 h1:BwBrrXu9Unh9JjjX4GAc5FfzU github.com/filecoin-project/go-data-transfer v0.3.0/go.mod h1:cONglGP4s/d+IUQw5mWZrQK+FQATQxr3AXzi4dRh0l4= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= -github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615223906-0fb36d5347bd h1:yQqt+9CDKdZhg1VZEgV8O5tA+D1f0mairODT7dcwHtU= -github.com/filecoin-project/go-fil-markets v0.2.8-0.20200615223906-0fb36d5347bd/go.mod h1:UXsXi43AyUQ5ieb4yIaLgk4PVt7TAbl1UCccuNw+7ds= +github.com/filecoin-project/go-fil-markets v0.3.0 h1:7iCGiuTSia4f4DmOn3s96NWUwMNSOI0ZHel/XgeApAQ= +github.com/filecoin-project/go-fil-markets v0.3.0/go.mod h1:UXsXi43AyUQ5ieb4yIaLgk4PVt7TAbl1UCccuNw+7ds= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= diff --git a/node/impl/storminer.go b/node/impl/storminer.go index a01cad9c2..0cc13177e 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -202,7 +202,7 @@ func (sm *StorageMinerAPI) MarketListIncompleteDeals(ctx context.Context) ([]sto } func (sm *StorageMinerAPI) MarketSetPrice(ctx context.Context, p types.BigInt) error { - return sm.StorageProvider.SetAsk(abi.TokenAmount(p), 60*60*24*100) // lasts for 100 days? + return sm.StorageProvider.SetAsk(p, 60*60*24*100) // lasts for 100 days? } func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) { From f8c4b647828139199717ec86834c9f5603e64266 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Mon, 15 Jun 2020 16:05:29 -0700 Subject: [PATCH 161/379] improve chain import analyze output, add some rough virtual gas charges --- chain/vm/gas.go | 11 ++++++++++- chain/vm/gas_v0.go | 10 +++++----- chain/vm/syscalls.go | 4 +++- cmd/lotus-bench/import.go | 30 +++++++++++++++++++++++------- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/chain/vm/gas.go b/chain/vm/gas.go index f1dcc933d..e6bde25bf 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -186,6 +186,15 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte } func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { - ps.chargeGas(newGasCharge("BatchVerifySeals", 0, 0)) // TODO: this is only called by the cron actor. Should we even charge gas? + var gasChargeSum GasCharge + gasChargeSum.Name = "BatchVerifySeals" + ps.chargeGas(gasChargeSum) // TODO: this is only called by the cron actor. Should we even charge gas? + + for _, svis := range inp { + for _, svi := range svis { + ch := ps.pl.OnVerifySeal(svi) + ps.chargeGas(newGasCharge("BatchVerifySingle", 0, 0).WithVirtual(ch.VirtualCompute+ch.ComputeGas, 0)) + } + } return ps.under.BatchVerifySeals(inp) } diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index 6994fd544..072c1f140 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -103,17 +103,17 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M if methodNum != builtin.MethodSend { ret += pl.sendInvokeMethod } - return newGasCharge("OnMethodInvocation", ret, 0) + return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(ret*15000, 0) } // OnIpldGet returns the gas used for storing an object func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge { - return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize) + return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize).WithVirtual(pl.ipldGetBase*13750+(pl.ipldGetPerByte*100), 0) } // OnIpldPut returns the gas used for storing an object func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge { - return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize) + return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(pl.ipldPutBase*8700+(pl.ipldPutPerByte*100), 0) } // OnCreateActor returns the gas used for creating an actor @@ -144,13 +144,13 @@ func (pl *pricelistV0) OnHashing(dataSize int) GasCharge { // OnComputeUnsealedSectorCid func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0) + return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(pl.computeUnsealedSectorCidBase*24500, 0) } // OnVerifySeal func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnVerifySeal", pl.verifySealBase, 0) + return newGasCharge("OnVerifySeal", pl.verifySealBase, 0).WithVirtual(pl.verifySealBase*177500, 0) } // OnVerifyPost diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index a5910121d..a6a589761 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -241,10 +241,12 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres return sigs.Verify(&sig, kaddr, input) } +var BatchSealVerifyParallelism = goruntime.NumCPU() + func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { out := make(map[address.Address][]bool) - sema := make(chan struct{}, goruntime.NumCPU()) + sema := make(chan struct{}, BatchSealVerifyParallelism) var wg sync.WaitGroup for addr, seals := range inp { diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 8d62ac0d8..f9c20ac9a 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "math" "os" + "runtime" "runtime/pprof" "sort" "time" @@ -45,8 +46,14 @@ var importBenchCmd = &cli.Command{ Name: "height", Usage: "halt validation after given height", }, + &cli.IntFlag{ + Name: "batch-seal-verify-threads", + Usage: "set the parallelism factor for batch seal verification", + Value: runtime.NumCPU(), + }, }, Action: func(cctx *cli.Context) error { + vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads") if !cctx.Args().Present() { fmt.Println("must pass car file of chain to benchmark importing") return nil @@ -200,6 +207,21 @@ func compStats(vals []float64) (float64, float64) { return av, math.Sqrt(varsum / float64(len(vals))) } +func tallyGasCharges(charges map[string][]float64, et *types.ExecutionTrace) { + for _, gc := range et.GasCharges { + + compGas := gc.ComputeGas + gc.VirtualComputeGas + ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) + + charges[gc.Name] = append(charges[gc.Name], 1/(ratio/GasPerNs)) + //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) + for _, sub := range et.Subcalls { + tallyGasCharges(charges, &sub) + } + } + +} + var importAnalyzeCmd = &cli.Command{ Name: "analyze", Action: func(cctx *cli.Context) error { @@ -235,14 +257,8 @@ var importAnalyzeCmd = &cli.Command{ cgas, vgas := countGasCosts(&inv.ExecutionTrace) fmt.Printf("Invocation: %d %s: %s %d -> %0.2f\n", inv.Msg.Method, inv.Msg.To, inv.Duration, cgas+vgas, float64(GasPerNs*inv.Duration.Nanoseconds())/float64(cgas+vgas)) - for _, gc := range inv.ExecutionTrace.GasCharges { + tallyGasCharges(chargeDeltas, &inv.ExecutionTrace) - compGas := gc.ComputeGas + gc.VirtualComputeGas - ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) - - chargeDeltas[gc.Name] = append(chargeDeltas[gc.Name], 1/(ratio/GasPerNs)) - //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) - } } } From 69948cd09c7e2345c4dab220ff7cf4af586781d9 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Mon, 15 Jun 2020 21:00:22 -0400 Subject: [PATCH 162/379] WalletSign should resolve ID addresses --- node/impl/full/wallet.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 7d7cbae67..8da8d3062 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -40,7 +40,11 @@ func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (ty } func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) { - return a.Wallet.Sign(ctx, k, msg) + keyAddr, err := a.StateManager.ResolveToKeyAddress(ctx, k, nil) + if err != nil { + return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) + } + return a.Wallet.Sign(ctx, keyAddr, msg) } func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { From ed3b2716af6b4dfbd906e5b980c20ae15361db5f Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Mon, 15 Jun 2020 21:02:25 -0400 Subject: [PATCH 163/379] Don't verify ElectionPostVRF when insecure validation enabled --- chain/sync.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/chain/sync.go b/chain/sync.go index 07d470d28..05c0bc7cf 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -650,7 +650,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err return xerrors.Errorf("could not draw randomness: %w", err) } - if err := gen.VerifyVRF(ctx, waddr, vrfBase, h.ElectionProof.VRFProof); err != nil { + if err := VerifyElectionPoStVRF(ctx, waddr, vrfBase, h.ElectionProof.VRFProof); err != nil { return xerrors.Errorf("validating block election proof failed: %w", err) } @@ -711,7 +711,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err return xerrors.Errorf("failed to compute vrf base for ticket: %w", err) } - err = gen.VerifyVRF(ctx, waddr, vrfBase, h.Ticket.VRFProof) + err = VerifyElectionPoStVRF(ctx, waddr, vrfBase, h.Ticket.VRFProof) if err != nil { return xerrors.Errorf("validating block tickets failed: %w", err) } @@ -1336,12 +1336,12 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error return nil } -func VerifyElectionPoStVRF(ctx context.Context, evrf []byte, rand []byte, worker address.Address) error { - if err := gen.VerifyVRF(ctx, worker, rand, evrf); err != nil { - return xerrors.Errorf("failed to verify post_randomness vrf: %w", err) +func VerifyElectionPoStVRF(ctx context.Context, worker address.Address, rand []byte, evrf []byte) error { + if build.InsecurePoStValidation { + return nil + } else { + return gen.VerifyVRF(ctx, worker, rand, evrf) } - - return nil } func (syncer *Syncer) State() []SyncerState { From a9abf3ceb2ac791f3ff2908046d9ac743a3d84ab Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Mon, 15 Jun 2020 21:02:53 -0400 Subject: [PATCH 164/379] extract the fake Wpost used for testing --- chain/gen/gen.go | 8 +++++--- cmd/lotus/debug_advance.go | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index c9ebebcef..172c73845 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -45,6 +45,10 @@ var log = logging.Logger("gen") const msgsPerBlock = 20 +var ValidWpostForTesting = []abi.PoStProof{{ + ProofBytes: []byte("valid proof"), +}} + type ChainGen struct { msgsPerBlock int @@ -529,9 +533,7 @@ func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandom } func (wpp *wppProvider) ComputeProof(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]abi.PoStProof, error) { - return []abi.PoStProof{{ - ProofBytes: []byte("valid proof"), - }}, nil + return ValidWpostForTesting, nil } type ProofInput struct { diff --git a/cmd/lotus/debug_advance.go b/cmd/lotus/debug_advance.go index 990bbe95d..b18878d9d 100644 --- a/cmd/lotus/debug_advance.go +++ b/cmd/lotus/debug_advance.go @@ -72,7 +72,7 @@ func init() { uts := head.MinTimestamp() + uint64(build.BlockDelay) nheight := head.Height() + 1 blk, err := api.MinerCreateBlock(ctx, &lapi.BlockTemplate{ - addr, head.Key(), ticket, nil, nil, msgs, nheight, uts, nil, + addr, head.Key(), ticket, &types.ElectionProof{}, nil, msgs, nheight, uts, gen.ValidWpostForTesting, }) if err != nil { return xerrors.Errorf("creating block: %w", err) From f31fcdae08b1ed26b74d8c52de35ee896933c3d6 Mon Sep 17 00:00:00 2001 From: Travis Person Date: Mon, 15 Jun 2020 20:34:48 +0000 Subject: [PATCH 165/379] stats: increase miner power lookup perf --- tools/stats/metrics.go | 84 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 7 deletions(-) diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index eb653e1d7..53fa6ed63 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "context" "encoding/json" "fmt" @@ -13,9 +14,14 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/ipfs/go-cid" "github.com/multiformats/go-multihash" + cbg "github.com/whyrusleeping/cbor-gen" + _ "github.com/influxdata/influxdb1-client" models "github.com/influxdata/influxdb1-client/models" client "github.com/influxdata/influxdb1-client/v2" @@ -135,6 +141,36 @@ func RecordTipsetPoints(ctx context.Context, api api.FullNode, pl *PointList, ti return nil } +type apiIpldStore struct { + ctx context.Context + api api.FullNode +} + +func (ht *apiIpldStore) Context() context.Context { + return ht.ctx +} + +func (ht *apiIpldStore) Get(ctx context.Context, c cid.Cid, out interface{}) error { + raw, err := ht.api.ChainReadObj(ctx, c) + if err != nil { + return err + } + + cu, ok := out.(cbg.CBORUnmarshaler) + if ok { + if err := cu.UnmarshalCBOR(bytes.NewReader(raw)); err != nil { + return err + } + return nil + } + + return fmt.Errorf("Object does not implement CBORUnmarshaler") +} + +func (ht *apiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error) { + return cid.Undef, fmt.Errorf("Put is not implemented on apiIpldStore") +} + func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error { pc, err := api.StatePledgeCollateral(ctx, tipset.Key()) if err != nil { @@ -158,24 +194,58 @@ func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointLis p = NewPoint("network.balance", netBalFilFloat) pl.AddPoint(p) - power, err := api.StateMinerPower(ctx, address.Address{}, tipset.Key()) + totalPower, err := api.StateMinerPower(ctx, address.Address{}, tipset.Key()) if err != nil { return err } - p = NewPoint("chain.power", power.TotalPower.QualityAdjPower.Int64()) + p = NewPoint("chain.power", totalPower.TotalPower.QualityAdjPower.Int64()) pl.AddPoint(p) - miners, err := api.StateListMiners(ctx, tipset.Key()) - for _, miner := range miners { - power, err := api.StateMinerPower(ctx, miner, tipset.Key()) + powerActor, err := api.StateGetActor(ctx, builtin.StoragePowerActorAddr, tipset.Key()) + if err != nil { + return err + } + + powerRaw, err := api.ChainReadObj(ctx, powerActor.Head) + if err != nil { + return err + } + + var powerActorState power.State + + if err := powerActorState.UnmarshalCBOR(bytes.NewReader(powerRaw)); err != nil { + return fmt.Errorf("failed to unmarshal power actor state: %w", err) + } + + s := &apiIpldStore{ctx, api} + mp, err := adt.AsMap(s, powerActorState.Claims) + if err != nil { + return err + } + + err = mp.ForEach(nil, func(key string) error { + addr, err := address.NewFromBytes([]byte(key)) if err != nil { return err } - p = NewPoint("chain.miner_power", power.MinerPower.QualityAdjPower.Int64()) - p.AddTag("miner", miner.String()) + var claim power.Claim + keyerAddr := adt.AddrKey(addr) + mp.Get(keyerAddr, &claim) + + if claim.QualityAdjPower.Int64() == 0 { + return nil + } + + p = NewPoint("chain.miner_power", claim.QualityAdjPower.Int64()) + p.AddTag("miner", addr.String()) pl.AddPoint(p) + + return nil + }) + if err != nil { + return err } return nil From d8a517f9925a4a160338f8b005a7f6f365173c61 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 12 Jun 2020 00:47:57 -0400 Subject: [PATCH 166/379] Syncer::InformNewHead can quickly fail if height is impossibly large --- chain/sync.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/chain/sync.go b/chain/sync.go index 07d470d28..c5dde625c 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -50,6 +50,10 @@ import ( "github.com/filecoin-project/lotus/metrics" ) +// Blocks that are more than MaxHeightDrift epochs above +//the theoretical max height based on systime are quickly rejected +const MaxHeightDrift = 5 + var log = logging.Logger("chain") var LocalIncoming = "incoming" @@ -134,6 +138,11 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool { return false } + if syncer.IsEpochBeyondCurrMax(fts.TipSet().Height()) { + log.Errorf("Received block with impossibly large height %d", fts.TipSet().Height()) + return false + } + for _, b := range fts.Blocks { if reason, ok := syncer.bad.Has(b.Cid()); ok { log.Warnf("InformNewHead called on block marked as bad: %s (reason: %s)", b.Cid(), reason) @@ -1380,3 +1389,13 @@ func (syncer *Syncer) getLatestBeaconEntry(ctx context.Context, ts *types.TipSet return nil, xerrors.Errorf("found NO beacon entries in the 20 blocks prior to given tipset") } + +func (syncer *Syncer) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool { + g, err := syncer.store.GetGenesis() + if err != nil { + return false + } + + now := uint64(time.Now().Unix()) + return epoch > (abi.ChainEpoch((now-g.Timestamp)/build.BlockDelay) + MaxHeightDrift) +} From 18dd1c277be738316616671efd3e0ff8a5d33dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 16 Jun 2020 12:28:28 +0200 Subject: [PATCH 167/379] Update ffi --- extern/filecoin-ffi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 5bb4a309b..ca281af0b 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 5bb4a309bce9d446ac618f34a8b9e2883af2002f +Subproject commit ca281af0b6c00314382a75ae869e5cb22c83655b From bac6a47c6753382b5f746c9984d8e5a8c733d2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 16 Jun 2020 12:30:54 +0200 Subject: [PATCH 168/379] specs-actors v0.6.1 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8457847a6..14c3a39f3 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 - github.com/filecoin-project/specs-actors v0.6.0 + github.com/filecoin-project/specs-actors v0.6.1 github.com/filecoin-project/specs-storage v0.1.0 github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 47a405efa..6c45b1daa 100644 --- a/go.sum +++ b/go.sum @@ -228,6 +228,8 @@ github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.m github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9kNbbHOcU/9oiC0= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.6.1 h1:rhHlEzqcuuQU6oKc4csuq+/kQBDZ4EXtSomoN2XApCA= +github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg= From fd6c8769dd266baf24f256577fbad016b769b805 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 10 Jun 2020 20:17:03 +0200 Subject: [PATCH 169/379] Update to new drand WIP Signed-off-by: Jakub Sztandera --- chain/beacon/drand/drand.go | 26 ++-- chain/beacon/drand/drand_test.go | 4 +- go.mod | 8 +- go.sum | 203 +++++++++++++++++++++++++++++-- 4 files changed, 212 insertions(+), 29 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 8742350ba..21bd2501a 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -8,8 +8,9 @@ import ( dchain "github.com/drand/drand/chain" dclient "github.com/drand/drand/client" - gclient "github.com/drand/drand/cmd/relay-gossip/client" + hclient "github.com/drand/drand/client/http" dlog "github.com/drand/drand/log" + gclient "github.com/drand/drand/lp2p/client" "github.com/drand/kyber" kzap "github.com/go-kit/kit/log/zap" "go.uber.org/zap/zapcore" @@ -79,11 +80,22 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon dlogger := dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger( log.SugaredLogger.Desugar(), zapcore.InfoLevel)) + + var clients []dclient.Client + for _, url := range drandServers { + hc, err := hclient.NewWithInfo(url, drandChain, nil) + if err != nil { + return nil, xerrors.Errorf("could not create http drand client: %w", err) + } + clients = append(clients, hc) + + } + opts := []dclient.Option{ dclient.WithChainInfo(drandChain), - dclient.WithHTTPEndpoints(drandServers), dclient.WithCacheSize(1024), dclient.WithLogger(dlogger), + dclient.WithAutoWatch(), } if ps != nil { @@ -92,19 +104,11 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon log.Info("drand beacon without pubsub") } - client, err := dclient.New(opts...) + client, err := dclient.Wrap(clients, opts...) if err != nil { return nil, xerrors.Errorf("creating drand client") } - go func() { - // Explicitly Watch until that is fixed in drand - ch := client.Watch(context.Background()) - for range ch { - } - log.Error("dranch Watch bork") - }() - db := &DrandBeacon{ client: client, localCache: make(map[uint64]types.BeaconEntry), diff --git a/chain/beacon/drand/drand_test.go b/chain/beacon/drand/drand_test.go index 85b80cbe6..f35f3e4cc 100644 --- a/chain/beacon/drand/drand_test.go +++ b/chain/beacon/drand/drand_test.go @@ -5,12 +5,12 @@ import ( "testing" dchain "github.com/drand/drand/chain" - dclient "github.com/drand/drand/client" + hclient "github.com/drand/drand/client/http" "github.com/stretchr/testify/assert" ) func TestPrintGroupInfo(t *testing.T) { - c, err := dclient.NewHTTPClient(drandServers[0], nil, nil) + c, err := hclient.New(drandServers[0], nil, nil) assert.NoError(t, err) cg := c.(interface { FetchChainInfo(groupHash []byte) (*dchain.Info, error) diff --git a/go.mod b/go.mod index 89e2e2842..55d33c390 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,8 @@ require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/coreos/go-systemd/v22 v22.0.0 github.com/docker/go-units v0.4.0 - github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 - github.com/drand/kyber v1.0.2 + github.com/drand/drand v0.9.2-0.20200616080806-a94e9c1636a4 + github.com/drand/kyber v1.1.0 github.com/fatih/color v1.8.0 github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09 github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d @@ -36,7 +36,6 @@ require ( github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect - github.com/golang/protobuf v1.4.2 // indirect github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.2 @@ -118,9 +117,10 @@ require ( go.uber.org/multierr v1.5.0 go.uber.org/zap v1.15.0 go4.org v0.0.0-20190313082347-94abd6928b1d // indirect - golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 + golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 + google.golang.org/api v0.25.0 // indirect launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect ) diff --git a/go.sum b/go.sum index 83af4904c..1e7e750aa 100644 --- a/go.sum +++ b/go.sum @@ -2,11 +2,32 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= contrib.go.opencensus.io/exporter/jaeger v0.1.0 h1:WNc9HbA38xEQmsI40Tjd/MNU/g8byN2Of7lwIjv0Jdc= contrib.go.opencensus.io/exporter/jaeger v0.1.0/go.mod h1:VYianECmuFPwU37O699Vc1GOcy+y8kOsfaxHRImmjbA= contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg= contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= @@ -16,6 +37,7 @@ github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkBy github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= @@ -49,7 +71,7 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -96,6 +118,9 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -119,6 +144,8 @@ github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -154,11 +181,15 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE= github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= -github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2 h1:IUxiqYU8BM8CyjHqxOTUbjrq7OvSDm8n1v9igaxtapM= -github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2/go.mod h1:UIhZq1vHM1BQbpLa9K2HkxpCtbdsGkCc9MnCdKJxYjk= +github.com/drand/drand v0.9.2-0.20200616080806-a94e9c1636a4 h1:wEpu4hGFF0m0uDq/gxT9Ca/HWek0tvsMqsyPpLBWJ/E= +github.com/drand/drand v0.9.2-0.20200616080806-a94e9c1636a4/go.mod h1:Bu8QYdU0YdB2ZQZezHxabmOIciddiwLRnyV4nuZ2HQE= github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= github.com/drand/kyber v1.0.2 h1:dHjtWJZJdn3zBBZ9pqLsLfcR9ScvDvSqzS1sWA8seao= github.com/drand/kyber v1.0.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= +github.com/drand/kyber v1.1.0 h1:uBfD8gwpVufr+7Dvbxi4jGQ+qoMCO5tRfhYPyn+Tpqk= +github.com/drand/kyber v1.1.0/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= +github.com/drand/kyber-bls12381 v0.1.0 h1:/P4C65VnyEwxzR5ZYYVMNzY1If+aYBrdUU5ukwh7LQw= +github.com/drand/kyber-bls12381 v0.1.0/go.mod h1:N1emiHpm+jj7kMlxEbu3MUyOiooTgNySln564cgD9mk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -243,6 +274,9 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= @@ -260,8 +294,11 @@ github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968 h1:s+PDl6lozQ+dEUtUtQn github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= 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= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -270,15 +307,23 @@ github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/status v1.0.3 h1:WkVBY59mw7qUNTr/bLwO7J2vesJ0rQ2C3tMXrTd3w5M= github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc= +github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -291,6 +336,7 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -310,12 +356,18 @@ github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbB github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= @@ -336,12 +388,15 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY= -github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= +github.com/grpc-ecosystem/grpc-gateway v1.14.6 h1:8ERzHx8aj1Sc47mu9n/AksaKCSWrMchFtkdrS4BIj5o= +github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= @@ -384,6 +439,7 @@ github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOo github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -523,7 +579,6 @@ github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= -github.com/ipfs/go-log/v2 v2.1.0/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7 h1:LtL/rvdfbKSthZGmAAD9o4KKg6HA6Qn8gXCCdgnj7lw= github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= @@ -599,6 +654,7 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 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= @@ -608,12 +664,16 @@ github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3/go.mod h1:BYpt4 github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f h1:qET3Wx0v8tMtoTOQnsJXVvqvCopSf48qobR6tcJuDHo= +github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d h1:68u9r4wEvL3gYg2jvAOgROwZ3H+Y3hIDk4tbbmIjcYQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -777,8 +837,8 @@ github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYc github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= -github.com/libp2p/go-libp2p-pubsub v0.3.0/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-pubsub v0.3.1/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= +github.com/libp2p/go-libp2p-pubsub v0.3.2-0.20200527132641-c0712c6e92cf/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-pubsub v0.3.2 h1:k3cJm5JW5mjaWZkobS50sJLJWaB2mBi0HW4eRlE8mSo= github.com/libp2p/go-libp2p-pubsub v0.3.2/go.mod h1:Uss7/Cfz872KggNb+doCVPHeCDmXB7z500m/R8DaAUk= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= @@ -1060,9 +1120,13 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= +github.com/opentracing-contrib/go-grpc v0.0.0-20191001143057-db30781987df h1:vdYtBU6zvL7v+Tr+0xFM/qhahw/EvY8DMMunZHKH6eE= +github.com/opentracing-contrib/go-grpc v0.0.0-20191001143057-db30781987df/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9 h1:QsgXACQhd9QJhEmRumbsMQQvBtmdS0mafoVEBplWXEg= github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= +github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w= +github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= @@ -1100,8 +1164,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= -github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A= +github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= 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= @@ -1117,6 +1181,8 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/node_exporter v1.0.0-rc.0.0.20200428091818-01054558c289/go.mod h1:FGbBv5OPKjch+jNUJmEQpMZytIdyW0NdBtWFcfSKusc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1128,6 +1194,8 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.1.0 h1:jhMy6QXfi3y2HEzFoyuCj40z4OZIIHHPtFyCMftmvKA= +github.com/prometheus/procfs v0.1.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -1175,6 +1243,8 @@ github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745/go.mod h1:G81a github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= @@ -1306,6 +1376,7 @@ go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= @@ -1354,6 +1425,7 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1368,19 +1440,38 @@ golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1402,6 +1493,8 @@ golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1410,17 +1503,27 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1429,6 +1532,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1453,10 +1558,13 @@ golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1466,25 +1574,34 @@ golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200427175716-29b57079015a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1492,6 +1609,7 @@ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1503,26 +1621,44 @@ golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108195415-316d2f248479/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566 h1:OXjomkWHhzUx4+HldlJ2TsMxJdWgEo5CTtspD1wdhdk= golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4 h1:kDtqNkeBrZb8B+atrj50B5XLHpzXXqcCdZPP/ApQ5NY= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -1533,21 +1669,54 @@ google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx1 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.3.2 h1:iTp+3yyl/KOtxa/d1/JUE0GGSoR6FuW5udver22iwpw= google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.25.0 h1:LodzhlzZEUfhXzNUMIfVlf9Gr6Ua5MMtoFWh7+f47qA= +google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8= +google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1555,21 +1724,29 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1603,6 +1780,7 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= @@ -1611,6 +1789,7 @@ howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqp howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= From 030472d61c52376355ce5741cb3208109e103d43 Mon Sep 17 00:00:00 2001 From: Rob Quist Date: Tue, 16 Jun 2020 15:30:41 +0200 Subject: [PATCH 170/379] Remove Rust installation and remove Go installation guide --- documentation/en/install-lotus-ubuntu.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/documentation/en/install-lotus-ubuntu.md b/documentation/en/install-lotus-ubuntu.md index 4d5ba77f9..a72f56a06 100644 --- a/documentation/en/install-lotus-ubuntu.md +++ b/documentation/en/install-lotus-ubuntu.md @@ -25,25 +25,7 @@ sudo apt upgrade ### Install Go 1.14 -Find the latest version of Go [on their website](https://golang.org/dl/) and follow the installation instructions. At the time of writing this document, thats 1.14.4. Extract it to `/usr/local`, and add the go binaries to your `$PATH`. - -```sh -wget -c https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local -echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile -source ~/.profile -``` - -Verify your go installation by running -```sh -go version -``` - -### Install Rust -_(this is an interactive installer)_ -```sh -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source ~/.profile -``` +Install the latest version of Go by following [the docs on their website](https://golang.org/doc/install). ### Clone the Lotus repository From 9d17e0be9d33dbe41cce71f81d5d67c13797c737 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 16 Jun 2020 11:14:49 -0300 Subject: [PATCH 171/379] ClientMinerQueryOfer API & CLI support Signed-off-by: Ignacio Hagopian --- api/api_full.go | 1 + api/apistruct/struct.go | 27 ++++++++++++++---------- cli/client.go | 42 +++++++++++++++++++++++++++----------- node/impl/client/client.go | 39 ++++++++++++++++++++++------------- 4 files changed, 72 insertions(+), 37 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 61ef1fa1c..573a06859 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -118,6 +118,7 @@ type FullNode interface { ClientListDeals(ctx context.Context) ([]DealInfo, error) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) + ClientMinerQueryOffer(ctx context.Context, root cid.Cid, miner address.Address) (QueryOffer, error) ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*CommPRet, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 85ac54c17..18f5a97f6 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -106,17 +106,18 @@ type FullNodeStruct struct { WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` WalletDelete func(context.Context, address.Address) error `perm:"write"` - ClientImport func(ctx context.Context, ref api.FileRef) (cid.Cid, error) `perm:"admin"` - ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"` - ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"` - ClientFindData func(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) `perm:"read"` - ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` - ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` - ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"` - ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"` - ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"` - ClientCalcCommP func(ctx context.Context, inpath string, miner address.Address) (*api.CommPRet, error) `perm:"read"` - ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"` + ClientImport func(ctx context.Context, ref api.FileRef) (cid.Cid, error) `perm:"admin"` + ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"` + ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"` + ClientFindData func(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) `perm:"read"` + ClientMinerQueryOffer func(ctx context.Context, root cid.Cid, miner address.Address) (api.QueryOffer, error) `perm:"read"` + ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` + ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` + ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"` + ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"` + ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"` + ClientCalcCommP func(ctx context.Context, inpath string, miner address.Address) (*api.CommPRet, error) `perm:"read"` + ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"` StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"` StateMinerSectors func(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` @@ -318,6 +319,10 @@ func (c *FullNodeStruct) ClientFindData(ctx context.Context, root cid.Cid) ([]ap return c.Internal.ClientFindData(ctx, root) } +func (c *FullNodeStruct) ClientMinerQueryOffer(ctx context.Context, root cid.Cid, miner address.Address) (api.QueryOffer, error) { + return c.Internal.ClientMinerQueryOffer(ctx, root, miner) +} + func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) { return c.Internal.ClientStartDeal(ctx, params) } diff --git a/cli/client.go b/cli/client.go index 9d4479b62..c692fbe4b 100644 --- a/cli/client.go +++ b/cli/client.go @@ -19,6 +19,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" ) @@ -391,6 +392,10 @@ var clientRetrieveCmd = &cli.Command{ Name: "car", Usage: "export to a car file instead of a regular file", }, + &cli.StringFlag{ + Name: "miner", + Usage: "miner address for retrieval, if not present it'll use local discovery", + }, }, Action: func(cctx *cli.Context) error { if cctx.NArg() != 2 { @@ -398,7 +403,7 @@ var clientRetrieveCmd = &cli.Command{ return nil } - api, closer, err := GetFullNodeAPI(cctx) + fapi, closer, err := GetFullNodeAPI(cctx) if err != nil { return err } @@ -409,7 +414,7 @@ var clientRetrieveCmd = &cli.Command{ if cctx.String("address") != "" { payer, err = address.NewFromString(cctx.String("address")) } else { - payer, err = api.WalletDefaultAddress(ctx) + payer, err = fapi.WalletDefaultAddress(ctx) } if err != nil { return err @@ -432,23 +437,36 @@ var clientRetrieveCmd = &cli.Command{ return nil }*/ // TODO: fix - offers, err := api.ClientFindData(ctx, file) - if err != nil { - return err - } + var offer api.QueryOffer + minerStrAddr := cctx.String("miner") + if minerStrAddr == "" { // Local discovery + offers, err := fapi.ClientFindData(ctx, file) + if err != nil { + return err + } - // TODO: parse offer strings from `client find`, make this smarter - - if len(offers) < 1 { - fmt.Println("Failed to find file") - return nil + // TODO: parse offer strings from `client find`, make this smarter + if len(offers) < 1 { + fmt.Println("Failed to find file") + return nil + } + offer = offers[0] + } else { // Directed retrieval + minerAddr, err := address.NewFromString(minerStrAddr) + if err != nil { + return err + } + offer, err = fapi.ClientMinerQueryOffer(ctx, file, minerAddr) + if err != nil { + return err + } } ref := &lapi.FileRef{ Path: cctx.Args().Get(1), IsCAR: cctx.Bool("car"), } - if err := api.ClientRetrieve(ctx, offers[0].Order(payer), ref); err != nil { + if err := fapi.ClientRetrieve(ctx, offer.Order(payer), ref); err != nil { return xerrors.Errorf("Retrieval Failed: %w", err) } diff --git a/node/impl/client/client.go b/node/impl/client/client.go index ff974e8b2..3ed90b0fa 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -201,25 +201,36 @@ func (a *API) ClientFindData(ctx context.Context, root cid.Cid) ([]api.QueryOffe out := make([]api.QueryOffer, len(peers)) for k, p := range peers { - queryResponse, err := a.Retrieval.Query(ctx, p, root, retrievalmarket.QueryParams{}) - if err != nil { - out[k] = api.QueryOffer{Err: err.Error(), Miner: p.Address, MinerPeerID: p.ID} - } else { - out[k] = api.QueryOffer{ - Root: root, - Size: queryResponse.Size, - MinPrice: queryResponse.PieceRetrievalPrice(), - PaymentInterval: queryResponse.MaxPaymentInterval, - PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease, - Miner: queryResponse.PaymentAddress, // TODO: check - MinerPeerID: p.ID, - } - } + out[k] = a.makeRetrievalQuery(ctx, p, root, retrievalmarket.QueryParams{}) } return out, nil } +func (a *API) ClientMinerQueryOffer(ctx context.Context, payload cid.Cid, miner address.Address) (api.QueryOffer, error) { + rp := retrievalmarket.RetrievalPeer{ + Address: miner, + } + return a.makeRetrievalQuery(ctx, rp, payload, retrievalmarket.QueryParams{}), nil +} + +func (a *API) makeRetrievalQuery(ctx context.Context, rp retrievalmarket.RetrievalPeer, payload cid.Cid, qp retrievalmarket.QueryParams) api.QueryOffer { + queryResponse, err := a.Retrieval.Query(ctx, rp, payload, qp) + if err != nil { + return api.QueryOffer{Err: err.Error(), Miner: rp.Address, MinerPeerID: rp.ID} + } + + return api.QueryOffer{ + Root: payload, + Size: queryResponse.Size, + MinPrice: queryResponse.PieceRetrievalPrice(), + PaymentInterval: queryResponse.MaxPaymentInterval, + PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease, + Miner: queryResponse.PaymentAddress, // TODO: check + MinerPeerID: rp.ID, + } +} + func (a *API) ClientImport(ctx context.Context, ref api.FileRef) (cid.Cid, error) { bufferedDS := ipld.NewBufferedDAG(ctx, a.LocalDAG) From 7fd082e941b69f9fe97c1774720256a8d6c738e3 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 16 Jun 2020 12:22:44 -0300 Subject: [PATCH 172/379] resolve peerid Signed-off-by: Ignacio Hagopian --- node/impl/client/client.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 3ed90b0fa..c2073872f 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -208,8 +208,13 @@ func (a *API) ClientFindData(ctx context.Context, root cid.Cid) ([]api.QueryOffe } func (a *API) ClientMinerQueryOffer(ctx context.Context, payload cid.Cid, miner address.Address) (api.QueryOffer, error) { + mi, err := a.StateMinerInfo(ctx, miner, types.EmptyTSK) + if err != nil { + return api.QueryOffer{}, err + } rp := retrievalmarket.RetrievalPeer{ Address: miner, + ID: mi.PeerId, } return a.makeRetrievalQuery(ctx, rp, payload, retrievalmarket.QueryParams{}), nil } From 35d9de6b6e577a5d7826b9346cd64a3f7575d205 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 16 Jun 2020 17:32:03 -0300 Subject: [PATCH 173/379] consider response status and err Signed-off-by: Ignacio Hagopian --- cli/client.go | 3 +++ node/impl/client/client.go | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/cli/client.go b/cli/client.go index c692fbe4b..1b1459707 100644 --- a/cli/client.go +++ b/cli/client.go @@ -461,6 +461,9 @@ var clientRetrieveCmd = &cli.Command{ return err } } + if offer.Err != "" { + return fmt.Errorf("The received offer errored: %s", offer.Err) + } ref := &lapi.FileRef{ Path: cctx.Args().Get(1), diff --git a/node/impl/client/client.go b/node/impl/client/client.go index c2073872f..23994fbe5 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -224,6 +224,15 @@ func (a *API) makeRetrievalQuery(ctx context.Context, rp retrievalmarket.Retriev if err != nil { return api.QueryOffer{Err: err.Error(), Miner: rp.Address, MinerPeerID: rp.ID} } + var errStr string + switch queryResponse.Status { + case retrievalmarket.QueryResponseAvailable: + errStr = "" + case retrievalmarket.QueryResponseUnavailable: + errStr = "retrieval query offer was unavailable" + case retrievalmarket.QueryResponseError: + errStr = "retrieval query offer errored" + } return api.QueryOffer{ Root: payload, @@ -233,6 +242,7 @@ func (a *API) makeRetrievalQuery(ctx context.Context, rp retrievalmarket.Retriev PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease, Miner: queryResponse.PaymentAddress, // TODO: check MinerPeerID: rp.ID, + Err: errStr, } } From ec9a334f933f2e1066d16ebfc8928411e531f747 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 16 Jun 2020 17:52:47 -0300 Subject: [PATCH 174/379] append message on unavailable and error status Signed-off-by: Ignacio Hagopian --- node/impl/client/client.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 23994fbe5..2779343c4 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -3,6 +3,7 @@ package client import ( "context" "errors" + "fmt" "github.com/filecoin-project/go-fil-markets/pieceio" basicnode "github.com/ipld/go-ipld-prime/node/basic" @@ -229,9 +230,9 @@ func (a *API) makeRetrievalQuery(ctx context.Context, rp retrievalmarket.Retriev case retrievalmarket.QueryResponseAvailable: errStr = "" case retrievalmarket.QueryResponseUnavailable: - errStr = "retrieval query offer was unavailable" + errStr = fmt.Sprintf("retrieval query offer was unavailable: %s", queryResponse.Message) case retrievalmarket.QueryResponseError: - errStr = "retrieval query offer errored" + errStr = fmt.Sprintf("retrieval query offer errored: %s", queryResponse.Message) } return api.QueryOffer{ From 9690bc9c638909b7136887c6f6f5db8bec76a8a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 17 Jun 2020 00:35:51 +0200 Subject: [PATCH 175/379] seed: Cleanup unsealed sectors --- cmd/lotus-seed/seed/seed.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index ffb651c00..be366d4db 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -92,6 +92,10 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect return nil, nil, xerrors.Errorf("trim cache: %w", err) } + if err := cleanupUnsealed(sbfs, sid); err != nil { + return nil, nil, xerrors.Errorf("remove unsealed file: %w", err) + } + log.Warn("PreCommitOutput: ", sid, cids.Sealed, cids.Unsealed) sealedSectors = append(sealedSectors, &genesis.PreSeal{ CommR: cids.Sealed, @@ -161,6 +165,16 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect return miner, &minerAddr.KeyInfo, nil } +func cleanupUnsealed(sbfs *basicfs.Provider, sid abi.SectorID) error { + paths, done, err := sbfs.AcquireSector(context.TODO(), sid, stores.FTUnsealed, stores.FTNone, stores.PathSealing) + if err != nil { + return err + } + defer done() + + return os.Remove(paths.Unsealed) +} + func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Miner, key *types.KeyInfo) error { output := map[string]genesis.Miner{ maddr.String(): *gm, From b845013836376c2f466fb047a2bca560490dd634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 16 Jun 2020 13:59:15 +0200 Subject: [PATCH 176/379] Set build params for testnet --- build/params_testnet.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/params_testnet.go b/build/params_testnet.go index c222862eb..202dfb231 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -12,9 +12,8 @@ import ( ) func init() { - power.ConsensusMinerMinPower = big.NewInt(1024 << 20) + power.ConsensusMinerMinPower = big.NewInt(1024 << 30) miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ - abi.RegisteredSealProof_StackedDrg512MiBV1: {}, abi.RegisteredSealProof_StackedDrg32GiBV1: {}, abi.RegisteredSealProof_StackedDrg64GiBV1: {}, } From 6253c39100f4fcc16099e6f4fbcd620aad11c13c Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 16 Jun 2020 15:38:48 -0700 Subject: [PATCH 177/379] replace "set-price" with "set-ask" Fixes #2027 --- api/api_storage.go | 2 +- api/apistruct/struct.go | 12 +++--- cmd/lotus-storage-miner/main.go | 1 - cmd/lotus-storage-miner/market.go | 71 +++++++++++++++++++++++++------ node/impl/storminer.go | 9 +++- 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 04ff8311c..e07505e3f 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -50,7 +50,7 @@ type StorageMiner interface { MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error) MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) - MarketSetPrice(context.Context, types.BigInt) error + MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 02d9e5155..55c87dbd4 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -192,10 +192,10 @@ type StorageMinerStruct struct { MiningBase func(context.Context) (*types.TipSet, error) `perm:"read"` - MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"` - MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` - MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` - MarketSetPrice func(context.Context, types.BigInt) error `perm:"admin"` + MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"` + MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` + MarketSetAsk func(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error `perm:"admin"` PledgeSector func(context.Context) error `perm:"write"` @@ -841,8 +841,8 @@ func (c *StorageMinerStruct) MarketListIncompleteDeals(ctx context.Context) ([]s return c.Internal.MarketListIncompleteDeals(ctx) } -func (c *StorageMinerStruct) MarketSetPrice(ctx context.Context, p types.BigInt) error { - return c.Internal.MarketSetPrice(ctx, p) +func (c *StorageMinerStruct) MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error { + return c.Internal.MarketSetAsk(ctx, price, duration, minPieceSize, maxPieceSize) } func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error { diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index ba7722e4e..dc6de7029 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -30,7 +30,6 @@ func main() { stopCmd, sectorsCmd, storageCmd, - setPriceCmd, workersCmd, provingCmd, } diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index c2f2555fa..74a42d85d 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -4,10 +4,13 @@ import ( "encoding/json" "fmt" - "github.com/filecoin-project/lotus/chain/types" - lcli "github.com/filecoin-project/lotus/cli" + "github.com/docker/go-units" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "github.com/urfave/cli/v2" + + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" ) var enableCmd = &cli.Command{ @@ -40,29 +43,70 @@ var disableCmd = &cli.Command{ }, } -var setPriceCmd = &cli.Command{ - Name: "set-price", - Usage: "Set price that miner will accept storage deals at (FIL / GiB / Epoch)", - Flags: []cli.Flag{}, +var setAskCmd = &cli.Command{ + Name: "set-ask", + Usage: "Configure the miner's ask", + Flags: []cli.Flag{ + &cli.Uint64Flag{ + Name: "price", + Usage: "Set the price of the ask (specified as FIL / GiB / Epoch) to `PRICE`", + Required: true, + }, + &cli.Uint64Flag{ + Name: "duration", + Usage: "Set the duration (specified as epochs) of the ask to `DURATION`", + DefaultText: "8640000", + Value: 8640000, + }, + &cli.StringFlag{ + Name: "min-piece-size", + Usage: "Set minimum piece size (without bit-padding, in bytes) in ask to `SIZE`", + DefaultText: "254B", + Value: "254B", + }, + &cli.StringFlag{ + Name: "max-piece-size", + Usage: "Set maximum piece size (without bit-padding, in bytes) in ask to `SIZE`", + DefaultText: "miner sector size, without bit-padding", + }, + }, Action: func(cctx *cli.Context) error { + ctx := lcli.DaemonContext(cctx) + api, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { return err } defer closer() - ctx := lcli.DaemonContext(cctx) + pri := types.NewInt(cctx.Uint64("price")) + dur := abi.ChainEpoch(cctx.Uint64("duration")) - if !cctx.Args().Present() { - return fmt.Errorf("must specify price to set") - } - - fp, err := types.ParseFIL(cctx.Args().First()) + min, err := units.RAMInBytes(cctx.String("min-piece-size")) if err != nil { return err } - return api.MarketSetPrice(ctx, types.BigInt(fp)) + max, err := units.RAMInBytes(cctx.String("max-piece-size")) + if err != nil { + return err + } + + if max == 0 { + maddr, err := api.ActorAddress(ctx) + if err != nil { + return err + } + + ssize, err := api.ActorSectorSize(ctx, maddr) + if err != nil { + return err + } + + max = int64(abi.PaddedPieceSize(ssize).Unpadded()) + } + + return api.MarketSetAsk(ctx, pri, dur, abi.UnpaddedPieceSize(min).Padded(), abi.UnpaddedPieceSize(max).Padded()) }, } @@ -74,6 +118,7 @@ var dealsCmd = &cli.Command{ dealsListCmd, enableCmd, disableCmd, + setAskCmd, }, } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 0cc13177e..7ece10ac0 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -201,8 +201,13 @@ func (sm *StorageMinerAPI) MarketListIncompleteDeals(ctx context.Context) ([]sto return sm.StorageProvider.ListLocalDeals() } -func (sm *StorageMinerAPI) MarketSetPrice(ctx context.Context, p types.BigInt) error { - return sm.StorageProvider.SetAsk(p, 60*60*24*100) // lasts for 100 days? +func (sm *StorageMinerAPI) MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error { + options := []storagemarket.StorageAskOption{ + storagemarket.MinPieceSize(minPieceSize), + storagemarket.MaxPieceSize(maxPieceSize), + } + + return sm.StorageProvider.SetAsk(price, duration, options...) } func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) { From 5eceed81e192a9aca66dbe06e6ae64d28e0c264e Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 16 Jun 2020 17:18:54 -0700 Subject: [PATCH 178/379] add "get-ask" command --- api/api_storage.go | 1 + api/apistruct/struct.go | 5 ++++ cmd/lotus-storage-miner/market.go | 46 +++++++++++++++++++++++++++++-- node/impl/storminer.go | 4 +++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index e07505e3f..90de01fb9 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -51,6 +51,7 @@ type StorageMiner interface { MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error) MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error + MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 55c87dbd4..a1fe69f06 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -196,6 +196,7 @@ type StorageMinerStruct struct { MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` MarketSetAsk func(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error `perm:"admin"` + MarketGetAsk func(ctx context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"` PledgeSector func(context.Context) error `perm:"write"` @@ -845,6 +846,10 @@ func (c *StorageMinerStruct) MarketSetAsk(ctx context.Context, price types.BigIn return c.Internal.MarketSetAsk(ctx, price, duration, minPieceSize, maxPieceSize) } +func (c *StorageMinerStruct) MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) { + return c.Internal.MarketGetAsk(ctx) +} + func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error { return c.Internal.DealsImportData(ctx, dealPropCid, file) } diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 74a42d85d..b2b7155c3 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -3,12 +3,16 @@ package main import ( "encoding/json" "fmt" + "os" + "text/tabwriter" "github.com/docker/go-units" - "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "github.com/urfave/cli/v2" + "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -55,8 +59,8 @@ var setAskCmd = &cli.Command{ &cli.Uint64Flag{ Name: "duration", Usage: "Set the duration (specified as epochs) of the ask to `DURATION`", - DefaultText: "8640000", - Value: 8640000, + DefaultText: "100000", + Value: 100000, }, &cli.StringFlag{ Name: "min-piece-size", @@ -110,6 +114,41 @@ var setAskCmd = &cli.Command{ }, } +var getAskCmd = &cli.Command{ + Name: "get-ask", + Usage: "Print the miner's ask", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + ctx := lcli.DaemonContext(cctx) + + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + sask, err := api.MarketGetAsk(ctx) + if err != nil { + return err + } + + var ask *storagemarket.StorageAsk + if sask != nil && sask.Ask != nil { + ask = sask.Ask + } + + w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) + fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (bytes, unpadded)\tMax. Piece Size (bytes, unpadded)\tExpiry\tSeq. No.\n") + if ask == nil { + fmt.Fprintf(w, "\n") + } else { + fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\n", ask.Price, ask.MinPieceSize.Unpadded(), ask.MaxPieceSize.Unpadded(), ask.Expiry, ask.SeqNo) + } + + return w.Flush() + }, +} + var dealsCmd = &cli.Command{ Name: "deals", Usage: "interact with your deals", @@ -119,6 +158,7 @@ var dealsCmd = &cli.Command{ enableCmd, disableCmd, setAskCmd, + getAskCmd, }, } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 7ece10ac0..ed94e173d 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -210,6 +210,10 @@ func (sm *StorageMinerAPI) MarketSetAsk(ctx context.Context, price types.BigInt, return sm.StorageProvider.SetAsk(price, duration, options...) } +func (sm *StorageMinerAPI) MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) { + return sm.StorageProvider.GetAsk(), nil +} + func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) { return sm.StorageProvider.ListDeals(ctx) } From 4ba1846c11d031716ec0d336d8593d20736559c4 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 16 Jun 2020 17:32:45 -0700 Subject: [PATCH 179/379] format the piece sizes --- cmd/lotus-storage-miner/market.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index b2b7155c3..60c53bff8 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -138,11 +138,11 @@ var getAskCmd = &cli.Command{ } w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) - fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (bytes, unpadded)\tMax. Piece Size (bytes, unpadded)\tExpiry\tSeq. No.\n") + fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (unpadded)\tMax. Piece Size (unpadded)\tExpiry\tSeq. No.\n") if ask == nil { fmt.Fprintf(w, "\n") } else { - fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\n", ask.Price, ask.MinPieceSize.Unpadded(), ask.MaxPieceSize.Unpadded(), ask.Expiry, ask.SeqNo) + fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize.Unpadded()))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize.Unpadded()))), ask.Expiry, ask.SeqNo) } return w.Flush() From ec693008d7ba5758e0a5380f681c92e468735c6b Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 16 Jun 2020 17:39:51 -0700 Subject: [PATCH 180/379] allow sealing bench to run parallel seals --- cmd/lotus-bench/main.go | 276 +++++++++++++++++++++++----------------- go.mod | 2 + go.sum | 10 -- 3 files changed, 161 insertions(+), 127 deletions(-) diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index a10c3c00e..06042b3d1 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -139,6 +139,10 @@ var sealBenchCmd = &cli.Command{ Name: "num-sectors", Value: 1, }, + &cli.IntFlag{ + Name: "parallel", + Value: 1, + }, }, Action: func(c *cli.Context) error { if c.Bool("no-gpu") { @@ -235,7 +239,7 @@ var sealBenchCmd = &cli.Command{ if robench == "" { var err error - sealTimings, sealedSectors, err = runSeals(sb, sbfs, c.Int("num-sectors"), mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), c.Bool("skip-commit2"), c.Bool("skip-unseal")) + sealTimings, sealedSectors, err = runSeals(sb, sbfs, c.Int("num-sectors"), c.Int("parallel"), mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), c.Bool("skip-commit2"), c.Bool("skip-unseal")) if err != nil { return xerrors.Errorf("failed to run seals: %w", err) } @@ -447,9 +451,14 @@ var sealBenchCmd = &cli.Command{ }, } -func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []abi.SectorInfo, error) { - var sealTimings []SealingResult - var sealedSectors []abi.SectorInfo +func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, parallelism int, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []abi.SectorInfo, error) { + var pieces []abi.PieceInfo + sealTimings := make([]SealingResult, numSectors) + sealedSectors := make([]abi.SectorInfo, numSectors) + + if numSectors%parallelism != 0 { + return nil, nil, fmt.Errorf("parallelism factor must cleanly divide numSectors") + } for i := abi.SectorNumber(1); i <= abi.SectorNumber(numSectors); i++ { sid := abi.SectorID{ @@ -458,7 +467,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid } start := time.Now() - log.Info("Writing piece into sector...") + log.Infof("[%d] Writing piece into sector...", i) r := rand.New(rand.NewSource(100 + int64(i))) @@ -467,129 +476,162 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid return nil, nil, err } - addpiece := time.Now() + pieces = append(pieces, pi) - trand := blake2b.Sum256(ticketPreimage) - ticket := abi.SealRandomness(trand[:]) + sealTimings[i-1].AddPiece = time.Since(start) + } - log.Info("Running replication(1)...") - pieces := []abi.PieceInfo{pi} - pc1o, err := sb.SealPreCommit1(context.TODO(), sid, ticket, pieces) - if err != nil { - return nil, nil, xerrors.Errorf("commit: %w", err) - } + sectorsPerWorker := numSectors / parallelism - precommit1 := time.Now() + errs := make(chan error, parallelism) + for wid := 0; wid < parallelism; wid++ { + go func(worker int) { + sealerr := func() error { + start := 1 + (worker * sectorsPerWorker) + end := start + sectorsPerWorker + for i := abi.SectorNumber(start); i < abi.SectorNumber(end); i++ { + ix := int(i - 1) + sid := abi.SectorID{ + Miner: mid, + Number: i, + } - log.Info("Running replication(2)...") - cids, err := sb.SealPreCommit2(context.TODO(), sid, pc1o) - if err != nil { - return nil, nil, xerrors.Errorf("commit: %w", err) - } + start := time.Now() - precommit2 := time.Now() + trand := blake2b.Sum256(ticketPreimage) + ticket := abi.SealRandomness(trand[:]) - sealedSectors = append(sealedSectors, abi.SectorInfo{ - SealProof: sb.SealProofType(), - SectorNumber: i, - SealedCID: cids.Sealed, - }) + log.Infof("[%d] Running replication(1)...", i) + pieces := []abi.PieceInfo{pieces[ix]} + pc1o, err := sb.SealPreCommit1(context.TODO(), sid, ticket, pieces) + if err != nil { + return xerrors.Errorf("commit: %w", err) + } - seed := lapi.SealSeed{ - Epoch: 101, - Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 255}, - } + precommit1 := time.Now() - log.Info("Generating PoRep for sector (1)") - c1o, err := sb.SealCommit1(context.TODO(), sid, ticket, seed.Value, pieces, cids) + log.Infof("[%d] Running replication(2)...", i) + cids, err := sb.SealPreCommit2(context.TODO(), sid, pc1o) + if err != nil { + return xerrors.Errorf("commit: %w", err) + } + + precommit2 := time.Now() + + sealedSectors[ix] = abi.SectorInfo{ + SealProof: sb.SealProofType(), + SectorNumber: i, + SealedCID: cids.Sealed, + } + + seed := lapi.SealSeed{ + Epoch: 101, + Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 255}, + } + + log.Infof("[%d] Generating PoRep for sector (1)", i) + c1o, err := sb.SealCommit1(context.TODO(), sid, ticket, seed.Value, pieces, cids) + if err != nil { + return err + } + + sealcommit1 := time.Now() + + log.Infof("[%d] Generating PoRep for sector (2)", i) + + if saveC2inp != "" { + c2in := Commit2In{ + SectorNum: int64(i), + Phase1Out: c1o, + SectorSize: uint64(sectorSize), + } + + b, err := json.Marshal(&c2in) + if err != nil { + return err + } + + if err := ioutil.WriteFile(saveC2inp, b, 0664); err != nil { + log.Warnf("%+v", err) + } + } + + var proof storage.Proof + if !skipc2 { + proof, err = sb.SealCommit2(context.TODO(), sid, c1o) + if err != nil { + return err + } + } + + sealcommit2 := time.Now() + + if !skipc2 { + svi := abi.SealVerifyInfo{ + SectorID: abi.SectorID{Miner: mid, Number: i}, + SealedCID: cids.Sealed, + SealProof: sb.SealProofType(), + Proof: proof, + DealIDs: nil, + Randomness: ticket, + InteractiveRandomness: seed.Value, + UnsealedCID: cids.Unsealed, + } + + ok, err := ffiwrapper.ProofVerifier.VerifySeal(svi) + if err != nil { + return err + } + if !ok { + return xerrors.Errorf("porep proof for sector %d was invalid", i) + } + } + + verifySeal := time.Now() + + if !skipunseal { + log.Infof("[%d] Unsealing sector", i) + { + p, done, err := sbfs.AcquireSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, stores.FTUnsealed, stores.FTNone, true) + if err != nil { + return xerrors.Errorf("acquire unsealed sector for removing: %w", err) + } + done() + + if err := os.Remove(p.Unsealed); err != nil { + return xerrors.Errorf("removing unsealed sector: %w", err) + } + } + + err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed) + if err != nil { + return err + } + } + unseal := time.Now() + + sealTimings[ix].PreCommit1 = precommit1.Sub(start) + sealTimings[ix].PreCommit2 = precommit2.Sub(precommit1) + sealTimings[ix].Commit1 = sealcommit1.Sub(precommit2) + sealTimings[ix].Commit2 = sealcommit2.Sub(sealcommit1) + sealTimings[ix].Verify = verifySeal.Sub(sealcommit2) + sealTimings[ix].Unseal = unseal.Sub(verifySeal) + } + return nil + }() + if sealerr != nil { + errs <- sealerr + return + } + errs <- nil + }(wid) + } + + for i := 0; i < parallelism; i++ { + err := <-errs if err != nil { return nil, nil, err } - - sealcommit1 := time.Now() - - log.Info("Generating PoRep for sector (2)") - - if saveC2inp != "" { - c2in := Commit2In{ - SectorNum: int64(i), - Phase1Out: c1o, - SectorSize: uint64(sectorSize), - } - - b, err := json.Marshal(&c2in) - if err != nil { - return nil, nil, err - } - - if err := ioutil.WriteFile(saveC2inp, b, 0664); err != nil { - log.Warnf("%+v", err) - } - } - - var proof storage.Proof - if !skipc2 { - proof, err = sb.SealCommit2(context.TODO(), sid, c1o) - if err != nil { - return nil, nil, err - } - } - - sealcommit2 := time.Now() - - if !skipc2 { - svi := abi.SealVerifyInfo{ - SectorID: abi.SectorID{Miner: mid, Number: i}, - SealedCID: cids.Sealed, - SealProof: sb.SealProofType(), - Proof: proof, - DealIDs: nil, - Randomness: ticket, - InteractiveRandomness: seed.Value, - UnsealedCID: cids.Unsealed, - } - - ok, err := ffiwrapper.ProofVerifier.VerifySeal(svi) - if err != nil { - return nil, nil, err - } - if !ok { - return nil, nil, xerrors.Errorf("porep proof for sector %d was invalid", i) - } - } - - verifySeal := time.Now() - - if !skipunseal { - log.Info("Unsealing sector") - { - p, done, err := sbfs.AcquireSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, stores.FTUnsealed, stores.FTNone, true) - if err != nil { - return nil, nil, xerrors.Errorf("acquire unsealed sector for removing: %w", err) - } - done() - - if err := os.Remove(p.Unsealed); err != nil { - return nil, nil, xerrors.Errorf("removing unsealed sector: %w", err) - } - } - - err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed) - if err != nil { - return nil, nil, err - } - } - unseal := time.Now() - - sealTimings = append(sealTimings, SealingResult{ - AddPiece: addpiece.Sub(start), - PreCommit1: precommit1.Sub(addpiece), - PreCommit2: precommit2.Sub(precommit1), - Commit1: sealcommit1.Sub(precommit2), - Commit2: sealcommit2.Sub(sealcommit1), - Verify: verifySeal.Sub(sealcommit2), - Unseal: unseal.Sub(verifySeal), - }) } return sealTimings, sealedSectors, nil diff --git a/go.mod b/go.mod index d5e684e46..13b68200b 100644 --- a/go.mod +++ b/go.mod @@ -126,4 +126,6 @@ require ( replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 +replace github.com/filecoin-project/specs-actors => ../specs-actors + replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi diff --git a/go.sum b/go.sum index 53c989e62..f28646534 100644 --- a/go.sum +++ b/go.sum @@ -215,14 +215,11 @@ github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGj github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09 h1:GuiNSEZ9nc05LUpKhABw/SO6t9wqCfsJX1D0ByWQjkc= github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09/go.mod h1:HEJn6kOXMNhCNBYNTO/lrEI7wSgqCOR6hN5ecfYUnC8= -github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef/go.mod h1:SrA+pWVoUivqKOfC+ckVYbx41hWz++HxJcrlmHNnebU= -github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 h1:jamfsxfK0Q9yCMHt8MPWx7Aa/O9k2Lve8eSc6FILYGQ= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= -github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e h1:gkG/7G+iKy4He+IiQNeQn+nndFznb/vCoOR8iRQsm60= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= @@ -255,12 +252,6 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 h1:cjsOpQKvZosPx9/qqq2bucHVdRyXzvBR1f37atiR3/0= github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= -github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= -github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= -github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9kNbbHOcU/9oiC0= -github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= -github.com/filecoin-project/specs-actors v0.6.1 h1:rhHlEzqcuuQU6oKc4csuq+/kQBDZ4EXtSomoN2XApCA= -github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg= @@ -1330,7 +1321,6 @@ github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CH github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200501014322-5f9941ef88e0/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= From 5acf5bf102d9f11eb63f49eaecaeb8604d202380 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 16 Jun 2020 17:45:11 -0700 Subject: [PATCH 181/379] upper and lower bounds checking --- cmd/lotus-storage-miner/market.go | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 60c53bff8..84465f60d 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -8,6 +8,7 @@ import ( "github.com/docker/go-units" "github.com/ipfs/go-cid" + "github.com/pkg/errors" "github.com/urfave/cli/v2" "github.com/filecoin-project/go-fil-markets/storagemarket" @@ -91,23 +92,33 @@ var setAskCmd = &cli.Command{ return err } + if min < 254 { + return errors.New("minimum piece size (unpadded) is 254 B") + } + max, err := units.RAMInBytes(cctx.String("max-piece-size")) if err != nil { return err } + maddr, err := api.ActorAddress(ctx) + if err != nil { + return err + } + + ssize, err := api.ActorSectorSize(ctx, maddr) + if err != nil { + return err + } + + smax := int64(abi.PaddedPieceSize(ssize).Unpadded()) + if max == 0 { - maddr, err := api.ActorAddress(ctx) - if err != nil { - return err - } + max = smax + } - ssize, err := api.ActorSectorSize(ctx, maddr) - if err != nil { - return err - } - - max = int64(abi.PaddedPieceSize(ssize).Unpadded()) + if max > smax { + return errors.Errorf("max piece size (unpadded) %s cannot exceed miner sector size (unpadded) %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax)))) } return api.MarketSetAsk(ctx, pri, dur, abi.UnpaddedPieceSize(min).Padded(), abi.UnpaddedPieceSize(max).Padded()) From 2676892886cf674528528b46432fa80a76baaefa Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 16 Jun 2020 17:47:04 -0700 Subject: [PATCH 182/379] go mod tidy --- go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/go.mod b/go.mod index d5e684e46..cb94ad055 100644 --- a/go.mod +++ b/go.mod @@ -103,6 +103,7 @@ require ( github.com/multiformats/go-multibase v0.0.2 github.com/multiformats/go-multihash v0.0.13 github.com/opentracing/opentracing-go v1.1.0 + github.com/pkg/errors v0.9.1 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 From 139c3297ab59939285842baea007276019add121 Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 08:34:50 -0700 Subject: [PATCH 183/379] change "duration" help text --- cmd/lotus-storage-miner/market.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 84465f60d..1163e09e8 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -59,7 +59,7 @@ var setAskCmd = &cli.Command{ }, &cli.Uint64Flag{ Name: "duration", - Usage: "Set the duration (specified as epochs) of the ask to `DURATION`", + Usage: "Set the number of epochs (from now) that the ask will expire `DURATION`", DefaultText: "100000", Value: 100000, }, From 5d4f1bb3f1b8004ce75cff2e3154d501014ea0a3 Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 08:42:30 -0700 Subject: [PATCH 184/379] work with bit-padded byte quantities, as per PR feedback --- cmd/lotus-storage-miner/market.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 1163e09e8..8d677a55c 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -10,6 +10,7 @@ import ( "github.com/ipfs/go-cid" "github.com/pkg/errors" "github.com/urfave/cli/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/specs-actors/actors/abi" @@ -59,20 +60,20 @@ var setAskCmd = &cli.Command{ }, &cli.Uint64Flag{ Name: "duration", - Usage: "Set the number of epochs (from now) that the ask will expire `DURATION`", + Usage: "Set the number of epochs from the current chain head that the ask will expire `DURATION`", DefaultText: "100000", Value: 100000, }, &cli.StringFlag{ Name: "min-piece-size", - Usage: "Set minimum piece size (without bit-padding, in bytes) in ask to `SIZE`", - DefaultText: "254B", - Value: "254B", + Usage: "Set minimum piece size (w/bit-padding, in bytes) in ask to `SIZE`", + DefaultText: "256B", + Value: "256B", }, &cli.StringFlag{ Name: "max-piece-size", - Usage: "Set maximum piece size (without bit-padding, in bytes) in ask to `SIZE`", - DefaultText: "miner sector size, without bit-padding", + Usage: "Set maximum piece size (w/bit-padding, in bytes) in ask to `SIZE`", + DefaultText: "miner sector size", }, }, Action: func(cctx *cli.Context) error { @@ -92,8 +93,8 @@ var setAskCmd = &cli.Command{ return err } - if min < 254 { - return errors.New("minimum piece size (unpadded) is 254 B") + if min < 256 { + return xerrors.New("minimum piece size (w/bit-padding) is 256B") } max, err := units.RAMInBytes(cctx.String("max-piece-size")) @@ -111,17 +112,17 @@ var setAskCmd = &cli.Command{ return err } - smax := int64(abi.PaddedPieceSize(ssize).Unpadded()) + smax := int64(ssize) if max == 0 { max = smax } if max > smax { - return errors.Errorf("max piece size (unpadded) %s cannot exceed miner sector size (unpadded) %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax)))) + return errors.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax)))) } - return api.MarketSetAsk(ctx, pri, dur, abi.UnpaddedPieceSize(min).Padded(), abi.UnpaddedPieceSize(max).Padded()) + return api.MarketSetAsk(ctx, pri, dur, abi.PaddedPieceSize(min), abi.PaddedPieceSize(max)) }, } @@ -149,11 +150,11 @@ var getAskCmd = &cli.Command{ } w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) - fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (unpadded)\tMax. Piece Size (unpadded)\tExpiry\tSeq. No.\n") + fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (w/bit-padding)\tMax. Piece Size (w/bit-padding)\tExpiry\tSeq. No.\n") if ask == nil { fmt.Fprintf(w, "\n") } else { - fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize.Unpadded()))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize.Unpadded()))), ask.Expiry, ask.SeqNo) + fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, ask.SeqNo) } return w.Flush() From 8b8bb5e833b82402fb7e764701227f1d56e18cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 17 Jun 2020 16:44:59 +0200 Subject: [PATCH 185/379] rpc: add Closing method --- api/api_common.go | 2 ++ api/apistruct/struct.go | 7 ++++++- node/impl/common/common.go | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/api/api_common.go b/api/api_common.go index e5556d16f..6d47e35f7 100644 --- a/api/api_common.go +++ b/api/api_common.go @@ -38,6 +38,8 @@ type Common interface { // trigger graceful shutdown Shutdown(context.Context) error + + Closing(context.Context) (<-chan struct{}, error) } // Version provides various build-time information diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 02d9e5155..dfa7a44ee 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -50,7 +50,8 @@ type CommonStruct struct { LogList func(context.Context) ([]string, error) `perm:"write"` LogSetLevel func(context.Context, string, string) error `perm:"write"` - Shutdown func(context.Context) error `perm:"admin"` + Shutdown func(context.Context) error `perm:"admin"` + Closing func(context.Context) (<-chan struct{}, error) `perm:"read"` } } @@ -313,6 +314,10 @@ func (c *CommonStruct) Shutdown(ctx context.Context) error { return c.Internal.Shutdown(ctx) } +func (c *CommonStruct) Closing(ctx context.Context) (<-chan struct{}, error) { + return c.Internal.Closing(ctx) +} + // FullNodeStruct func (c *FullNodeStruct) ClientListImports(ctx context.Context) ([]api.Import, error) { diff --git a/node/impl/common/common.go b/node/impl/common/common.go index aa85d9182..3a42872d9 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -139,4 +139,8 @@ func (a *CommonAPI) Shutdown(ctx context.Context) error { return nil } +func (a *CommonAPI) Closing(ctx context.Context) (<-chan struct{}, error) { + return make(chan struct{}), nil // relies on jsonrpc closing +} + var _ api.Common = &CommonAPI{} From fc7195f19ab9ccd2ce0e41cdca819843ee8466d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 17 Jun 2020 17:23:07 +0200 Subject: [PATCH 186/379] seal-worker: Wait for miner API on start --- cmd/lotus-seal-worker/main.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 65418ead8..bb83ebf8c 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -3,11 +3,13 @@ package main import ( "context" "encoding/json" + "fmt" "io/ioutil" "net" "net/http" "os" "path/filepath" + "time" "github.com/google/uuid" "github.com/gorilla/mux" @@ -117,10 +119,18 @@ var runCmd = &cli.Command{ } // Connect to storage-miner + var nodeApi api.StorageMiner + var closer func() + var err error + for { + nodeApi, closer, err = lcli.GetStorageMinerAPI(cctx) + if err == nil { + break + } + fmt.Printf("\r\x1b[0KConnecting to miner API... (%s)", err) + time.Sleep(time.Second) + continue - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return xerrors.Errorf("getting miner api: %w", err) } defer closer() ctx := lcli.ReqContext(cctx) From 2761872ea7e77bd709254b1637de541d3b171b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 17 Jun 2020 17:43:16 +0200 Subject: [PATCH 187/379] seal-worker: Auto-restart when API connection is lost --- cmd/lotus-seal-worker/main.go | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index bb83ebf8c..ff45687f8 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -9,6 +9,7 @@ import ( "net/http" "os" "path/filepath" + "syscall" "time" "github.com/google/uuid" @@ -130,8 +131,8 @@ var runCmd = &cli.Command{ fmt.Printf("\r\x1b[0KConnecting to miner API... (%s)", err) time.Sleep(time.Second) continue - } + defer closer() ctx := lcli.ReqContext(cctx) ctx, cancel := context.WithCancel(ctx) @@ -146,6 +147,8 @@ var runCmd = &cli.Command{ } log.Infof("Remote version %s", v) + watchMinerConn(ctx, cctx, nodeApi) + // Check params act, err := nodeApi.ActorAddress(ctx) @@ -327,3 +330,42 @@ var runCmd = &cli.Command{ return srv.Serve(nl) }, } + +func watchMinerConn(ctx context.Context, cctx *cli.Context, nodeApi api.StorageMiner) { + go func() { + closing, err := nodeApi.Closing(ctx) + if err != nil { + log.Errorf("failed to get remote closing channel: %+v", err) + } + + select { + case <-closing: + case <-ctx.Done(): + } + + if ctx.Err() != nil { + return // graceful shutdown + } + + log.Warnf("Connection with miner node lost, restarting") + + exe, err := os.Executable() + if err != nil { + log.Errorf("getting executable for auto-restart: %+v", err) + } + + log.Sync() + + // TODO: there are probably cleaner/more graceful ways to restart, + // but this is good enough for now (FSM can recover from the mess this creates) + if err := syscall.Exec(exe, []string{exe, "run", + fmt.Sprintf("--address=%s", cctx.String("address")), + fmt.Sprintf("--no-local-storage=%t", cctx.Bool("no-local-storage")), + fmt.Sprintf("--precommit1=%t", cctx.Bool("precommit1")), + fmt.Sprintf("--precommit2=%t", cctx.Bool("precommit2")), + fmt.Sprintf("--commit=%t", cctx.Bool("commit")), + }, os.Environ()); err != nil { + fmt.Println(err) + } + }() +} From 673a64318426dda40ca3244f82c7e9af662c8ceb Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 08:57:18 -0700 Subject: [PATCH 188/379] use xerrors, as per feedback in PR --- cmd/lotus-storage-miner/market.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 8d677a55c..71be988e9 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -8,7 +8,6 @@ import ( "github.com/docker/go-units" "github.com/ipfs/go-cid" - "github.com/pkg/errors" "github.com/urfave/cli/v2" "golang.org/x/xerrors" @@ -119,7 +118,7 @@ var setAskCmd = &cli.Command{ } if max > smax { - return errors.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax)))) + return xerrors.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax)))) } return api.MarketSetAsk(ctx, pri, dur, abi.PaddedPieceSize(min), abi.PaddedPieceSize(max)) From 9d7be5dcbfac3e6cdb90e9ac5a33effa8b6c879c Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 09:20:43 -0700 Subject: [PATCH 189/379] modify set-ask to work with human-readable clock time/duration --- cmd/lotus-storage-miner/market.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 71be988e9..a189706f3 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "text/tabwriter" + "time" "github.com/docker/go-units" "github.com/ipfs/go-cid" @@ -14,6 +15,7 @@ import ( "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -57,11 +59,11 @@ var setAskCmd = &cli.Command{ Usage: "Set the price of the ask (specified as FIL / GiB / Epoch) to `PRICE`", Required: true, }, - &cli.Uint64Flag{ + &cli.StringFlag{ Name: "duration", - Usage: "Set the number of epochs from the current chain head that the ask will expire `DURATION`", - DefaultText: "100000", - Value: 100000, + Usage: "Set duration of ask (a quantity of time after which the ask expires) `DURATION`", + DefaultText: "30d0h0m0s", + Value: "30d0h0m0s", }, &cli.StringFlag{ Name: "min-piece-size", @@ -85,11 +87,17 @@ var setAskCmd = &cli.Command{ defer closer() pri := types.NewInt(cctx.Uint64("price")) - dur := abi.ChainEpoch(cctx.Uint64("duration")) + + dur, err := time.ParseDuration(cctx.String("duration")) + if err != nil { + return xerrors.Errorf("cannot parse duration: %w", err) + } + + qty := dur.Seconds() / build.BlockDelay min, err := units.RAMInBytes(cctx.String("min-piece-size")) if err != nil { - return err + return xerrors.Errorf("cannot parse min-piece-size to quantity of bytes: %w", err) } if min < 256 { @@ -98,7 +106,7 @@ var setAskCmd = &cli.Command{ max, err := units.RAMInBytes(cctx.String("max-piece-size")) if err != nil { - return err + return xerrors.Errorf("cannot parse max-piece-size to quantity of bytes: %w", err) } maddr, err := api.ActorAddress(ctx) @@ -121,7 +129,7 @@ var setAskCmd = &cli.Command{ return xerrors.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax)))) } - return api.MarketSetAsk(ctx, pri, dur, abi.PaddedPieceSize(min), abi.PaddedPieceSize(max)) + return api.MarketSetAsk(ctx, pri, abi.ChainEpoch(qty), abi.PaddedPieceSize(min), abi.PaddedPieceSize(max)) }, } From e60dd219dc8a89126fbf0c8470187fa59724e464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 17 Jun 2020 18:21:40 +0200 Subject: [PATCH 190/379] wdpost: Don't return nil from checkSectors --- storage/wdpost_run.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 902c9b741..5c1170551 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -99,10 +99,6 @@ func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check *abi.BitFi log.Warnw("Checked sectors", "checked", len(tocheck), "good", len(sectors)) - if len(sectors) == 0 { // nothing to recover - return nil, nil - } - sbf := bitfield.New() for s := range sectors { (&sbf).Set(uint64(s.Number)) From 402cd8be1903bb50eff997ad1272e5810178aeb3 Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 10:20:42 -0700 Subject: [PATCH 191/379] get-ask output should use durations, too --- cmd/lotus-storage-miner/market.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index a189706f3..977ae22de 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -62,8 +62,8 @@ var setAskCmd = &cli.Command{ &cli.StringFlag{ Name: "duration", Usage: "Set duration of ask (a quantity of time after which the ask expires) `DURATION`", - DefaultText: "30d0h0m0s", - Value: "30d0h0m0s", + DefaultText: "720h0m0s", + Value: "720h0m0s", }, &cli.StringFlag{ Name: "min-piece-size", @@ -157,13 +157,22 @@ var getAskCmd = &cli.Command{ } w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) - fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (w/bit-padding)\tMax. Piece Size (w/bit-padding)\tExpiry\tSeq. No.\n") + fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (w/bit-padding)\tMax. Piece Size (w/bit-padding)\tExpiry (Epoch)\tExpiry (Appx. Rem. Time)\tSeq. No.\n") if ask == nil { fmt.Fprintf(w, "\n") - } else { - fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, ask.SeqNo) + + return w.Flush() } + miningBaseTs, err := api.MiningBase(ctx) + if err != nil { + return err + } + + rem := time.Second * time.Duration((ask.Expiry-miningBaseTs.Height())*build.BlockDelay) + + fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, rem, ask.SeqNo) + return w.Flush() }, } From 791dff5a8712c3291a67f1977a08d27bfbdb27ba Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 10:30:16 -0700 Subject: [PATCH 192/379] don't go into negative remaining time --- cmd/lotus-storage-miner/market.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 977ae22de..dd99a375c 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -169,7 +169,11 @@ var getAskCmd = &cli.Command{ return err } - rem := time.Second * time.Duration((ask.Expiry-miningBaseTs.Height())*build.BlockDelay) + dlt := ask.Expiry - miningBaseTs.Height() + rem := "" + if dlt > 0 { + rem = (time.Second * time.Duration(dlt*build.BlockDelay)).String() + } fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, rem, ask.SeqNo) From ed5b74b1ae377910aaf4398b5af885412142f806 Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 10:42:09 -0700 Subject: [PATCH 193/379] tidy up --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index cb94ad055..d5e684e46 100644 --- a/go.mod +++ b/go.mod @@ -103,7 +103,6 @@ require ( github.com/multiformats/go-multibase v0.0.2 github.com/multiformats/go-multihash v0.0.13 github.com/opentracing/opentracing-go v1.1.0 - github.com/pkg/errors v0.9.1 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 From fcdfda8ba2eb2e994d26eabe8be759c947f60ad7 Mon Sep 17 00:00:00 2001 From: laser Date: Wed, 17 Jun 2020 10:56:42 -0700 Subject: [PATCH 194/379] use chain head instead of mining base --- cmd/lotus-storage-miner/market.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index dd99a375c..4dac236e4 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -140,13 +140,19 @@ var getAskCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := lcli.DaemonContext(cctx) - api, closer, err := lcli.GetStorageMinerAPI(cctx) + fnapi, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err } defer closer() - sask, err := api.MarketGetAsk(ctx) + smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + sask, err := smapi.MarketGetAsk(ctx) if err != nil { return err } @@ -164,12 +170,12 @@ var getAskCmd = &cli.Command{ return w.Flush() } - miningBaseTs, err := api.MiningBase(ctx) + head, err := fnapi.ChainHead(ctx) if err != nil { return err } - dlt := ask.Expiry - miningBaseTs.Height() + dlt := ask.Expiry - head.Height() rem := "" if dlt > 0 { rem = (time.Second * time.Duration(dlt*build.BlockDelay)).String() From b91e7a98609d382a01cd00b457df2ec454dbd299 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 17 Jun 2020 20:00:30 +0200 Subject: [PATCH 195/379] Update to specs actors with ChargeGas interface Based on `lotus-0.6.1-chargegas` in specs-actors. Signed-off-by: Jakub Sztandera --- chain/vm/runtime.go | 14 +++++++++++--- go.mod | 2 +- go.sum | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 48563df64..d6d49c214 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -253,7 +253,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) { rt.Abortf(exitcode.SysErrorIllegalArgument, "Actor address already exists") } - rt.ChargeGas(rt.Pricelist().OnCreateActor()) + rt.chargeGas(rt.Pricelist().OnCreateActor()) err = rt.state.SetActor(address, &types.Actor{ Code: codeID, @@ -267,7 +267,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) { } func (rt *Runtime) DeleteActor(addr address.Address) { - rt.ChargeGas(rt.Pricelist().OnDeleteActor()) + rt.chargeGas(rt.Pricelist().OnDeleteActor()) act, err := rt.state.GetActor(rt.Message().Receiver()) if err != nil { if xerrors.Is(err, types.ErrActorNotFound) { @@ -496,7 +496,15 @@ func (rt *Runtime) finilizeGasTracing() { } } -func (rt *Runtime) ChargeGas(gas GasCharge) { +// ChargeGas is spec actors function +func (rt *Runtime) ChargeGas(name string, compute int64, virtual int64) { + err := rt.chargeGasInternal(newGasCharge(name, compute, 0).WithVirtual(virtual, 0), 1) + if err != nil { + panic(err) + } +} + +func (rt *Runtime) chargeGas(gas GasCharge) { err := rt.chargeGasInternal(gas, 1) if err != nil { panic(err) diff --git a/go.mod b/go.mod index d5e684e46..c2471b82a 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 - github.com/filecoin-project/specs-actors v0.6.1 + github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.0 github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 53c989e62..14308aedb 100644 --- a/go.sum +++ b/go.sum @@ -261,6 +261,8 @@ github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9 github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.1 h1:rhHlEzqcuuQU6oKc4csuq+/kQBDZ4EXtSomoN2XApCA= github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= +github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg= From d66c70d1e6ae1002811bec1feefadc1c3b211bf3 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 17 Jun 2020 11:02:48 -0700 Subject: [PATCH 196/379] add configurable paralellism for sub portions of the sealing process --- cmd/lotus-bench/main.go | 38 +++++++++++++++++++++++++++++--------- go.mod | 2 -- go.sum | 9 +++++++++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 06042b3d1..3a649418f 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -239,7 +239,12 @@ var sealBenchCmd = &cli.Command{ if robench == "" { var err error - sealTimings, sealedSectors, err = runSeals(sb, sbfs, c.Int("num-sectors"), c.Int("parallel"), mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), c.Bool("skip-commit2"), c.Bool("skip-unseal")) + parCfg := ParCfg{ + PreCommit1: c.Int("parallel"), + PreCommit2: 1, + Commit: 1, + } + sealTimings, sealedSectors, err = runSeals(sb, sbfs, c.Int("num-sectors"), parCfg, mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), c.Bool("skip-commit2"), c.Bool("skip-unseal")) if err != nil { return xerrors.Errorf("failed to run seals: %w", err) } @@ -451,12 +456,21 @@ var sealBenchCmd = &cli.Command{ }, } -func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, parallelism int, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []abi.SectorInfo, error) { +type ParCfg struct { + PreCommit1 int + PreCommit2 int + Commit int +} + +func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par ParCfg, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []abi.SectorInfo, error) { var pieces []abi.PieceInfo sealTimings := make([]SealingResult, numSectors) sealedSectors := make([]abi.SectorInfo, numSectors) - if numSectors%parallelism != 0 { + preCommit2Sema := make(chan struct{}, par.PreCommit2) + commitSema := make(chan struct{}, par.Commit) + + if numSectors%par.PreCommit1 != 0 { return nil, nil, fmt.Errorf("parallelism factor must cleanly divide numSectors") } @@ -481,10 +495,10 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, paralle sealTimings[i-1].AddPiece = time.Since(start) } - sectorsPerWorker := numSectors / parallelism + sectorsPerWorker := numSectors / par.PreCommit1 - errs := make(chan error, parallelism) - for wid := 0; wid < parallelism; wid++ { + errs := make(chan error, par.PreCommit1) + for wid := 0; wid < par.PreCommit1; wid++ { go func(worker int) { sealerr := func() error { start := 1 + (worker * sectorsPerWorker) @@ -510,6 +524,8 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, paralle precommit1 := time.Now() + preCommit2Sema <- struct{}{} + pc2Start := time.Now() log.Infof("[%d] Running replication(2)...", i) cids, err := sb.SealPreCommit2(context.TODO(), sid, pc1o) if err != nil { @@ -517,6 +533,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, paralle } precommit2 := time.Now() + <-preCommit2Sema sealedSectors[ix] = abi.SectorInfo{ SealProof: sb.SealProofType(), @@ -529,6 +546,8 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, paralle Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 255}, } + commitSema <- struct{}{} + commitStart := time.Now() log.Infof("[%d] Generating PoRep for sector (1)", i) c1o, err := sb.SealCommit1(context.TODO(), sid, ticket, seed.Value, pieces, cids) if err != nil { @@ -565,6 +584,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, paralle } sealcommit2 := time.Now() + <-commitSema if !skipc2 { svi := abi.SealVerifyInfo{ @@ -611,8 +631,8 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, paralle unseal := time.Now() sealTimings[ix].PreCommit1 = precommit1.Sub(start) - sealTimings[ix].PreCommit2 = precommit2.Sub(precommit1) - sealTimings[ix].Commit1 = sealcommit1.Sub(precommit2) + sealTimings[ix].PreCommit2 = precommit2.Sub(pc2Start) + sealTimings[ix].Commit1 = sealcommit1.Sub(commitStart) sealTimings[ix].Commit2 = sealcommit2.Sub(sealcommit1) sealTimings[ix].Verify = verifySeal.Sub(sealcommit2) sealTimings[ix].Unseal = unseal.Sub(verifySeal) @@ -627,7 +647,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors, paralle }(wid) } - for i := 0; i < parallelism; i++ { + for i := 0; i < par.PreCommit1; i++ { err := <-errs if err != nil { return nil, nil, err diff --git a/go.mod b/go.mod index 13b68200b..d5e684e46 100644 --- a/go.mod +++ b/go.mod @@ -126,6 +126,4 @@ require ( replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 -replace github.com/filecoin-project/specs-actors => ../specs-actors - replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi diff --git a/go.sum b/go.sum index f28646534..68b7fbd1f 100644 --- a/go.sum +++ b/go.sum @@ -215,11 +215,14 @@ github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGj github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09 h1:GuiNSEZ9nc05LUpKhABw/SO6t9wqCfsJX1D0ByWQjkc= github.com/filecoin-project/chain-validation v0.0.6-0.20200615191232-6be1a8c6ed09/go.mod h1:HEJn6kOXMNhCNBYNTO/lrEI7wSgqCOR6hN5ecfYUnC8= +github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U= github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef/go.mod h1:SrA+pWVoUivqKOfC+ckVYbx41hWz++HxJcrlmHNnebU= +github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 h1:jamfsxfK0Q9yCMHt8MPWx7Aa/O9k2Lve8eSc6FILYGQ= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= +github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e h1:gkG/7G+iKy4He+IiQNeQn+nndFznb/vCoOR8iRQsm60= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= @@ -252,6 +255,11 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 h1:cjsOpQKvZosPx9/qqq2bucHVdRyXzvBR1f37atiR3/0= github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= +github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= +github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.6.1 h1:rhHlEzqcuuQU6oKc4csuq+/kQBDZ4EXtSomoN2XApCA= +github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg= @@ -1321,6 +1329,7 @@ github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CH github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200501014322-5f9941ef88e0/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= From 5c5a3f22648bd410e82fc2fac3e37914454f9f26 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 17 Jun 2020 20:04:28 +0200 Subject: [PATCH 197/379] go mod tidy Signed-off-by: Jakub Sztandera --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 14308aedb..c48bc2071 100644 --- a/go.sum +++ b/go.sum @@ -259,8 +259,6 @@ github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.m github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9kNbbHOcU/9oiC0= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= -github.com/filecoin-project/specs-actors v0.6.1 h1:rhHlEzqcuuQU6oKc4csuq+/kQBDZ4EXtSomoN2XApCA= -github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= From 290512ee68c5f57904cb93034add64a3d2718fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 17 Jun 2020 20:42:08 +0200 Subject: [PATCH 198/379] Update storage FSM with a bunch of fixes --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c2471b82a..dea622198 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.0 - github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 + github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index c48bc2071..11848416b 100644 --- a/go.sum +++ b/go.sum @@ -263,8 +263,8 @@ github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= -github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg= -github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0= +github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 h1:zPKiZPMgkFF0Lq13hsk8lcWlxeVAs6vvJaa3uHn9v70= +github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= From c7e470bd5eda2bba34e81cd06be948ba24bb2d86 Mon Sep 17 00:00:00 2001 From: Jim Pick Date: Wed, 17 Jun 2020 12:49:23 -0700 Subject: [PATCH 199/379] Spelling: s/winnnig/winning/ It was bugging me. :-) --- cmd/lotus-bench/main.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index a10c3c00e..e3d213a86 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -307,7 +307,7 @@ var sealBenchCmd = &cli.Command{ return err } - winnnigpost1 := time.Now() + winningpost1 := time.Now() log.Info("computing winning post snark (hot)") proof2, err := sb.GenerateWinningPoSt(context.TODO(), mid, candidates, challenge[:]) @@ -331,7 +331,7 @@ var sealBenchCmd = &cli.Command{ log.Error("post verification failed") } - verifyWinnnigPost1 := time.Now() + verifyWinningPost1 := time.Now() pvi2 := abi.WinningPoStVerifyInfo{ Randomness: abi.PoStRandomness(challenge[:]), @@ -398,10 +398,10 @@ var sealBenchCmd = &cli.Command{ verifyWindowpost2 := time.Now() bo.PostGenerateCandidates = gencandidates.Sub(beforePost) - bo.PostWinningProofCold = winnnigpost1.Sub(gencandidates) - bo.PostWinningProofHot = winnningpost2.Sub(winnnigpost1) - bo.VerifyWinningPostCold = verifyWinnnigPost1.Sub(winnningpost2) - bo.VerifyWinningPostHot = verifyWinningPost2.Sub(verifyWinnnigPost1) + bo.PostWinningProofCold = winningpost1.Sub(gencandidates) + bo.PostWinningProofHot = winnningpost2.Sub(winningpost1) + bo.VerifyWinningPostCold = verifyWinningPost1.Sub(winnningpost2) + bo.VerifyWinningPostHot = verifyWinningPost2.Sub(verifyWinningPost1) bo.PostWindowProofCold = windowpost1.Sub(verifyWinningPost2) bo.PostWindowProofHot = windowpost2.Sub(windowpost1) @@ -432,10 +432,10 @@ var sealBenchCmd = &cli.Command{ } if !c.Bool("skip-commit2") { fmt.Printf("generate candidates: %s (%s)\n", bo.PostGenerateCandidates, bps(bo.SectorSize*abi.SectorSize(len(bo.SealingResults)), bo.PostGenerateCandidates)) - fmt.Printf("compute winnnig post proof (cold): %s\n", bo.PostWinningProofCold) - fmt.Printf("compute winnnig post proof (hot): %s\n", bo.PostWinningProofHot) - fmt.Printf("verify winnnig post proof (cold): %s\n", bo.VerifyWinningPostCold) - fmt.Printf("verify winnnig post proof (hot): %s\n\n", bo.VerifyWinningPostHot) + fmt.Printf("compute winning post proof (cold): %s\n", bo.PostWinningProofCold) + fmt.Printf("compute winning post proof (hot): %s\n", bo.PostWinningProofHot) + fmt.Printf("verify winning post proof (cold): %s\n", bo.VerifyWinningPostCold) + fmt.Printf("verify winning post proof (hot): %s\n\n", bo.VerifyWinningPostHot) fmt.Printf("compute window post proof (cold): %s\n", bo.PostWindowProofCold) fmt.Printf("compute window post proof (hot): %s\n", bo.PostWindowProofHot) From c02d8225a8223ea951e359e42290d9ec16c9c21f Mon Sep 17 00:00:00 2001 From: Travis Person Date: Wed, 17 Jun 2020 23:01:26 +0000 Subject: [PATCH 200/379] Bootstrap peers --- build/bootstrap/bootstrappers.pi | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build/bootstrap/bootstrappers.pi b/build/bootstrap/bootstrappers.pi index 61b7dede3..0854ac0ed 100644 --- a/build/bootstrap/bootstrappers.pi +++ b/build/bootstrap/bootstrappers.pi @@ -1,12 +1,12 @@ -/dns4/bootstrap-0-sin.fil-test.net/tcp/1347/p2p/12D3KooWKNF7vNFEhnvB45E9mw2B5z6t419W3ziZPLdUDVnLLKGs -/ip4/86.109.15.57/tcp/1347/p2p/12D3KooWKNF7vNFEhnvB45E9mw2B5z6t419W3ziZPLdUDVnLLKGs -/dns4/bootstrap-0-dfw.fil-test.net/tcp/1347/p2p/12D3KooWECJTm7RUPyGfNbRwm6y2fK4wA7EB8rDJtWsq5AKi7iDr -/ip4/139.178.84.45/tcp/1347/p2p/12D3KooWECJTm7RUPyGfNbRwm6y2fK4wA7EB8rDJtWsq5AKi7iDr -/dns4/bootstrap-0-fra.fil-test.net/tcp/1347/p2p/12D3KooWC7MD6m7iNCuDsYtNr7xVtazihyVUizBbhmhEiyMAm9ym -/ip4/136.144.49.17/tcp/1347/p2p/12D3KooWC7MD6m7iNCuDsYtNr7xVtazihyVUizBbhmhEiyMAm9ym -/dns4/bootstrap-1-sin.fil-test.net/tcp/1347/p2p/12D3KooWD8eYqsKcEMFax6EbWN3rjA7qFsxCez2rmN8dWqkzgNaN -/ip4/86.109.15.55/tcp/1347/p2p/12D3KooWD8eYqsKcEMFax6EbWN3rjA7qFsxCez2rmN8dWqkzgNaN -/dns4/bootstrap-1-dfw.fil-test.net/tcp/1347/p2p/12D3KooWLB3RR8frLAmaK4ntHC2dwrAjyGzQgyUzWxAum1FxyyqD -/ip4/139.178.84.41/tcp/1347/p2p/12D3KooWLB3RR8frLAmaK4ntHC2dwrAjyGzQgyUzWxAum1FxyyqD -/dns4/bootstrap-1-fra.fil-test.net/tcp/1347/p2p/12D3KooWGPDJAw3HW4uVU3JEQBfFaZ1kdpg4HvvwRMVpUYbzhsLQ -/ip4/136.144.49.131/tcp/1347/p2p/12D3KooWGPDJAw3HW4uVU3JEQBfFaZ1kdpg4HvvwRMVpUYbzhsLQ +/dns4/bootstrap-0-sin.fil-test.net/tcp/1347/p2p/12D3KooWPdUquftaQvoQEtEdsRBAhwD6jopbF2oweVTzR59VbHEd +/ip4/86.109.15.57/tcp/1347/p2p/12D3KooWPdUquftaQvoQEtEdsRBAhwD6jopbF2oweVTzR59VbHEd +/dns4/bootstrap-0-dfw.fil-test.net/tcp/1347/p2p/12D3KooWQSCkHCzosEyrh8FgYfLejKgEPM5VB6qWzZE3yDAuXn8d +/ip4/139.178.84.45/tcp/1347/p2p/12D3KooWQSCkHCzosEyrh8FgYfLejKgEPM5VB6qWzZE3yDAuXn8d +/dns4/bootstrap-0-fra.fil-test.net/tcp/1347/p2p/12D3KooWEXN2eQmoyqnNjde9PBAQfQLHN67jcEdWU6JougWrgXJK +/ip4/136.144.49.17/tcp/1347/p2p/12D3KooWEXN2eQmoyqnNjde9PBAQfQLHN67jcEdWU6JougWrgXJK +/dns4/bootstrap-1-sin.fil-test.net/tcp/1347/p2p/12D3KooWLmJkZd33mJhjg5RrpJ6NFep9SNLXWc4uVngV4TXKwzYw +/ip4/86.109.15.123/tcp/1347/p2p/12D3KooWLmJkZd33mJhjg5RrpJ6NFep9SNLXWc4uVngV4TXKwzYw +/dns4/bootstrap-1-dfw.fil-test.net/tcp/1347/p2p/12D3KooWGXLHjiz6pTRu7x2pkgTVCoxcCiVxcNLpMnWcJ3JiNEy5 +/ip4/139.178.86.3/tcp/1347/p2p/12D3KooWGXLHjiz6pTRu7x2pkgTVCoxcCiVxcNLpMnWcJ3JiNEy5 +/dns4/bootstrap-1-fra.fil-test.net/tcp/1347/p2p/12D3KooW9szZmKttS9A1FafH3Zc2pxKwwmvCWCGKkRP4KmbhhC4R +/ip4/136.144.49.131/tcp/1347/p2p/12D3KooW9szZmKttS9A1FafH3Zc2pxKwwmvCWCGKkRP4KmbhhC4R From 2bf781d5918c8f1078e5b0aacc818d9efe04d26f Mon Sep 17 00:00:00 2001 From: Jim Pick Date: Wed, 17 Jun 2020 18:04:46 -0700 Subject: [PATCH 201/379] Fix bad link in hardware mining docs This fixes a bad link. There's also a link to the Github issue thread for results that still works, but is a bit stale (for proofs before v20). I didn't attempt to fix that as there doesn't appear to be a thread for v27 proofs. --- documentation/en/hardware-mining.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/en/hardware-mining.md b/documentation/en/hardware-mining.md index 0379cc4e1..459b6074b 100644 --- a/documentation/en/hardware-mining.md +++ b/documentation/en/hardware-mining.md @@ -51,4 +51,4 @@ To get the number of cores for your GPU, you will need to check your card’s sp ## Benchmarking -Here is a [benchmarking tool](https://github.com/filecoin-project/lotus/tree/testnet-staging/cmd/lotus-bench) and a [GitHub issue thread](https://github.com/filecoin-project/lotus/issues/694) for those who wish to experiment with and contribute hardware setups for the **Filecoin Testnet**. +Here is a [benchmarking tool](https://github.com/filecoin-project/lotus/tree/master/cmd/lotus-bench) and a [GitHub issue thread](https://github.com/filecoin-project/lotus/issues/694) for those who wish to experiment with and contribute hardware setups for the **Filecoin Testnet**. From 324b659d33fe25cb09ff59c44e19425c6b6bc9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 18 Jun 2020 09:34:28 +0200 Subject: [PATCH 202/379] Update sector-storage with 32G checkFiles fix --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dea622198..68ac9a884 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 + github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.0 github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 diff --git a/go.sum b/go.sum index dd8e57c7b..e21c27f74 100644 --- a/go.sum +++ b/go.sum @@ -253,8 +253,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= -github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 h1:cjsOpQKvZosPx9/qqq2bucHVdRyXzvBR1f37atiR3/0= -github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= +github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4 h1:lQC8Fbyn31/H4QxYAYwVV3PYZ9vS61EmjktZc5CaiYs= +github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= From 55d9ad0b550dfb16397c55c949839213600c7cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 18 Jun 2020 14:30:00 +0200 Subject: [PATCH 203/379] Fix docgen --- api/docgen/docgen.go | 37 ++++++++++++++++++++++--------------- build/params_testnet.go | 4 ++-- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 4cd982aa7..ced04e7be 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -73,9 +73,13 @@ func init() { addExample(bitfield.NewFromSet([]uint64{5})) addExample(abi.RegisteredSealProof_StackedDrg32GiBV1) + addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1) addExample(abi.ChainEpoch(10101)) addExample(crypto.SigTypeBLS) addExample(int64(9)) + addExample(12.3) + addExample(123) + addExample(uintptr(0)) addExample(abi.MethodNum(1)) addExample(exitcode.ExitCode(0)) addExample(crypto.DomainSeparationTag_ElectionProofProduction) @@ -94,17 +98,17 @@ func init() { addExample(api.PCHInbound) addExample(time.Minute) addExample(&types.ExecutionTrace{ - Msg: exampleValue(reflect.TypeOf(&types.Message{})).(*types.Message), - MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{})).(*types.MessageReceipt), + Msg: exampleValue(reflect.TypeOf(&types.Message{}), nil).(*types.Message), + MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt), }) addExample(map[string]types.Actor{ - "t01236": exampleValue(reflect.TypeOf(types.Actor{})).(types.Actor), + "t01236": exampleValue(reflect.TypeOf(types.Actor{}), nil).(types.Actor), }) addExample(map[string]api.MarketDeal{ - "t026363": exampleValue(reflect.TypeOf(api.MarketDeal{})).(api.MarketDeal), + "t026363": exampleValue(reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal), }) addExample(map[string]api.MarketBalance{ - "t026363": exampleValue(reflect.TypeOf(api.MarketBalance{})).(api.MarketBalance), + "t026363": exampleValue(reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance), }) maddr, err := multiaddr.NewMultiaddr("/ip4/52.36.61.156/tcp/1347/p2p/12D3KooWFETiESTf1v4PGUvtnxMAcEFMzLZbJGg4tjWfGEimYior") @@ -117,7 +121,7 @@ func init() { } -func exampleValue(t reflect.Type) interface{} { +func exampleValue(t, parent reflect.Type) interface{} { v, ok := ExampleValues[t] if ok { return v @@ -126,25 +130,25 @@ func exampleValue(t reflect.Type) interface{} { switch t.Kind() { case reflect.Slice: out := reflect.New(t).Elem() - reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem()))) + reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem(), t))) return out.Interface() case reflect.Chan: - return exampleValue(t.Elem()) + return exampleValue(t.Elem(), nil) case reflect.Struct: - es := exampleStruct(t) + es := exampleStruct(t, parent) v := reflect.ValueOf(es).Elem().Interface() ExampleValues[t] = v return v case reflect.Array: out := reflect.New(t).Elem() for i := 0; i < t.Len(); i++ { - out.Index(i).Set(reflect.ValueOf(exampleValue(t.Elem()))) + out.Index(i).Set(reflect.ValueOf(exampleValue(t.Elem(), t))) } return out.Interface() case reflect.Ptr: if t.Elem().Kind() == reflect.Struct { - es := exampleStruct(t.Elem()) + es := exampleStruct(t.Elem(), t) //ExampleValues[t] = es return es } @@ -155,12 +159,15 @@ func exampleValue(t reflect.Type) interface{} { panic(fmt.Sprintf("No example value for type: %s", t)) } -func exampleStruct(t reflect.Type) interface{} { +func exampleStruct(t, parent reflect.Type) interface{} { ns := reflect.New(t) for i := 0; i < t.NumField(); i++ { f := t.Field(i) + if f.Type == parent { + continue + } if strings.Title(f.Name) == f.Name { - ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(f.Type))) + ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(f.Type, t))) } } @@ -286,7 +293,7 @@ func main() { ft := m.Func.Type() for j := 2; j < ft.NumIn(); j++ { inp := ft.In(j) - args = append(args, exampleValue(inp)) + args = append(args, exampleValue(inp, nil)) } v, err := json.Marshal(args) @@ -294,7 +301,7 @@ func main() { panic(err) } - outv := exampleValue(ft.Out(0)) + outv := exampleValue(ft.Out(0), nil) ov, err := json.Marshal(outv) if err != nil { diff --git a/build/params_testnet.go b/build/params_testnet.go index 202dfb231..69884f3f8 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -14,8 +14,8 @@ import ( func init() { power.ConsensusMinerMinPower = big.NewInt(1024 << 30) miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ - abi.RegisteredSealProof_StackedDrg32GiBV1: {}, - abi.RegisteredSealProof_StackedDrg64GiBV1: {}, + abi.RegisteredSealProof_StackedDrg32GiBV1: {}, + abi.RegisteredSealProof_StackedDrg64GiBV1: {}, } } From 90fbbea3727659b604bfd7ca6cf1c57c84026c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 18 Jun 2020 14:37:36 +0200 Subject: [PATCH 204/379] docgen: Make larger inputs/outputs more readable --- api/docgen/docgen.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index ced04e7be..39892c820 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -296,14 +296,14 @@ func main() { args = append(args, exampleValue(inp, nil)) } - v, err := json.Marshal(args) + v, err := json.MarshalIndent(args, "", " ") if err != nil { panic(err) } outv := exampleValue(ft.Out(0), nil) - ov, err := json.Marshal(outv) + ov, err := json.MarshalIndent(outv, "", " ") if err != nil { panic(err) } @@ -338,8 +338,17 @@ func main() { fmt.Printf("### %s\n", m.Name) fmt.Printf("%s\n\n", m.Comment) - fmt.Printf("Inputs: `%s`\n\n", m.InputExample) - fmt.Printf("Response: `%s`\n\n", m.ResponseExample) + if strings.Count(m.InputExample, "\n") > 0 { + fmt.Printf("Inputs:\n```json\n%s\n```\n\n", m.InputExample) + } else { + fmt.Printf("Inputs: `%s`\n\n", m.InputExample) + } + + if strings.Count(m.ResponseExample, "\n") > 0 { + fmt.Printf("Response:\n```json\n%s\n```\n\n", m.ResponseExample) + } else { + fmt.Printf("Response: `%s`\n\n", m.ResponseExample) + } } } } From 382734b057888fb02d7fd3039eb90b53d631a722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 18 Jun 2020 14:56:00 +0200 Subject: [PATCH 205/379] docgen: Generate simple index --- api/api_common.go | 8 ++++++-- api/docgen/docgen.go | 9 +++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/api/api_common.go b/api/api_common.go index 6d47e35f7..aa63e9815 100644 --- a/api/api_common.go +++ b/api/api_common.go @@ -13,11 +13,13 @@ import ( ) type Common interface { - // Auth + + // MethodGroup: Auth + AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) - // network + // MethodGroup: Net NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) NetPeers(context.Context) ([]peer.AddrInfo, error) @@ -27,6 +29,8 @@ type Common interface { NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error) NetPubsubScores(context.Context) ([]PubsubScore, error) + // MethodGroup: Common + // ID returns peerID of libp2p node backing this API ID(context.Context) (peer.ID, error) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 39892c820..f876e280e 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -325,6 +325,15 @@ func main() { return groupslice[i].GroupName < groupslice[j].GroupName }) + fmt.Printf("# Groups\n") + + for _, g := range groupslice { + fmt.Printf("* [%s](#%s)\n", g.GroupName, g.GroupName) + for _, method := range g.Methods { + fmt.Printf(" * [%s](#%s)\n", method.Name, method.Name) + } + } + for _, g := range groupslice { g := g fmt.Printf("## %s\n", g.GroupName) From c0a50a21432b8d82b71ae173137d2d096532b55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 18 Jun 2020 15:44:47 +0200 Subject: [PATCH 206/379] api: Add a bunch of donstrings --- api/api_full.go | 77 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index bbd28b39e..17b0fdce6 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -35,26 +35,71 @@ type FullNode interface { // ChainNotify returns channel with chain head updates // First message is guaranteed to be of len == 1, and type == 'current' ChainNotify(context.Context) (<-chan []*HeadChange, error) + // ChainHead returns the current head of the chain ChainHead(context.Context) (*types.TipSet, error) + // ChainGetRandomness is used to sample the chain for randomness ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) + // ChainGetBlock returns the block specified by the given CID ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) - ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error) - ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error) - ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error) + + // ChainGetBlockMessages returns messages stored in the specified block + ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*BlockMessages, error) + + // ChainGetParentReceipts returns receipts for messages in parent tipset of + // the specified block + ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error) + + // ChainGetParentReceipts returns messages stored in parent tipset of the + // specified block + ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]Message, error) + + // ChainGetTipSetByHeight looks back for a tipset at the specified epoch. + // If there are no blocks at the specified epoch, a tipset at higher epoch + // will be returned ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) + + // ChainReadObj reads ipld nodes referenced by the specified CID from chain + // blockstore and returns raw bytes ChainReadObj(context.Context, cid.Cid) ([]byte, error) + + // ChainHasObj checks if a given CID exists in the chain blockstore ChainHasObj(context.Context, cid.Cid) (bool, error) ChainStatObj(context.Context, cid.Cid, cid.Cid) (ObjStat, error) + + // ChainSetHead forcefully sets current chain head. Use with caution ChainSetHead(context.Context, types.TipSetKey) error + + // ChainGetGenesis returns the genesis tipset ChainGetGenesis(context.Context) (*types.TipSet, error) + + // ChainTipSetWeight computes weight for the specified tipset ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error) ChainGetNode(ctx context.Context, p string) (*IpldObject, error) + + // ChainGetMessage reads a message referenced by the specified CID from the + // chain blockstore ChainGetMessage(context.Context, cid.Cid) (*types.Message, error) + + // ChainGetPath returns a set of revert/apply operations needed to get from + // one tipset to another, for example: + //``` + // to + // ^ + // from tAA + // ^ ^ + // tBA tAB + // ^---*--^ + // ^ + // tRR + //``` + // Would return `[revert(tBA), apply(tAB), apply(tAA)]` ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error) + + // ChainExport returns a stream of bytes with CAR dump of chain data ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error) // MethodGroup: Sync @@ -63,23 +108,45 @@ type FullNode interface { // SyncState returns the current status of the lotus sync system SyncState(context.Context) (*SyncState, error) + // SyncSubmitBlock can be used to submit a newly created block to the // network through this node SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error + + // SyncIncomingBlocks returns a channel streaming incoming, potentially not + // yet synced block headers. SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) + + // SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced. + // Use with extreme caution SyncMarkBad(ctx context.Context, bcid cid.Cid) error + + // SyncCheckBad checks if a block was marked as bad, and if it was, returns + // the reason SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) // MethodGroup: Mpool // The Mpool methods are for interacting with the message pool. The message pool // manages all incoming and outgoing 'messages' going over the network. + // MpoolPending returns pending mempool messages MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) + + // MpoolPush pushes a signed message to mempool MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error) - MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push + + // MpoolPushMessage atomically assigns a nonce, signs, and pushes a message + // to mempool + MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) + + // MpoolGetNonce gets next nonce for the specified sender. + // Note that this method may not be atomic. Use MpoolPushMessage instead MpoolGetNonce(context.Context, address.Address) (uint64, error) MpoolSub(context.Context) (<-chan MpoolUpdate, error) - MpoolEstimateGasPrice(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error) + + // MpoolEstimateGasPrice estimates what gas price should be used for a + // message to have high likelihood of inclusion in `nblocksincl` epochs + MpoolEstimateGasPrice(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) // MethodGroup: Miner From 997a46a90f02db165a86dab0025ae71fe23afe6e Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 18 Jun 2020 10:32:32 -0700 Subject: [PATCH 207/379] wombat --- cmd/lotus-storage-miner/market.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 4dac236e4..cb49854cd 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -140,6 +140,8 @@ var getAskCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := lcli.DaemonContext(cctx) + fmt.Println("wombat") + fnapi, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err From b0edf924b429a99e25312dd0ee133b55561190fc Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 18 Jun 2020 13:15:18 -0700 Subject: [PATCH 208/379] add commands for manipulating storage deal CID blacklist --- api/api_storage.go | 2 + api/apistruct/struct.go | 10 +++ cmd/lotus-storage-miner/market.go | 126 ++++++++++++++++++++++++++++++ node/builder.go | 2 + node/config/def.go | 4 + node/impl/storminer.go | 12 ++- node/modules/dtypes/miner.go | 11 +++ node/modules/storageminer.go | 83 ++++++++++++++------ 8 files changed, 225 insertions(+), 25 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 90de01fb9..0eda830dc 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -56,6 +56,8 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) DealsSetAcceptingStorageDeals(context.Context, bool) error + DealsBlacklist(context.Context) ([]cid.Cid, error) + DealsSetBlacklist(context.Context, []cid.Cid) error StorageAddLocal(ctx context.Context, path string) error } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 0d69174ab..43c0a423e 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -226,6 +226,8 @@ type StorageMinerStruct struct { DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsBlacklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` + DealsSetBlacklist func(context.Context, []cid.Cid) error `perm:"read"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -872,6 +874,14 @@ func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, return c.Internal.DealsSetAcceptingStorageDeals(ctx, b) } +func (c *StorageMinerStruct) DealsBlacklist(ctx context.Context) ([]cid.Cid, error) { + return c.Internal.DealsBlacklist(ctx) +} + +func (c *StorageMinerStruct) DealsSetBlacklist(ctx context.Context, cids []cid.Cid) error { + return c.Internal.DealsSetBlacklist(ctx, cids) +} + func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error { return c.Internal.StorageAddLocal(ctx, path) } diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index cb49854cd..f12bce62c 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -1,14 +1,18 @@ package main import ( + "bufio" "encoding/json" "fmt" "os" + "path/filepath" "text/tabwriter" "time" "github.com/docker/go-units" "github.com/ipfs/go-cid" + "github.com/ipfs/go-cidutil/cidenc" + "github.com/multiformats/go-multibase" "github.com/urfave/cli/v2" "golang.org/x/xerrors" @@ -20,6 +24,32 @@ import ( lcli "github.com/filecoin-project/lotus/cli" ) +var CidBaseFlag = cli.StringFlag{ + Name: "cid-base", + Hidden: true, + Value: "base32", + Usage: "Multibase encoding used for version 1 CIDs in output.", + DefaultText: "base32", +} + +// GetCidEncoder returns an encoder using the `cid-base` flag if provided, or +// the default (Base32) encoder if not. +func GetCidEncoder(cctx *cli.Context) (cidenc.Encoder, error) { + val := cctx.String("cid-base") + + e := cidenc.Encoder{Base: multibase.MustNewEncoder(multibase.Base32)} + + if val != "" { + var err error + e.Base, err = multibase.EncoderByName(val) + if err != nil { + return e, err + } + } + + return e, nil +} + var enableCmd = &cli.Command{ Name: "enable", Usage: "Configure the miner to consider storage deal proposals", @@ -199,6 +229,9 @@ var dealsCmd = &cli.Command{ disableCmd, setAskCmd, getAskCmd, + setBlacklistCmd, + getBlacklistCmd, + resetBlacklistCmd, }, } @@ -257,3 +290,96 @@ var dealsListCmd = &cli.Command{ return nil }, } + +var getBlacklistCmd = &cli.Command{ + Name: "get-blacklist", + Usage: "List the CIDs in the storage miner's blacklist", + Flags: []cli.Flag{ + &CidBaseFlag, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + blacklist, err := api.DealsBlacklist(lcli.DaemonContext(cctx)) + if err != nil { + return err + } + + encoder, err := GetCidEncoder(cctx) + if err != nil { + return err + } + + for idx := range blacklist { + fmt.Println(encoder.Encode(blacklist[idx])) + } + + return nil + }, +} + +var setBlacklistCmd = &cli.Command{ + Name: "set-blacklist", + Usage: "Set the storage miner's list of blacklisted CIDs", + ArgsUsage: "[ (optional, will read from stdin if omitted)]", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + scanner := bufio.NewScanner(os.Stdin) + if cctx.Args().Present() && cctx.Args().First() != "-" { + absPath, err := filepath.Abs(cctx.Args().First()) + if err != nil { + return err + } + + file, err := os.Open(absPath) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + scanner = bufio.NewScanner(file) + } + + var blacklist []cid.Cid + for scanner.Scan() { + decoded, err := cid.Decode(scanner.Text()) + if err != nil { + return err + } + + blacklist = append(blacklist, decoded) + } + + err = scanner.Err() + if err != nil { + return err + } + + return api.DealsSetBlacklist(lcli.DaemonContext(cctx), blacklist) + }, +} + +var resetBlacklistCmd = &cli.Command{ + Name: "reset-blacklist", + Usage: "Remove all entries from the storage miner's blacklist", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + return api.DealsSetBlacklist(lcli.DaemonContext(cctx), []cid.Cid{}) + }, +} diff --git a/node/builder.go b/node/builder.go index 536d81901..52e089bbe 100644 --- a/node/builder.go +++ b/node/builder.go @@ -314,6 +314,8 @@ func Online() Option { Override(new(dtypes.AcceptingStorageDealsConfigFunc), modules.NewAcceptingStorageDealsConfigFunc), Override(new(dtypes.SetAcceptingStorageDealsConfigFunc), modules.NewSetAcceptingStorageDealsConfigFunc), + Override(new(dtypes.StorageDealCidBlacklistConfigFunc), modules.NewStorageDealCidBlacklistConfigFunc), + Override(new(dtypes.SetStorageDealCidBlacklistConfigFunc), modules.NewSetStorageDealCidBlacklistConfigFunc), ), ) } diff --git a/node/config/def.go b/node/config/def.go index 5c46f77a4..b92ac3b4d 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -4,6 +4,8 @@ import ( "encoding" "time" + "github.com/ipfs/go-cid" + sectorstorage "github.com/filecoin-project/sector-storage" ) @@ -33,6 +35,7 @@ type StorageMiner struct { type DealmakingConfig struct { AcceptingStorageDeals bool + Blacklist []cid.Cid } // API contains configs for API endpoint @@ -121,6 +124,7 @@ func DefaultStorageMiner() *StorageMiner { Dealmaking: DealmakingConfig{ AcceptingStorageDeals: true, + Blacklist: []cid.Cid{}, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/impl/storminer.go b/node/impl/storminer.go index ed94e173d..2863a9d28 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -43,7 +43,9 @@ type StorageMinerAPI struct { StorageMgr *sectorstorage.Manager `optional:"true"` *stores.Index - SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc + SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc + StorageDealCidBlacklistConfigFunc dtypes.StorageDealCidBlacklistConfigFunc + SetStorageDealCidBlacklistConfigFunc dtypes.SetStorageDealCidBlacklistConfigFunc } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { @@ -232,6 +234,14 @@ func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fn return sm.StorageProvider.ImportDataForDeal(ctx, deal, fi) } +func (sm *StorageMinerAPI) DealsBlacklist(ctx context.Context) ([]cid.Cid, error) { + return sm.StorageDealCidBlacklistConfigFunc() +} + +func (sm *StorageMinerAPI) DealsSetBlacklist(ctx context.Context, cids []cid.Cid) error { + return sm.SetStorageDealCidBlacklistConfigFunc(cids) +} + func (sm *StorageMinerAPI) StorageAddLocal(ctx context.Context, path string) error { if sm.StorageMgr == nil { return xerrors.Errorf("no storage manager") diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 5c761d3e5..04ae07a53 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -1,6 +1,8 @@ package dtypes import ( + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" ) @@ -15,3 +17,12 @@ type AcceptingStorageDealsConfigFunc func() (bool, error) // SetAcceptingStorageDealsFunc is a function which is used to disable or enable // storage deal acceptance. type SetAcceptingStorageDealsConfigFunc func(bool) error + +// StorageDealCidBlacklistConfigFunc is a function which reads from miner config +// to obtain a list of CIDs for which the storage miner will not accept storage +// proposals. +type StorageDealCidBlacklistConfigFunc func() ([]cid.Cid, error) + +// SetStorageDealCidBlacklistConfigFunc is a function which is used to set a +// list of CIDs for which the storage miner will reject deal proposals. +type SetStorageDealCidBlacklistConfigFunc func([]cid.Cid) error diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index fce9f9e1f..a6ef6304e 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -8,6 +8,7 @@ import ( "github.com/ipfs/go-bitswap" "github.com/ipfs/go-bitswap/network" "github.com/ipfs/go-blockservice" + "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" graphsync "github.com/ipfs/go-graphsync/impl" @@ -380,35 +381,69 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA } func NewAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.AcceptingStorageDealsConfigFunc, error) { - return func() (bool, error) { - raw, err := r.Config() - if err != nil { - return false, err - } - - cfg, ok := raw.(*config.StorageMiner) - if !ok { - return false, xerrors.New("expected address of config.StorageMiner") - } - - return cfg.Dealmaking.AcceptingStorageDeals, nil + return func() (out bool, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.AcceptingStorageDeals + }) + return }, nil } func NewSetAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.SetAcceptingStorageDealsConfigFunc, error) { - return func(b bool) error { - var typeErr error - - setConfigErr := r.SetConfig(func(raw interface{}) { - cfg, ok := raw.(*config.StorageMiner) - if !ok { - typeErr = errors.New("expected storage miner config") - return - } - + return func(b bool) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { cfg.Dealmaking.AcceptingStorageDeals = b }) - - return multierr.Combine(typeErr, setConfigErr) + return }, nil } + +func NewStorageDealCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.StorageDealCidBlacklistConfigFunc, error) { + return func() (out []cid.Cid, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.Blacklist + }) + return + }, nil +} + +func NewSetStorageDealCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.SetStorageDealCidBlacklistConfigFunc, error) { + return func(blacklist []cid.Cid) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.Blacklist = blacklist + }) + return + }, nil +} + +func readCfg(r repo.LockedRepo, accessor func(*config.StorageMiner)) error { + raw, err := r.Config() + if err != nil { + return err + } + + cfg, ok := raw.(*config.StorageMiner) + if !ok { + return xerrors.New("expected address of config.StorageMiner") + } + + accessor(cfg) + + return nil +} + +func mutateCfg(r repo.LockedRepo, mutator func(*config.StorageMiner)) error { + var typeErr error + + setConfigErr := r.SetConfig(func(raw interface{}) { + cfg, ok := raw.(*config.StorageMiner) + if !ok { + typeErr = errors.New("expected storage miner config") + return + } + + mutator(cfg) + }) + + return multierr.Combine(typeErr, setConfigErr) +} From aa18d1985e6835a0b4ea7d3b08913064ea82e9ee Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 18 Jun 2020 13:32:20 -0700 Subject: [PATCH 209/379] reject storage deal proposals containing blacklisted piece CIDs --- node/modules/storageminer.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index a6ef6304e..49893c494 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -3,6 +3,7 @@ package modules import ( "context" "errors" + "fmt" "net/http" "github.com/ipfs/go-bitswap" @@ -308,7 +309,7 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return storedAsk, nil } -func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc) (storagemarket.StorageProvider, error) { +func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc, blacklistFunc dtypes.StorageDealCidBlacklistConfigFunc) (storagemarket.StorageProvider, error) { net := smnet.NewFromLibp2pHost(h) store, err := piecefilestore.NewLocalFileStore(piecefilestore.OsPath(r.Path())) if err != nil { @@ -326,6 +327,18 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con return false, "miner is not accepting storage deals", nil } + blacklist, err := blacklistFunc() + if err != nil { + return false, "miner error", err + } + + for idx := range blacklist { + if deal.Proposal.PieceCID.Equals(blacklist[idx]) { + log.Warnf("piece CID in proposal %s is blacklisted; rejecting storage deal proposal from client: %s", deal.Proposal.PieceCID, deal.Client.String()) + return false, fmt.Sprintf("miner has blacklisted piece CID %s", deal.Proposal.PieceCID), nil + } + } + return true, "", nil }) From 0c8d6489980d2ae2d3630ab33e371c47739eb9a2 Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 18 Jun 2020 13:36:48 -0700 Subject: [PATCH 210/379] specify which CID is being blacklisted (it's the piece) --- api/api_storage.go | 4 ++-- api/apistruct/struct.go | 12 ++++++------ cmd/lotus-storage-miner/market.go | 14 +++++++------- node/builder.go | 4 ++-- node/config/def.go | 4 ++-- node/impl/storminer.go | 14 +++++++------- node/modules/dtypes/miner.go | 4 ++-- node/modules/storageminer.go | 10 +++++----- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 0eda830dc..afc25f1c5 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -56,8 +56,8 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) DealsSetAcceptingStorageDeals(context.Context, bool) error - DealsBlacklist(context.Context) ([]cid.Cid, error) - DealsSetBlacklist(context.Context, []cid.Cid) error + DealsPieceCidBlacklist(context.Context) ([]cid.Cid, error) + DealsSetPieceCidBlacklist(context.Context, []cid.Cid) error StorageAddLocal(ctx context.Context, path string) error } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 43c0a423e..3d2375c87 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -226,8 +226,8 @@ type StorageMinerStruct struct { DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsBlacklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` - DealsSetBlacklist func(context.Context, []cid.Cid) error `perm:"read"` + DealsPieceCidBlacklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` + DealsSetPieceCidBlacklist func(context.Context, []cid.Cid) error `perm:"read"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -874,12 +874,12 @@ func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, return c.Internal.DealsSetAcceptingStorageDeals(ctx, b) } -func (c *StorageMinerStruct) DealsBlacklist(ctx context.Context) ([]cid.Cid, error) { - return c.Internal.DealsBlacklist(ctx) +func (c *StorageMinerStruct) DealsPieceCidBlacklist(ctx context.Context) ([]cid.Cid, error) { + return c.Internal.DealsPieceCidBlacklist(ctx) } -func (c *StorageMinerStruct) DealsSetBlacklist(ctx context.Context, cids []cid.Cid) error { - return c.Internal.DealsSetBlacklist(ctx, cids) +func (c *StorageMinerStruct) DealsSetPieceCidBlacklist(ctx context.Context, cids []cid.Cid) error { + return c.Internal.DealsSetPieceCidBlacklist(ctx, cids) } func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error { diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index f12bce62c..1f7b84371 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -293,7 +293,7 @@ var dealsListCmd = &cli.Command{ var getBlacklistCmd = &cli.Command{ Name: "get-blacklist", - Usage: "List the CIDs in the storage miner's blacklist", + Usage: "List the contents of the storage miner's piece CID blacklist", Flags: []cli.Flag{ &CidBaseFlag, }, @@ -304,7 +304,7 @@ var getBlacklistCmd = &cli.Command{ } defer closer() - blacklist, err := api.DealsBlacklist(lcli.DaemonContext(cctx)) + blacklist, err := api.DealsPieceCidBlacklist(lcli.DaemonContext(cctx)) if err != nil { return err } @@ -324,8 +324,8 @@ var getBlacklistCmd = &cli.Command{ var setBlacklistCmd = &cli.Command{ Name: "set-blacklist", - Usage: "Set the storage miner's list of blacklisted CIDs", - ArgsUsage: "[ (optional, will read from stdin if omitted)]", + Usage: "Set the storage miner's list of blacklisted piece CIDs", + ArgsUsage: "[ (optional, will read from stdin if omitted)]", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { api, closer, err := lcli.GetStorageMinerAPI(cctx) @@ -365,13 +365,13 @@ var setBlacklistCmd = &cli.Command{ return err } - return api.DealsSetBlacklist(lcli.DaemonContext(cctx), blacklist) + return api.DealsSetPieceCidBlacklist(lcli.DaemonContext(cctx), blacklist) }, } var resetBlacklistCmd = &cli.Command{ Name: "reset-blacklist", - Usage: "Remove all entries from the storage miner's blacklist", + Usage: "Remove all entries from the storage miner's piece CID blacklist", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { api, closer, err := lcli.GetStorageMinerAPI(cctx) @@ -380,6 +380,6 @@ var resetBlacklistCmd = &cli.Command{ } defer closer() - return api.DealsSetBlacklist(lcli.DaemonContext(cctx), []cid.Cid{}) + return api.DealsSetPieceCidBlacklist(lcli.DaemonContext(cctx), []cid.Cid{}) }, } diff --git a/node/builder.go b/node/builder.go index 52e089bbe..bf32089e0 100644 --- a/node/builder.go +++ b/node/builder.go @@ -314,8 +314,8 @@ func Online() Option { Override(new(dtypes.AcceptingStorageDealsConfigFunc), modules.NewAcceptingStorageDealsConfigFunc), Override(new(dtypes.SetAcceptingStorageDealsConfigFunc), modules.NewSetAcceptingStorageDealsConfigFunc), - Override(new(dtypes.StorageDealCidBlacklistConfigFunc), modules.NewStorageDealCidBlacklistConfigFunc), - Override(new(dtypes.SetStorageDealCidBlacklistConfigFunc), modules.NewSetStorageDealCidBlacklistConfigFunc), + Override(new(dtypes.StorageDealPieceCidBlacklistConfigFunc), modules.NewStorageDealPieceCidBlacklistConfigFunc), + Override(new(dtypes.SetStorageDealPieceCidBlacklistConfigFunc), modules.NewSetStorageDealPieceCidBlacklistConfigFunc), ), ) } diff --git a/node/config/def.go b/node/config/def.go index b92ac3b4d..f9928ed3f 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -35,7 +35,7 @@ type StorageMiner struct { type DealmakingConfig struct { AcceptingStorageDeals bool - Blacklist []cid.Cid + PieceCidBlacklist []cid.Cid } // API contains configs for API endpoint @@ -124,7 +124,7 @@ func DefaultStorageMiner() *StorageMiner { Dealmaking: DealmakingConfig{ AcceptingStorageDeals: true, - Blacklist: []cid.Cid{}, + PieceCidBlacklist: []cid.Cid{}, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 2863a9d28..6eba12501 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -43,9 +43,9 @@ type StorageMinerAPI struct { StorageMgr *sectorstorage.Manager `optional:"true"` *stores.Index - SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc - StorageDealCidBlacklistConfigFunc dtypes.StorageDealCidBlacklistConfigFunc - SetStorageDealCidBlacklistConfigFunc dtypes.SetStorageDealCidBlacklistConfigFunc + SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc + StorageDealPieceCidBlacklistConfigFunc dtypes.StorageDealPieceCidBlacklistConfigFunc + SetStorageDealPieceCidBlacklistConfigFunc dtypes.SetStorageDealPieceCidBlacklistConfigFunc } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { @@ -234,12 +234,12 @@ func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fn return sm.StorageProvider.ImportDataForDeal(ctx, deal, fi) } -func (sm *StorageMinerAPI) DealsBlacklist(ctx context.Context) ([]cid.Cid, error) { - return sm.StorageDealCidBlacklistConfigFunc() +func (sm *StorageMinerAPI) DealsPieceCidBlacklist(ctx context.Context) ([]cid.Cid, error) { + return sm.StorageDealPieceCidBlacklistConfigFunc() } -func (sm *StorageMinerAPI) DealsSetBlacklist(ctx context.Context, cids []cid.Cid) error { - return sm.SetStorageDealCidBlacklistConfigFunc(cids) +func (sm *StorageMinerAPI) DealsSetPieceCidBlacklist(ctx context.Context, cids []cid.Cid) error { + return sm.SetStorageDealPieceCidBlacklistConfigFunc(cids) } func (sm *StorageMinerAPI) StorageAddLocal(ctx context.Context, path string) error { diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 04ae07a53..a9d278ca4 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -21,8 +21,8 @@ type SetAcceptingStorageDealsConfigFunc func(bool) error // StorageDealCidBlacklistConfigFunc is a function which reads from miner config // to obtain a list of CIDs for which the storage miner will not accept storage // proposals. -type StorageDealCidBlacklistConfigFunc func() ([]cid.Cid, error) +type StorageDealPieceCidBlacklistConfigFunc func() ([]cid.Cid, error) // SetStorageDealCidBlacklistConfigFunc is a function which is used to set a // list of CIDs for which the storage miner will reject deal proposals. -type SetStorageDealCidBlacklistConfigFunc func([]cid.Cid) error +type SetStorageDealPieceCidBlacklistConfigFunc func([]cid.Cid) error diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 49893c494..73e062c9c 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -309,7 +309,7 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return storedAsk, nil } -func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc, blacklistFunc dtypes.StorageDealCidBlacklistConfigFunc) (storagemarket.StorageProvider, error) { +func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc, blacklistFunc dtypes.StorageDealPieceCidBlacklistConfigFunc) (storagemarket.StorageProvider, error) { net := smnet.NewFromLibp2pHost(h) store, err := piecefilestore.NewLocalFileStore(piecefilestore.OsPath(r.Path())) if err != nil { @@ -411,19 +411,19 @@ func NewSetAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.SetAccepti }, nil } -func NewStorageDealCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.StorageDealCidBlacklistConfigFunc, error) { +func NewStorageDealPieceCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.StorageDealPieceCidBlacklistConfigFunc, error) { return func() (out []cid.Cid, err error) { err = readCfg(r, func(cfg *config.StorageMiner) { - out = cfg.Dealmaking.Blacklist + out = cfg.Dealmaking.PieceCidBlacklist }) return }, nil } -func NewSetStorageDealCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.SetStorageDealCidBlacklistConfigFunc, error) { +func NewSetStorageDealPieceCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.SetStorageDealPieceCidBlacklistConfigFunc, error) { return func(blacklist []cid.Cid) (err error) { err = mutateCfg(r, func(cfg *config.StorageMiner) { - cfg.Dealmaking.Blacklist = blacklist + cfg.Dealmaking.PieceCidBlacklist = blacklist }) return }, nil From 99060fbb64f6f14e98e3545b71f344f3e740d133 Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 18 Jun 2020 14:05:59 -0700 Subject: [PATCH 211/379] eliminate errant debug line --- cmd/lotus-storage-miner/market.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 1f7b84371..e27bf6081 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -170,8 +170,6 @@ var getAskCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := lcli.DaemonContext(cctx) - fmt.Println("wombat") - fnapi, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err From de7d6c255c00c180860279a6252cb8f4a1fb245e Mon Sep 17 00:00:00 2001 From: laser Date: Thu, 18 Jun 2020 15:42:24 -0700 Subject: [PATCH 212/379] blacklist -> blocklist --- api/api_storage.go | 4 ++-- api/apistruct/struct.go | 12 +++++----- cmd/lotus-storage-miner/market.go | 38 +++++++++++++++---------------- node/builder.go | 4 ++-- node/config/def.go | 4 ++-- node/impl/storminer.go | 12 +++++----- node/modules/dtypes/miner.go | 8 +++---- node/modules/storageminer.go | 22 +++++++++--------- 8 files changed, 52 insertions(+), 52 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index afc25f1c5..29ae5ea2e 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -56,8 +56,8 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) DealsSetAcceptingStorageDeals(context.Context, bool) error - DealsPieceCidBlacklist(context.Context) ([]cid.Cid, error) - DealsSetPieceCidBlacklist(context.Context, []cid.Cid) error + DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error) + DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error StorageAddLocal(ctx context.Context, path string) error } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 3d2375c87..fb11cbda2 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -226,8 +226,8 @@ type StorageMinerStruct struct { DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsPieceCidBlacklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` - DealsSetPieceCidBlacklist func(context.Context, []cid.Cid) error `perm:"read"` + DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` + DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -874,12 +874,12 @@ func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, return c.Internal.DealsSetAcceptingStorageDeals(ctx, b) } -func (c *StorageMinerStruct) DealsPieceCidBlacklist(ctx context.Context) ([]cid.Cid, error) { - return c.Internal.DealsPieceCidBlacklist(ctx) +func (c *StorageMinerStruct) DealsPieceCidBlocklist(ctx context.Context) ([]cid.Cid, error) { + return c.Internal.DealsPieceCidBlocklist(ctx) } -func (c *StorageMinerStruct) DealsSetPieceCidBlacklist(ctx context.Context, cids []cid.Cid) error { - return c.Internal.DealsSetPieceCidBlacklist(ctx, cids) +func (c *StorageMinerStruct) DealsSetPieceCidBlocklist(ctx context.Context, cids []cid.Cid) error { + return c.Internal.DealsSetPieceCidBlocklist(ctx, cids) } func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error { diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index e27bf6081..110411bc6 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -227,9 +227,9 @@ var dealsCmd = &cli.Command{ disableCmd, setAskCmd, getAskCmd, - setBlacklistCmd, - getBlacklistCmd, - resetBlacklistCmd, + setBlocklistCmd, + getBlocklistCmd, + resetBlocklistCmd, }, } @@ -289,9 +289,9 @@ var dealsListCmd = &cli.Command{ }, } -var getBlacklistCmd = &cli.Command{ - Name: "get-blacklist", - Usage: "List the contents of the storage miner's piece CID blacklist", +var getBlocklistCmd = &cli.Command{ + Name: "get-blocklist", + Usage: "List the contents of the storage miner's piece CID blocklist", Flags: []cli.Flag{ &CidBaseFlag, }, @@ -302,7 +302,7 @@ var getBlacklistCmd = &cli.Command{ } defer closer() - blacklist, err := api.DealsPieceCidBlacklist(lcli.DaemonContext(cctx)) + blocklist, err := api.DealsPieceCidBlocklist(lcli.DaemonContext(cctx)) if err != nil { return err } @@ -312,17 +312,17 @@ var getBlacklistCmd = &cli.Command{ return err } - for idx := range blacklist { - fmt.Println(encoder.Encode(blacklist[idx])) + for idx := range blocklist { + fmt.Println(encoder.Encode(blocklist[idx])) } return nil }, } -var setBlacklistCmd = &cli.Command{ - Name: "set-blacklist", - Usage: "Set the storage miner's list of blacklisted piece CIDs", +var setBlocklistCmd = &cli.Command{ + Name: "set-blocklist", + Usage: "Set the storage miner's list of blocklisted piece CIDs", ArgsUsage: "[ (optional, will read from stdin if omitted)]", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { @@ -348,14 +348,14 @@ var setBlacklistCmd = &cli.Command{ scanner = bufio.NewScanner(file) } - var blacklist []cid.Cid + var blocklist []cid.Cid for scanner.Scan() { decoded, err := cid.Decode(scanner.Text()) if err != nil { return err } - blacklist = append(blacklist, decoded) + blocklist = append(blocklist, decoded) } err = scanner.Err() @@ -363,13 +363,13 @@ var setBlacklistCmd = &cli.Command{ return err } - return api.DealsSetPieceCidBlacklist(lcli.DaemonContext(cctx), blacklist) + return api.DealsSetPieceCidBlocklist(lcli.DaemonContext(cctx), blocklist) }, } -var resetBlacklistCmd = &cli.Command{ - Name: "reset-blacklist", - Usage: "Remove all entries from the storage miner's piece CID blacklist", +var resetBlocklistCmd = &cli.Command{ + Name: "reset-blocklist", + Usage: "Remove all entries from the storage miner's piece CID blocklist", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { api, closer, err := lcli.GetStorageMinerAPI(cctx) @@ -378,6 +378,6 @@ var resetBlacklistCmd = &cli.Command{ } defer closer() - return api.DealsSetPieceCidBlacklist(lcli.DaemonContext(cctx), []cid.Cid{}) + return api.DealsSetPieceCidBlocklist(lcli.DaemonContext(cctx), []cid.Cid{}) }, } diff --git a/node/builder.go b/node/builder.go index bf32089e0..e84c4422c 100644 --- a/node/builder.go +++ b/node/builder.go @@ -314,8 +314,8 @@ func Online() Option { Override(new(dtypes.AcceptingStorageDealsConfigFunc), modules.NewAcceptingStorageDealsConfigFunc), Override(new(dtypes.SetAcceptingStorageDealsConfigFunc), modules.NewSetAcceptingStorageDealsConfigFunc), - Override(new(dtypes.StorageDealPieceCidBlacklistConfigFunc), modules.NewStorageDealPieceCidBlacklistConfigFunc), - Override(new(dtypes.SetStorageDealPieceCidBlacklistConfigFunc), modules.NewSetStorageDealPieceCidBlacklistConfigFunc), + Override(new(dtypes.StorageDealPieceCidBlocklistConfigFunc), modules.NewStorageDealPieceCidBlocklistConfigFunc), + Override(new(dtypes.SetStorageDealPieceCidBlocklistConfigFunc), modules.NewSetStorageDealPieceCidBlocklistConfigFunc), ), ) } diff --git a/node/config/def.go b/node/config/def.go index f9928ed3f..76a6a89ea 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -35,7 +35,7 @@ type StorageMiner struct { type DealmakingConfig struct { AcceptingStorageDeals bool - PieceCidBlacklist []cid.Cid + PieceCidBlocklist []cid.Cid } // API contains configs for API endpoint @@ -124,7 +124,7 @@ func DefaultStorageMiner() *StorageMiner { Dealmaking: DealmakingConfig{ AcceptingStorageDeals: true, - PieceCidBlacklist: []cid.Cid{}, + PieceCidBlocklist: []cid.Cid{}, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 6eba12501..360a9442c 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -44,8 +44,8 @@ type StorageMinerAPI struct { *stores.Index SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc - StorageDealPieceCidBlacklistConfigFunc dtypes.StorageDealPieceCidBlacklistConfigFunc - SetStorageDealPieceCidBlacklistConfigFunc dtypes.SetStorageDealPieceCidBlacklistConfigFunc + StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc + SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { @@ -234,12 +234,12 @@ func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fn return sm.StorageProvider.ImportDataForDeal(ctx, deal, fi) } -func (sm *StorageMinerAPI) DealsPieceCidBlacklist(ctx context.Context) ([]cid.Cid, error) { - return sm.StorageDealPieceCidBlacklistConfigFunc() +func (sm *StorageMinerAPI) DealsPieceCidBlocklist(ctx context.Context) ([]cid.Cid, error) { + return sm.StorageDealPieceCidBlocklistConfigFunc() } -func (sm *StorageMinerAPI) DealsSetPieceCidBlacklist(ctx context.Context, cids []cid.Cid) error { - return sm.SetStorageDealPieceCidBlacklistConfigFunc(cids) +func (sm *StorageMinerAPI) DealsSetPieceCidBlocklist(ctx context.Context, cids []cid.Cid) error { + return sm.SetStorageDealPieceCidBlocklistConfigFunc(cids) } func (sm *StorageMinerAPI) StorageAddLocal(ctx context.Context, path string) error { diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index a9d278ca4..3f0d81d6d 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -18,11 +18,11 @@ type AcceptingStorageDealsConfigFunc func() (bool, error) // storage deal acceptance. type SetAcceptingStorageDealsConfigFunc func(bool) error -// StorageDealCidBlacklistConfigFunc is a function which reads from miner config +// StorageDealCidBlocklistConfigFunc is a function which reads from miner config // to obtain a list of CIDs for which the storage miner will not accept storage // proposals. -type StorageDealPieceCidBlacklistConfigFunc func() ([]cid.Cid, error) +type StorageDealPieceCidBlocklistConfigFunc func() ([]cid.Cid, error) -// SetStorageDealCidBlacklistConfigFunc is a function which is used to set a +// SetStorageDealCidBlocklistConfigFunc is a function which is used to set a // list of CIDs for which the storage miner will reject deal proposals. -type SetStorageDealPieceCidBlacklistConfigFunc func([]cid.Cid) error +type SetStorageDealPieceCidBlocklistConfigFunc func([]cid.Cid) error diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 73e062c9c..67e0e0842 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -309,7 +309,7 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return storedAsk, nil } -func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc, blacklistFunc dtypes.StorageDealPieceCidBlacklistConfigFunc) (storagemarket.StorageProvider, error) { +func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc) (storagemarket.StorageProvider, error) { net := smnet.NewFromLibp2pHost(h) store, err := piecefilestore.NewLocalFileStore(piecefilestore.OsPath(r.Path())) if err != nil { @@ -327,15 +327,15 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con return false, "miner is not accepting storage deals", nil } - blacklist, err := blacklistFunc() + blocklist, err := blocklistFunc() if err != nil { return false, "miner error", err } - for idx := range blacklist { - if deal.Proposal.PieceCID.Equals(blacklist[idx]) { - log.Warnf("piece CID in proposal %s is blacklisted; rejecting storage deal proposal from client: %s", deal.Proposal.PieceCID, deal.Client.String()) - return false, fmt.Sprintf("miner has blacklisted piece CID %s", deal.Proposal.PieceCID), nil + for idx := range blocklist { + if deal.Proposal.PieceCID.Equals(blocklist[idx]) { + log.Warnf("piece CID in proposal %s is blocklisted; rejecting storage deal proposal from client: %s", deal.Proposal.PieceCID, deal.Client.String()) + return false, fmt.Sprintf("miner has blocklisted piece CID %s", deal.Proposal.PieceCID), nil } } @@ -411,19 +411,19 @@ func NewSetAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.SetAccepti }, nil } -func NewStorageDealPieceCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.StorageDealPieceCidBlacklistConfigFunc, error) { +func NewStorageDealPieceCidBlocklistConfigFunc(r repo.LockedRepo) (dtypes.StorageDealPieceCidBlocklistConfigFunc, error) { return func() (out []cid.Cid, err error) { err = readCfg(r, func(cfg *config.StorageMiner) { - out = cfg.Dealmaking.PieceCidBlacklist + out = cfg.Dealmaking.PieceCidBlocklist }) return }, nil } -func NewSetStorageDealPieceCidBlacklistConfigFunc(r repo.LockedRepo) (dtypes.SetStorageDealPieceCidBlacklistConfigFunc, error) { - return func(blacklist []cid.Cid) (err error) { +func NewSetStorageDealPieceCidBlocklistConfigFunc(r repo.LockedRepo) (dtypes.SetStorageDealPieceCidBlocklistConfigFunc, error) { + return func(blocklist []cid.Cid) (err error) { err = mutateCfg(r, func(cfg *config.StorageMiner) { - cfg.Dealmaking.PieceCidBlacklist = blacklist + cfg.Dealmaking.PieceCidBlocklist = blocklist }) return }, nil From c41c210ced80a25633f08ebb630392c37efda148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 19 Jun 2020 01:24:04 +0200 Subject: [PATCH 213/379] New Genesis --- build/genesis/devnet.car | Bin 254687 -> 25893 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/build/genesis/devnet.car b/build/genesis/devnet.car index 5f13410a61bc8cff76b7ae69500765c777aaad5d..3e156de61764ee49afa5b090f86511a29a661e5e 100644 GIT binary patch literal 25893 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
`0j72gaTX*t_-QT+wQR zK|#qQ=}X!*Fmsct3oV(z#5+v=7=j!mXo=GU>CGnIvRAEf3;{f8|6Y;RriKsfVfyvB0_O1b=y(?0+!`~5PqP9`2Y8%%m+oBwYH{T# zaTr7=J)^-Of`jFuyX3{9)2obp*{SW5*6fMB^J=Xhm*yh1hIlto2jv2CBIWAQ@{mD9 z2@;mO-^wy5-bvf@gxLqOjOTRaSv6`uOQ2LDV4{ik;-LVlta%J^4kR3ZRr`j2U#u8@ z%T-!I|4jTXY0$dVnLg6}QSY7|KN>lJ&^m@V4-(j`w~7kerOs6-zufJ+s5wd|a?4uX ztrb(|-FG&f;X33Tg7z^46-fB{82oukQ$@2pS10i;9d}OjO`(@mR!-8k<5k^`S5wI6 zvd%FCHAo~@p(j^e>$g4?$@qaKupG|Col{K_Aw=+&owb{Sln~h^ymkyh0}>k&+fE8v zk;z{%HShVOdky(Flddyn;czxc)_fdoYDL}+*N-7+LE_$+cGvIxyZu-qg>~1|2Q&IC z-L&6wYG`o^tqE&X7$T=9bdM5;L3C2@4GbbWu)M5>miv8-RT^6B9d*35ykfiOJ+8Dh zj86>loFAk49e@p7KE0#mA%ln>Bm}Px8+*}Z2>BXPYc{>h{8Yz7!dkPle`@1A3;&Yj zH3optKZXFhzJG5WVa=#~uO7XXH%|$2l6|d=;%pr(G*rI!$+mh{ix^rDa&Qu&dtE5 zd-h8Q882Is3{Z<3#}LdQ5x^jld>=7A)y5EdFUrXy&@Rj=`FZEQ)XQjQ&8sroq5yI8 z7=i^P6z0roSYF^Yl?fDCU32A}{~47&o0fKVn7*p5@nY5)C-v*WAYui} zvy~s;dd@(!f4#n%mVZC~k@c_n`zD*t38E2N&u5eBktfdNXnDvWVgm_Tzjq93sg!kv ziELq)`BeH#$ja#Ih03wV-1BOx5>ElY=?F7DhF}MYWW%O;u_Tv}Pw&-AN7Hl5b8|gT zcU>W6gvWGAVJ8y+$zL$DV+anApkQfVZPn6b&%$hCJG=36QafNJ%H!CPy{7i)=9lX!cb`1c z^EjW0nC~j4-=nh)W>huMjyd<1)2(nKYvJ z0G`zD~>r`C(Q+bK_m>8_c5@}QET%nDO*^b z&wRYnxb^Gn5j(2Nfv%ej&u*z=BD=KCN6SM75s)18_gO@*EYfgaFjM6|^%tomCZ~~{ zGX=LYL=-aYK6cHf=X^)@&0UTmL_q>yhQQ$wsky(CI)kUH23O@!%$-<@F4{M$Ysv;R z?CHqCwd*m27)YqlQ7!XODN^mWy?H(_IAZMOC+Hf@-DS0O=LrUOBQ`Pu+>Rl{K_b8b z7oR3TNn1+LbS{$ln!T-roN4ZpMlZ^PaOuW}0~|mExF17EfW)=H2Av6G2LsAmgEEXU z-Rp@_F~cQt5^8!3>{r+k!90MS{juMAo zDm>|n3;)-b3WsW6%4^56?ap0?_r0XS`)%B{IY{2=Jnr$l&3$q=9vFZh&T8$P%KDsR z(~=SN!|Ar`(jx1Xmtw)T?G-aRBpI9{=bZ{sHid_{aDKYU9K$;@H}~|~5EbW&#cjW2 zTPqRK3pXtMTY<%?L)C-k+>Ii}?Q{!u+lsXtq$ElUim~_c2?-xDeXtqV}*Pk-#La*013%>oTu?;U!db#W~sk?{d%X96RY@i z>g5h{6@79QDi!1q$Nv~Y5hNOWuV&*uY_twfZ#7S*C#wyP_^Lj>#x9R9`_uNK?iO;n zH{d97*czV{?qCopf#t=$e9(4^;qK*cuOqNsB=(-5NxW};r^&YTXGf0YmbWvI(h3Va zS{^cpltCg0w>UaPjLmxwMN7K%v?|_zWpVD2s(yP0SPhwC_|2K zu@4{3_0d>V2z1vew`n|TY`xGm@kr1&$_<&N5qu1x3KF3#&O^0Tq#`NjCzIbaquo>R zy_Za9tXjZSl;)-o#)nK-2|0#P1Bsb4HV*OQRPH@rms~mqUUQpZo1IP|GC9+npX5~M zYKdI+xO)tt4iYh@!sjTma2SkDR?Qw$MfYv=>d)iMxTYEXys(-*Yi$9Xi_l{T4UjNV z?rPUV_b%LBPW~7vSy;pnP8=gP@=e_jGv)SvIVmy%!j2)XfCOdsU5q)*$CfU55f6vC zgsRX}9$&%=KbzX4RoU{Iw)pR`d#S}X0+0V!uIQ(dN$RN@LiFmQ#XEuwvpPxKC-LSa+KH-?B)%t@U73l$ z@+GQJU~2k>h8!#UnYkYhgyu~=ui8%^tRnA*=wpa$Ao0s@A2Us{t@;Y5)1B5oY?TSA zwQF(xAtnBCai&pd?6Sat+&_l64ib%zOt^dOyYU*ll;d2k4>i7$l)BVt;rZce#JnZ{ zk0s>lZ_F`-E=c5Fy>_YVeF7aRERHFk(psXy=BIW(j*rHpk2aV#;ikwDYV1+sFo;fi zM1nyCJT3p8d;L{#bZ{jh85lHZCa7q+feUtbTt2()z!fi=^0WLyNlF97ItoLTjS{u0roOBFv z10*R=;PQ8gt9z9zNx)p;j-3(OcxYP0BHZF-YWKn`3-tm#w^8gSVw65H*wft1zMO z`E5y8v~fnA9ev~kXzEeoFo;g-Jb^)E0+!d@U#E1te?T&5o1uEr|4cOQbmE=YO+Ft? zX&tzYFK{5&D$6k^6#1^k*VZ&yRWmm~w zrts3*+N4dIz1sdau~anRKr)XZEJ31WsCW2AQ28tiOZZm1!<)Mf*(E(1U$tHs=sJpi zN;;(h5Lw3%Rv=MPk@fh42Xpm@{YBxWn3m$mM#6X|Ww&pPx~HjMsW&1MQL~RBtU;pd z?&>IgkvzNmRIZfxPZHwfugwRsO?2_gFfY=(Ufjq~&N)g@pat%f1fdwuk3B7>sd1NqcVFnNGTya^F2Q%{H$x{oN?yq%9*y-K!g9bt7Bue4#FV) zlqr$WuKO#UL$Dfmdu!)>%Y_R=?%Rx>^+9^P7$qLpr$+qS;=i2g*?c`Oe18iosmHpA z-(-TYIX=ViqI6nYdU_yB@y#&8V&SzaPdYfFey9JdldYqzJNT~~|CQ-B{X_8eLg%h^ zj9hZ+H1(Ad6-hXO9jj;z?=T6RaNa%yadr*|Bp+w}&xX&rd|jGI*SQ#04L`S%Vh}Ny zX&dM@kYPqGkVT2HWbJP0=I&_e{srSd{-j-kXAC9AcjR9Y$6j?ABi?1v_`sl)BjcXUFjfN-hZFV{T&fmx(zhY8d7fx5 zSbe&Pgk6(F{l8{@Cvb*a{O6)e)ME(@P32qK4m?m;8;s|Q!LK8R+x#umwR3(Vd+Zxi z+7pSZ!&<(??Moghlo$(t|N4iN@4jys-Hij}`Oz;Um_^52HtyN{p-0yed(~X~EHpSPTg{fr2YDb)5sRLS)c@9^YZmHQh6o z^)2OLy0+L%g(mo9V}lp8i7)V91x^x!Wu*{J7V^v>sv`CG=1fTy&7Il16mLb&`mp*f*2VWP zLWzD=ZVfG8Jut+e6_o&P&i~h|^YheyHG08Nq~Z2xp+qVUw!xnMz35X*VyY1Jt@>ay zw{tq07A3&PNG%Zm{rebcas^*J*M{BOr-dGOn+YaaOI^-A4wF2i)A(gmj7zUd@qhYb zq`T_f^F6=5q{}H+M2A}Yrg+$1m{p=%km+Ty>b^YMI7f-A^}q0Iq$kz-xUZ2Ko29?~ zM)nNtoe;lkhinL6%yqVz-zHxwUoz8P+U6{IfD(>YJ{xZsL&NPfUO(O-ze!^fBQ|r9 zMjeN$NvRaQeXJ0empF{v<^$@eUbZ^o1i71^#C1enr#}~+#ZbAFr}CRg0;}a7Fl;~E zRAXn%Yf852;{Z+y?<}j%7#uJDVn$eAY+qi}$d|jez=H1KrnQnBjX$q@D%!7pPQ1E* zr@Z)-!s>`>rsv4KC(e29I$&6QxGDcT{TJ^VOhwwam63fS8V#VCAgiPT)3e{JyxAIVp_+tU9wue=? zbsPRAvZ;k`rSY9ZX^3;x&7KCq#KcsXM&(o8IkNW|D4X)rV2@v9ztFa=#hBrCrsK}n zl)$0XvCYREU@xR&2-_aca(RXgeo&# zHAnW;o@c;4nQiTbp9Vim^5R3h&x!@v9UI&|WTu8V?Om-=unCcg5EDVDeaQoJJio}7 zP82_vinYTKN#fW?cRvi0lkTU(AVJAzt6@Hexn?31*S-+4+~(8w?QuwrtjnTXRR8kX zBD>LD0<<8Uqh%q21SOYEw6FDUsRFHhW9`l5h%eF_hCZB}vJFkE%R-`qe6KV8Qd`?Md-V=owu zJ87X1k*h%f*&QWsZL?|mwCk(eHtUkZ5*l`q1=sZ0)~z$-tMMYL9!Pi_o<<8IgzS!z zvv%*guw@FDq-$Qv)3>&9Pku{fjr3jDys10c8LjyMH-Q>0i0J67fF2FCN|V=3y3B_Q0bW6~mU0 zT<7~7Z9Q_oY2&mxV(OFxvO7wSTDRCaVGf}p2Wi0vQN+SDGmjdm5;xX^xxXyxMdbrGvmLCm_6L3T&UO|!JF zxUH6sA9#15uw1T&wLX;?<5N;!3Ws`~;SOt;H{u2Tvyk0U^3p2C9R}NfW{k6YkTu}$ z=M{a*el&BrVQ?(~J>5HM)D9ahh#ayzN=}*s1~&Kk2PPFi23pE=rG2bDou7Mb>{fMDaF*8HV#YYIJG~QLfdF zJFMd79EdebIQ(d7h%iC@xTwb6;W@*b(jT#yBXL%+nH332{Od`r7dA1NK5fgE{X}HY z!6~5tN-`QI3zf!eyj?Nr9MwvHs>&iQ2bO}w+DyVJI-eTMZFNMe4?hP5P*Tw{I(FbT zzkje1|G-V~+r%@d!co#=#u-L@QCr?eVLF-+0i1^dK$qrkgEk%oHzXLL-Bx>e*UV6U zN+EY;E|XdgX5KX%dowiWybA)Lf&wUMXj>NZEBYDM6}34Qc@@19w-jVIO#|xr>F9>b zt$u8w%OL=2D1efL#&09GF zY3gxlXE^0-HT2@fy>y=l-Qm(}Y-bLcQZy2s0SYjH*L+a9`o5SZjtRZ1X2DpazduuD zI0Fb!Qkt2yN;`y z$k)m{CKe#Y`^uPM?{Yx|Vxb?-32z8+6c zC}JiS&U&;oAZSq1%}5^_c)U+u=+4H){542}l|6BgtA1seHFoA(YhJ9E5n>J;&ISe8 z!Q-8nlIlI+a5d5`AvLxjc-!GYs@S3TfjD=s>OmR)^EE`yDx4h(pro3ec?qlL&tItj zdU=wg(BlWK?7&0S?cfE|AH6*-GAY$SL%{(BP!i2nPtgqI)3DN($Z9HFw+VRMiI2~` zQD!P#;?VXgU?mGU2b@p18)JflO5jzE3 zb1o==l4R!6PTR!6HnK&y?BznoHEq~8p(9;F6_sl8_VvwoB|eDp1^gluKuIxkx=8GW zOBc&{AE#J2_-)Z6R=j~zmV+_tWH-0-BQLrm@&@7DM}fnjIcbFTFKBqcOICGW+Lu3XtC1i&jc|S_fRa`w-5j)GQOLr{ z9mU9<@z6b^6Ek+DGQO4hp3NqQaECEsF&!=d1yGX8hI;fRXF?2_9AHLkd6s8q#Pi-X zN8xnCqpc)V_5Bu25P%>QKuIZ6jEf^sdXKX}tx*6!lQgPd@+~1lt>n9p%TGTouTs(J z5t3}pp7=I1ukQZ5kr!2n&O2NT3W$R@4(8X{2kxIc=!o>oHhY97uGMYHur55~NT)Qo zPtr-bgUF1Bi$ejFG_nyntbH@A!l|zJu8}5t4*kThI%@K#hAdeZ$XgSi8UYQ31Qb9? zBAd=;OJlyaCLtCnlVz9igOAnoju0J5{WJD4O3X3Zb)aK-8494Jke#WKe->9_r2EK? z)%?u5tW660%eVvDE7NtOr-?iBuOU_&;gUyz!`D4en$bf94eI1qn0kwq?Z|cJaapV| z;pZ1m&D(F|jBt`-)OJVTe%e_25OG!yXNh*Z*X2ve2D%=xE`08HdvX<;tUzR^sa66xJ-@P7q4`D%FlhSjVDr; zdP?S5qvxYfr;-OA-nl28)qi)c6hi;o6NfoqP1C;}_H{|w{Md2d)?qxw;h=UD}Hp+0306(e& zmxcl;*=u%l5+o#OIjhPe(R8Ux#-WKpnDZA-vpE@u$o&!B7bHahGEe}Rp8R_VBbu~E zmgmD_S}wzn5L_>mE~EEGV=T+3y3c`8KV-=}st;Y)GY z>Qiy&@4c*LsiS(bfrY!Z@`$W@xEvHf$y=i>O0;|BlA~%~A%AasIX2V0r^G}_SzB}C zG?vR1el4KwkcR>&S!*d}AvAV5yBwF%)s`jJE)x0U1wZA$l2{4LoV>i50Q@)?TmcFw zg6F{gzM=kipSUjN&NZ}gN4e7X1lV*`af458m*9!`=Exu>nBa;>fy1CV>Hhi`G)iD; zSWBCfB>l5ye=KW4&8!4pYjXIiIpOg3)vVr?a`huc4EEtlM@s{O1|?rjX17xQ2ihC- zSSO#(->Idkw~8fV80#p%h|f0$!n#v{hDI3*pk%8FZaZB0nI}p#b8eW*wc!;7wv}bc z=Eld4S{;91QfWzT1fT*1P;%AU%G>dBjL-?x(qtrBu}Lfj>8K_3WB4D$ag}_)FN#5= zy1-ST07|A>J6*{+`TL{JhRoI7H)d_&R|=&JhD)k3oh7uD!^jpC5r7&LK*>}4_Dyie z+to`M_x_Z$F<$WxtO>qW`NqAEnA$h}4mjNqiB52JD1efshLNstKE{}+Sy|&My|emf z$?~6}7tD5zV#wL}^!#mIee3N`Bg9io)sa5~AK+JJEo2^cVI5U8S)(ci8b3f)0#6kq`r2c}*yQ zlASgg@EzYE=2T(PpnA0yLyP2}rtOZn>3XGEs`KJW5$BoeUT@x-)>L ze_-(fKeF+iItS@9XKUkwNZD8+<%9dG2tXSOpk$_>*<-PSx`e0)$_IOc z#Bx-euC`_FLUts;a7G6TpyZ`ZqD_d@t*<_3Z=s#oU!|IzjqXStPycE#u{Rv*J<@`B z6%l?73ZP`Ay~SK8mL^W=`Y1>FD<(|?v)f_!&hzTiX#@}UwPL;p;3I(RPyi(-O<2j` z9L}y_muyF@Ibo{ZZ@f8`t|W4P{FXOeRx&RFc@Ti^QQ$CWPI~743mTM+G_Ce7Dc`&po%uTN#FF!qGy$i$ zwbBh&)t z>P#s+mG=E?p?}`bD$iv7o%gK*K=1qp6hO&Bi>=({(qH@Kp40ByLdJSfVf~f4u!H(D z!<6(Uw}gBZV)X-l6AGZ@pouDZ75hlie#Y3u!ZXSykvw&q4_1;9-4&hh`Uvj|Aux4g zd=xkgnv;58|AGeS2p)C_thT+*s#W=+M<0mxSYNv0q!cwgpO*7oydFn!^`aBvU1_+< z(b9mRLCHUp3xJD=S2`L6*AlT~3ziJW(*Dp`WFK_G>UyK4+r0)fjHXZkCHu_%bmp7H z>0*IL9=-1t#5*yg%Dme%wPve?TTi>)!%9|00A^6Y96W>utQr4Qk6Wg*#+YyChN)!s zG#4b4PWNS8{1hTdtH=!mjX4xR$vm?t+G+eh%-v;F73&))a5|(@Ng^LEhz(urx0ti)Snz;gIE+h(X=kw=UX9*c4VW04B=dWIV zkX%f!^s|y0SZ%X}0#@KPQ1Ky9(%9pyQKx;RxI!ZJ_f9xh*($yme|B3ik4q{ytk@@v$lnwTn0?tm0b3A|^|0S{%c#AM z;uJh$JUfqCb@B2{5>G&-dYb^c_Nzcxy&;7y6tDvU)MT*%Wydj#X}gjhil(ka^*>85 zhj8ltR1-MbFFR>j!T>ucU=ISwrn78Mzb!DVhpUy8uD-V7)%vDWrOsQP#YmbhvhS@2 z1MH!I0|{-N9h08j9QJN!60%JqEfe2PkkK1jbEW2MeS+ zifC&C%&OQ4oToLu5dD=9{6x(E*B2nyEa9E=xzrl0pq5d2_ zaGyIv0T&SPROy`5S~m4Oj0t(jCd&4F*v9CtvG3K6a@Q&5?R%@h60Hjqa0LM)X+n0i zlHYl33&X>E_?>h0$V`EDlfN^HQLU_=`Z)5y09PpR00h>PrrpO}{78GkSU+%+-i~rC zu)CC<_G9f$41w^2=q7C#@Bj+9fk14Wgrp44f}BuIww~6!W1jQxzT0HTG~sau=Anij z!@$;r8x(K{0lOO#m!?cgbr(jNjJbMgFQ5%cS2iixZ#XkN4#C`P2S!!yP{0EOB#8;U z^wbJ9E^G141`Y&d^EnGhiOKz)@=@`r5x=ZJ00TTu11Cvy-rW3O(s+W=Okdm?v9nc_ zC{tY1UtG<>dZZZ1_de#cgH&N_j2V+He5T z+}4+eq~GXXUAeR}81)diO&>x5FA&ILo)5AUC{#S8qirnK%r=Yci?AMQlX>sMu`~ZZ zWB}N|^MV48K;TiP#t;2xih-t-s>Cyp^2Umym(#@7 zyr?1tZk)$Zz!wB4CJtBy9AoO@^&2P(O;nb?bYzS7dL0E|4`sUuz0!s4w^R6@22K{s z&Z}vIB@N_+ky{R1If4)9Ue*P=**_>D5mS90|3Wsi2w2QHSt??2!A)lT zK^s}Gw?=vqt4RJvy?jp>g|Aj(xfBy?>yLDVrdOSV`qz!Nf^nRg&4U@E%6oL~)W7VX z)G`;-D@T1BABNC0y0sqb3ugz9W8a2fU$g(`EaR>K=Dx};1vh+tSI+rWgr-`5_U~9v zyF8cT&~4d?I~b98e5cWRS(ovdP!HX6F|W4>O|dRc?1c|k4D91Dj3K{84Vg|AH7nCw zzb{Sw$GwGfJPx7hb!nusOCO0PQ&mW?%Pc3c`+Ky2DZ@IB9O z;f}ct58s_iikeqg8;ePG^Ww(JcO+M$r4RlsmYsK1|J}KMF#W%QB`Ru0(4t!*;jeN6 zK0#)dt;Y1k$rM-CZ~{$LER)zwpsVvc{U-|wO!<=!OQMhvWz2S9gaSbzkn-5feHV9-ZKWq?DUNt#grVEGl>}p)yC?4psk25n zu)!1r1%g3fh_^>w$kBu{@|k<@xW=$Xyu0=1pU;9VUJT>h3kcQ&fZ)@>Nq2wV{q-+t zfcy8qq-koydX=s>!01wPS2Ubu+UB)wi0N<5P8X$1S6>1%&`>Dw3CgSN)LwczOk2%zl!)CD(cyYUqnI1 zjP-0~XTkFi@PrP70^uOQE=zh{{{ABRtPiSKIc@vOyP60`>NjK2m`{Q zKm-VstSjjh-t)G;QbQt$a@Y2B0(TCP>As6(gma6k8?YcrFxK^;>`x~ zHKMPzWUMKL=BEHRPULCeBx%m;Y5yfn6c~-6_U2_?F=qyX4(s?bqu-*DxBGaJ@-%am z!8R7ufTW2A0lpmM2jjK7-Hv##3C)?TFxpWCJFBnAhFV4SJ2WKdxxj#E zC=dezly2$P}_7i@=U9IjFFqA685`^MQ}914yV#|WpHSJ%euz3W-c zU_d++NB{w^KI0~_7ATU5qzgl8z`MzI7=1-uAiIOaT zc%tt8pr=(~1NkKS&(vVR3n-8b0*QAz@+c(3YsTcG&F`R3{<4@F&cEQB#iVKOd~+!K z5J=l(D3AgIO-Chf=2Fs1o2uk4v1ysl$Zrlxa%g8+{&-ABzuuDtJRDM>Kq?4iI4?iC zFMcC-i^zV_Alp^+!MhLLysGj@b)&QEacu8lm4FnfP#_HiuGC1Zyt_oGbmeP=Mbk(V zVRu>hDyN5@QpH37S2DS?1`J4p0>H@XzqAeUIg(7>jeSG-*TcF-;_V_zX5HXr5|fBY z`td)D_W8ixMmiLD2?9@4?lS5aT)E+{<7c;n%G0&?mhjJ_=M}N*KJh~9b&vI7z{}IX zNz$A*`udkN8DKOG47T}C)kFspTG}M?9j>TfjSOYtemx|&rkpY3%5ewQv@=de1Cr(y z2+Y}1ho-!!?E5geGhiQe%_9D|lH$|5zqr$K&IZeG;;+MiS5P1m1VU#u1LNkRi`d-^ zq)BY=WmaERW(=Y3Y>E=r!y{!40xE1Wp+FW0TsGw3{!6fRUjXR?lk0BT@<2+)b)5ap zqEd&eO4E3X@-QF^3S@(TxG&bYJ5$tdq3656Z=|gz@wA7WnYim`2TBeauOm?96-k3ZE6Y^Ik)NTo5?=MH{SE-+o(4{m=DczEzof|nqs6bGQ_~K9@cyInt$3xqS>WBi!Rvf>%I}}} zbvl;QhZ$kf@=iwsk|rMn#06Xxvixezn0VmZWxdc z1qwjm&h=6E_>?V;r?#j=^AMVWO zaqfv-8wzfsUzURbg;1af1cFM7BZwyT6hod>#G<+@8Bg}dS}VrHKMI#+G|=u7g#FqH zMG+Jz27wz5TRY)bFB?p!#j+2$R4PAYdDi1>rR&<{A04(H4GB)4)m6oHrx;moz0{wEBBX-Ipwz zHRZBJJ{fN2QsTX7?LlB9T?z%tKmc<~tcPV`q#`BhxS~LpGc`YQJ+?|^%K5KN@OD3s z5ipJ|g97CsaPO&Xpo{iu7%c(g>)09{6@@(J@C#AbOCC{r2hFR#a)klqP@n1OJld zoVoeGq^SX;NndLBa=b2odH3?D1^MLXHuU1FA!fw=JVkx1fr&d$fD2Z0IvS8PwIJ{* z&Z;krpKht~jdc*+91UeIRc1Hyt?lC*v&Ndg_Q`>%M=cbn0|6F;(U;#%H^Xsyo?gSL z;$CazqQwaiF?0D{9dBmYLoM_&GD`vrTWl^bT@8ro;P@Dhq6a)o>Tqb)s4m{%0(kXNBhB_FA}BS`+OE8O}>!@=C-+rbSz zQvoC68{aoHf!_B0Y2akB?7X)+VM&9yScXZwkF|h&!C(E5wVROGGcQf#W?)4@2Wnz8 z{%~b#)OFY)oh+7>vF+RwF~#j0*5-NDU~6H$*Lqc8Mn^SA_>%y~rT4dh?aPy<%AU?B zW0#(+VG3QcLJ^s~Yi3Dd@^&ztB|dbF!)3IU6`?6+J_UhG_|`|;nS{$(F}>zmbazUu z3iEi$bDZggUF;4Knwn5w!^fVG(Q8ES){@mDdno%sO~vU-@Wb!jIC;0--AECd293Qb zvTNOY<>EJE_7Q0++iFtrqal?qe<^XTnkTM;07BDaRL^R>x(TjVDn-@-I_B^88(+PS zc!ocDY;U5s!iNp41)ZFh>|1xUD>nNM4{UbC8A86YiGQ1-a@AW_$bPhQ^GIU%>%Yaa z^RDW@JGTj@|Mzea#EC9e@4}aoz5LO3a4@3D^2!q4-gq{{mp}GjI@a}QV1M$a(|>Z{ z&TR$(%~=eC%s(hk`WKzIJJk+w-yJ_kK~^oiu<-R31@c`ZVAr`B3VZ+oW?ozU>6G$| z6$J17r1f!Lqb{en|1QqaWXgEVuNAp&1Oq-mfff*86|s|kuJ8@ru9Gz3z*KrZ@9om{ zW?$*XdbWq5RaeA;I;R#W&)hw9 z+>`$PwyeOKQ1GSb*8PQte-_lgU?P-CkyK;hF( zTy=8!12?TgT~WK+<%Az_!#Al%aBD}kFELVdL4i*oz@{-^ zLKMfLm}2XO=Ohp*MT8?1&p*ttGsg-3(PsXXW?(4Rhi`AnU$Dfk6=PzLcz&py013*n&>E z$Q{f(HFGsR0-Jnct>kCAlP)f>?lA}jhCtxYW6w`TYMGxTIXSX6a}F5G6)6t$hXh-U z#tW`Rh_%VUfFUR_3Hzroo){5y!Kwmv(mM%E4n44(#0 zlIFZ;?!TlN0i&%HVQVJPhR!I)T;Qs*#M~vAndM-`6?S?;DXn|ILKG-R9622gNSbdT z5ENct`g*^gb9?aj6s2M5Fp(jx*a(uckqqr>rgkz8-^RoB=|!9Z3TZ?kJgt8je+-E#-YFj z2n1SmzKLSHcUi!McF5hi#81|;uQICRhbNijt?7rtG8iym0t!rmfUY!>Wx~S|l%&M$ z*mP#j8-^5#ChSjUJ6fB)0^h$SCV>HyP+$rKVlL)jJ!3G6bM~lmLe)iAabWchnWI1W zx*e5soo2-u*oB=s4V)y+d84m?N%I|ymQ#P6&D%L8DdY6{cMfyo3(~sQ&QLrps?w@- zv(AMEOIWn;r=tN$GYtaOswHU*k{3*n>g5+CS!W}#MNI;{J9P^=vo02-=nlBTfN3Z& z0|HX72S@A7yX>FO1ui^jyi%HEChL-g|B(L?br)9SRva*po`C|hAW*o_JYUgvZ?aXA z-*}PBQ1QMrlV+bEZyKvHyZIAcZlE-677EOP!11UM<*>htqFa7&G-qv&?ZN@+rs>yg zEQtoOy6ZowsA0ey6qpAAnGE&hyn*Z4W_u!?+VmRAgg+PuQuxttGGgSiU7-lHkg&->=N%~z8`$MfW_e@;QylcKP_D0~Vmb4-km4UPD2x zyFjhVAfaJ=(S}95#fmOZLd0ZFq20-owWZF)FKU#!N*yA6lZP~4jo zm%HN~p}DLzTSxHjiwO)^f&$ARaMYC2nb*lkue@TkRhWEy#qoxq>(fC?wvS9R;%itO zcVWOX6!-}OqN-5o~UW}IO_Y_RNkpAL|i#FoeNQJJzzV!+e_yq#x%%7Ca+waJ#*l)y2ioNOg zbXuapZ83c!^U9%uBq5#<2K<5ozd>N$16!c*zU@8o1cBLz#U`8q)sL=Dmy5^h-1ap} z))Rmm=Qk8s1%dHwokM*emEcc~w%39b2r4{wNorJ)kC1uLCB9}ytOMJytEYjJq&aU! z_AhDvfYCZz>+qPvjcjEIHsw&on~RL&Z8LH&W-a1wlt0YwxhDvV_UCjoAZgY>K%L*k z1b>i-yjAG}jc{XLWZ<>EebRRy@*jR{Almjk;)4NeP+%Pdl%Bu4tn^D0sXOn_H33d{ z!J|2p_+&1#d%g>{K9VGn1~6b93T%J?Z{&!BL+x>p?R-i<-kV6VJFBgi^2OJ>ch{0c z)}r=+b^Q$}un7V}1$(!$MK)P0DphGsP-EH@UgjRpk~6YR{!|&bi827B?Isl10s#zc zTN7{nqxYzH8pwarPXrn^Eatzr8ehwNU2UiF840+ETToyd1P&U4rs9~w?z|rh6e@Na z`5P7IX-mIo@IY5d&^3ce1$f49LxCL-5awF@%WB6u(Qf_sOTojLpVRwOk&~GXjK?pr z{qD%m16y)Cr-75CId5+MFKKqcXtdRmSF3ze*QFz_*NI8X)U)$FzhoTp5v@v!)%QS` zAE@QqJsk~5nmrJ}>M+XXF48XZ}B~Wms<9qz&;45 zxjpWnuTykPOWh4VWZbLqIM5Bk+x%<8{*aHwY_l2%2JAzD0}#MwwAh(J({kP3j&mHy zQc_v2Zs`7!8Z1a~NSis1L~s)Z96$kJRpq~jLqV@KKhLKhI?@lAheACryOZqaFltRl zJ!1${ync)W`>nVq6o*jYF9`VQ|J1pq8e8$q`e*bF8^UI^uf!dVCrfSfelWsv%Muj{Zo|JGDQJdY*`J>Qxz zj~DIqFkguDs|`(H9&yq%AelCjP5>|C&UI!NoGE{csYihl%!`$gJhy^%(EW$Q5t=p| zqc)E}2)}@Fo31W2{mPFQp^dD$dozPefWA(C#nWGHgSD~q0i_g*t~0YToC*By!5 zo$txq-uA%O^=_XA99bUSu$>d3Rw6Y)CwmjcnQqhHX7lBBPu^ zpn^o%6N!eHfCqV>TAb5-q+ULDp#F1Zeds<;zHq-yYq&2JK%kyMpn=3=PKy|S!F?31 zKX>R9*sL@hypzkO-bcgkKuTn^GYE8$@QHpPCNE!RXKtH8B34qsu8J|y z$AhCOX!=%aV=r1B_VlAfMn8kV0EyrSgeuQ6%m$6Gm?xE^^nV`UZ^Kp>*ZW~y`_o5Y zt%VmLFwP(_L81<|XL*xz?Nd%2gRAL$PJ2_V@m4h2KvJ=5`*n_s*s#8c5*hO}(emFf z3!Qhrfk}h~#(N$jzW;IS_+x?@^PlRkD1~$Dv_fBX3-6o#oed5B5(9f+QX*rWjt5U7 zY>+@k`?A|*j^7bRrLm|_qT453izH|^ufZRcPY@M(#Rm2=EhRGc8N>yUApOjnK;X1{ zqmC||`_&NN&2NO1i9FP^ zJK7zO#x7ml80WWjh7BDkk#Wu-a6!V|nW_fk$A_8+(GPTg>}=h33L74};jQY}-Ro6& zZ$<-FNkWN?dj^3A5?r;JAGC;SnVp%NlXkCm-1K}EMpwM5_erYzYREhh2K-v!ok8G( zM0#h+PK#ot+wFY<(_c1>7?gr^o-TK`pYAL)KN&MYg%kK^5CkAGZ-}-ao$=vg^W|EL6~iIXHcuO|kRh!Bj&lbB3l)b1P77)a$?qbz9| zLnQ4$oy69$U~S`DsO!WATsXqh@!&~B1QPsL(0*{N>($0zzTiH+Nj;uOFupK8# zWa2Xj5|B`S9K%4OkKX*jE%as`_3Dv&CB;rKg&zK|v;wY=dp@oJL2?EG?7RHeAHLy} zEvVSip(QGbP75uqv@4DqQ*aq+ts@E_At^}pguR|YiA;J1K?V|}HA9VWit$#YNxo41 zy3u=?P+jtVagh#f9)X<&nMNmU_m2{p>r%uJ+x;dZ{TaoYMur>S zD_=ZKoFvhC&uB1-D8P6>6ZS z6G~*tGYBe>c>6>E%RTjGo@-nL-~11w>BW%TyM(`a=C3P69_acoz#pnqXAsmNktw&K zqwDFIaj0(XwTOrBB~P9$!SK1oPkdII3~6!}R`yAWOnnAH0}^bHkl37G-aTqyY zidM+UBtrY!-kK@N9Z8|)uLAGPXwD!mfkeGQDbZ`cz3)cNovH(AH`)CT@SL(Z>u7hiZ!M0*B7 z2NK**nLpCbh>y}tBB6D}-TApmxZe_Ujz&fX64Q)wlH$|uc zvr+y=bO`)$#&ViCNuu+{^>!aVla?F%l6+i;e0FjN%i(2ieeRyf`@ovC`UWSTFZ!^hdP-#WGYAflxR=~e{hLmo zEfd`V6M6i0>>`E55r@HJEO|^UP7Ty?*s>`lGRGMNCrIdOOfq`0VKrFGw0{&UGEb*B z`s7jki(jMb?H@ElAraW*ni84w41x-kEWoL0koiyWh=}r7excUSwl3q+l3QvJ_LKsN}hS2w67?7YW6Hm2pubUp<4k z1`?UuYIldqDJpeFcn#X##Lr0{-hDGXb*;B&f&)dWs2KiGy>^;7Nuu*+d|(oBgYkS( znXENF;xH1YW8mW1^YGH<4}A!H;3p(MN|1m|unt>Tp+x3B9S@#FJRnisWySGR@Q9YW zny;2mVf8`n$`dB#-u@@S%xS}gTbL#Q!E*+|3li}Qe)mcnaGx8*R6P;qzmpK}aeQ2V zkS$ZaRobsxrL77Oyk`)6AQ2IuwAIK_d-L8X9clP4vRJxHPdUS7(T0tTEb8<)fZx!d zMCLn#;0Fmdr&@-`p_Vj>C0MTNg@pnP(=GI*bz*Z*AIq^fak!HM1pgU?07z);Eyb^X zD)!@_F1=l&>B(-0PS8!VEuh(E`kn||iVU`eK#44H1|bL%^W>t_;%nh7vp&^@$zuX2 zM_pv!vPbXz@lU^yOd|FUP6(bsTn7nx^b&!G`z4uKA12O*IzVQ8P>H)o8DT4yAt!heS;WG#kkO;NuZynFJh_GHM zf38}H?Io+QY#b_OvB)$OLD@>jhXN2HXAq(wF}@|v@Z_^b6ERMgUfJlxM~d&A#zl#W zN0BY)KmLYS!}dfdkwwoS#6V)w7`e_kQ$cn6+QzqAUqoKq>mAo7@W$mrzOnIG+btUQ z!&8*VVrLNIAW`_KYxDV`F7wDUZQ;%h+vv3@B#V2f>trIHRT0#mufQi6;%5*NAknl; zXdeA?_8@Wqw?E4qZSwoJlV+&J>$-%s`L3fE=&=1qN@R)C#K~7T&-=2#|Mk_)0BLR~ zna${5%mY5ja;y>(Y*Y=?caZCL54IWSNXgxRZvJEe?C3Ktva(JhgVbZ`*RAc%?m4{T zlD(1H$h#wkuE#uofKri@rdkH(@mHT&A;&ffBQXi(4!*C&MgDTAGvjR)Zi8fE1FQ|7 zG^J|17_<{vVnv4UDE}^SFHRKo#+cLZjA{dP8G0K24xsewq$%H&=}C%_BK5(p5drVa=LSeY{1R( zq}A1)Wv&NGFRnaRguNIDTOv7q@Vl?of9$Uvw-87YD3l2y`! ziFiv_y;;~R)Rf4QXArd1S6$3-1ZGujGBcHkWlQfC?PN zt<%IwZ+u?5gGnS0#*4Qk7?YFZ%6#tC<2gx|tiXCvL^aD-=TTUX8ZO;^pk#*j=RlQUl|yarU(SZj_c`kc<`RO6E&#s zpZ0Y}#}D;yx43>AIApcc@!(0M4iajwb2{jsGTh7?3yb@@MLL-n$x?14#G3cJf$3?? zNF01+M*R%p4oJLm2p1O2sqADRLUX)@Dyz}6Rvm25@smVv^}@>qPGV!=DDIp=+y#l| zT>-KkVWErsZmicwG%d*$En5{XX;Gf@#r`X^dWNk}UvqARmDST3`dj_Eg5{a^F#zPIkzM=1J48~sEt!KVJ zj(*iSlvbbjhUR@PfeXNe(>sH>2NL=?d5a8{BX`*&FocZei>72#yJ+cBP1TbqrWfLA z(&5+s-Wh~GNc7@_tD(kcwu@8#aufSX!WS6y&masy;$CAZ zr=YdZRlVUn!+DgiVZ<-H9ujkMPpL@g_&8gwi2x=mcUbW0&@r7PeU z2JdZqU1^2jcEbq>Rm5`SouLDhn~AWa@8h z@3}#;SJ=Q&7@a0glIXm_6PQHCV7!UxidvnJbbf5LMg8QYtA@00rY0XRT=AV5jxAez zM*yp~r$jbB9S@#FCLqBar?H4$74Gd*Mb*LRXRQ#be{C{4bzzJ;`%`-e$_K=3#-2? zbaY=QplU_xU z)k>#C8U6q8BYfu_^;sX`n@-lfGpjYxva0lE?cl@6z2WCR1xdeURi8att&DkP1#}oE zb2Kx*%UgoNC5k>2R&oqSuhlT0RJk6No7Ylw9Ntb6m3W5GG^~f_a8`LmIV4pz-iGaS zds+(Yg(iHDpDfH0bZlgOEeK7$yNJ}dS)WEmUjBBt(n0s*SMbZBo%t9#d5i3FrU`vu z)N*nFuhkD{h32=S6-A^zrv|oOc2QeM^y!;D&X~MOH7$#TSkaO0g@H#x7Eh+Fr^V0L zL5)0eH|LjX;NcPd^Gigy$3^-7KEik2`NR57!~&S(P>K+D>Or!}y96pcB<}WZvlGl5 z7tNdM)_zlY8E_yW9PPcYMn$(pv#)v5W417*mEw#2B*Xhj|3TsX#-4T`B|1?5b8=#I zd2hw}bXd9wn>~dn8>AiLiC4Gxvlk5JctWZ(*)IV-)k#y<`4S~2|M$3TgfCu&Rr=T& z-&33UH2OgD?L7~s7b;(YrT3Gj>u)b{ckeeEa!>-n6B=S_3^TFCz84>WeL7s-@Nu~b_egJ&uF(P{~S1GGhHW)gT3!YiR=IY zFhJmYWwT1`AgM}U%U_L-F)<8nZr*1eQ|K`3_NFhqHL>FC;k#E?i|zLxyO4%VQX zY;^CbeW`NAO#7{^fb(^R00^Znc)z(P8UtN}E8H&9j)>4Fb1`3AmIyQ-AbM;YOsq~1 zpR&3@0E9x9d|FP+x92p6JUlMy{n38(r;#g?^Bf!CSbXY-ZdHCwI_0HMsq`=*hY zV`SU+}>9juve^iOqdvGn&-PnXzKz2#}TNT||<2ONRNY2YMj z&g*GUl7+361m6YpfdB|4EzVzXx}8IA zBxX_em(Ye8rYvn<-K;|r9>Kh#Z^rEADh&M1A433yf)?q>?`Cx>I>fx`D-=(q#*H+o zvx0CA*aGth`*;Q|@!`9nzNdkA|MfKIJ#$Zz2JxePa@b6+@2vPa@VQnK+WNRuS{Xl< zN{W!=IK`>_2e_|Pex zo8G|`IO8W!0il}3P(3bPTHm%qbg)&_Ini2@smoX=P%2lOfQ*sB!weI?I^qu%5Qgi@CG7m*_z_)SgFRa1(uezw3)!cmsanXV{e z$PoztKyU-zVFf}3gi01HAxcgC%K-(WA-5Rqu8NBM@)9Swj``-%H+Di-9;8q3eY+s2 zfKbRnoTOcn;BNg|uQgeC`%>+PX_}7A6uh=4lc;Y>`CnASm#TtK3n$5Q-YD!}^3a1f zJh?JqT|p0%#1c}cstr2E_QyKO?6)t<KmQIo@v@fYF>SW-) z@OSsCnV%ZUPy8+TMSBJn7{Fr)szCO1K6>sEX2ibcIj6dHfu74MlPi8EU52WkrD_4b zP#Fdl7(wBU-+UL*y~WtK%cH++s_VJg%qCt~G*;C<=%P;#)~<&?DZ-%w6DahTH}SFg zUDvp^N!;njXvMadHQlpS)Bb6VM>ry5^*MZ@Isz&H!|4A8nsGVhXcv6V2z}f!IJsU17*%$g)yc`7#OxoY%yYjf z)x&p6qfUndk_VxDCBF7ho4@xfi-_cnr-#=zdK1ZqliY&~gGwWcjgp#nnfirw}U{}y_oSWv_$b??V%I&!bX(DsI{ zWRbrp%&?E#z@M6NP=O2l!wq8Jmb31pvVCuf(}cW|^GVrbV4h#_cy6Zv`7>de7<|Jn z9x5PIuCUr2>3=I8aqT8`Ho!CDmzYBFa`drZ>)6Mbdf#r<0ei)n5;*}XAQY}dTREB* zIAle1mnfINed#D79CdW(wzU!}lJZ8~kA5xqj$h(w;Usy^o2mUv9&YfICsx>US-w=^ z<_wABSgmOi5g)A*$<6$le^MD)LXz$X-=Ru69S%qygtC<}R9~4*GBa#1T()%jhE593 zCdMsN`W&s6Ue!zOTj*xMDZhXUyx=j&b`d`f-Fj|XvTsz&b?vEUVtAUh5bsATtAJ_K z;*mD^cqthwAQY|GlVe3q?{fGcd*++UwKg!uP#K`768|l=SO*1J%W z6N=pOnmb*-`o3<*a?Dsrb#H-hlBPiggo+hW-oI1c+suPk-!Pr4gVZ*@8`k_%0ai{0kA`A$E~~Jw+9_w1GWg@be&>!7 z`Q>ThBzex8yZ=ibgnAVk9?RL!187CuU+^m?Qq9F;rQ_Q0yMkwvGz?yI>^8%vR~e_n z0m*|+)9t>c&N-{G^t;` z%HmQKrBG&3f0PnR7=P4j247vsJuRHPRd(J=AuM?i7u7aQKGy0psnLx*T|(LVG3np9 z>@!&S1v~v^48@#p4++-A zHwaA$KQ-c*9AV2jS8m&r3U9}<-8ViCp?rp;6fFCAv%4q(q3OpOQ58B5>=!Aw46J*| z-NZ)2msHntEHw=|?%~&$83MaBCkLP*y(h?{@seCca_=kAYgwh8rHf;Yg^9MqD$6f) z2>;F@G&M&%;4m-Go7>rOJTS~Bwy0-+(rTtCQt~c%UwvEu?N@}RckNoX`FNHz-`r=% zxv?m^?Y1wvDHS_{?zx!nOf-iLL^o2U^s-T^@YxV_dq=EXlV z!pEHaPVV6IuIj%#_$EyMZ?JQr^!pf}cdv#~$X`*z@KV>x@RT5Y?J5PT`Tlo7yhrfA zdEV*2IdBI{f`X`!95x~A&T1V0O{M!hb4ICL;XZHdl!gDMDRu(pi4t1?l!U0>K+L6!wq1^&c zouB+zsix0z;G>UHsDMx&gY13RrvvNm(Yqat8RD{tyfV9cb!GEq(Nq|ZM%SlM;6t`D zsDMx%Ll?M~v20^>UqI>ZTgiw)DUuc4TVrS+QY3>Kt!ar=;m1%86%dMJ*jSd{lpP?E zzstPPU)d|SB65)SIqB#*#$z6g9Xz8s3m|zapaMc|OhXeo^`c{nCQBiTlkXKNeVIjc z6vm>Lm)-S?bvsN};9HuNPywMdru^xUwd?>UCjPdEjHW`3T98y7HFsc$UFyXZG*j0~ zC*T;WpaMc=%#!psK$7(FGys@_cs%=r=|gn&?eS~y9b^LpNY z$%9ZBqiz$$k2)&HHJZ9&WH!0Rl34q$`fH@*xPc6P8(}OGeAZHPIvkKZ2z4>n1AeVs zH}4WN$H|sL~%kQLBXtcfbVB{W!7zL8)W<-G_K*`6Rp! zc`@^w>PYU1P9#1ptjrSdI*vN1fKU}9mE<3z^5EC>z1pB(D{2?mda33S;g&{1+E*xZ{$X(fKU;WjPdt(%hI#LC?-5KvQ0uJ8%#$Bb3q!z z5jQ^VxJ^a)S-d|joFvbA&*Fc{gHRBY`#`^{bNN%!l=N}5bwN_YZ)TMWR{oE(^t-+K zFDrj(0~f97bT}Y+5b9w{Orj4-dpb;0XD9!F z&Q=~BeOO#4b79aNwZT?m1M`EQ#Rd4@KnqkrD25@!u+-St zX(UvGi$1sh@pnGpELx!gLM@D8#GM=S&)w{07?#XvU7O{oV^&OfzB1KbAjGlCz{P_v zvwnmM2&FK@y~4xRkLNSGA|j+HkL~)SM|1^$=h4j0f1a!BE-9KK0zL_7KP{Xj&v~P>f5~GEhWk+V81r{= zox*@~P0Z|Vi!lEhyR_H2s|O^ikMD*G2sJPjelP3j4H9-1 zgjOa3z5ZyflIcgp{~Xy^%*?1=FMW#*977LOumq1m1M}!zy4scenZ4T|uRW?SlYCVz zJhxyylxKCsxu(PfAM^A=1uIY(6+wN;oA6BG@GnsulX0R_eWhGs?9dz;Z6vo>WwARW za14E?g_GntZ@m65d91;3yTgIbRTrom#hPa)9ORZ39W;rBt|^D1U9MP9*sxE6ukC$4 z9S%qy8&JT**UGkVU`aZ}L#>JIeQL>B{fq9Ce%NO}OxM@PC0FhP2mA#p*n$H6n>EgB znwg!+*2FGBhh1d2bpDHc_F~#gnN=Tabco<%o_?rc2MWo7-?3P1KHJYWc4y{~^;Wes z_#a)q!$CabNyA|K)ek;k9)Jq=pm6sUU1+&-p>lO@oqJTHVxPoS{mY5Y$v8=lpX4SD zTH&i5U!j5nD7+_(_!Jm`$I#2q*gw%IUh?f@S&jiUHp_s6JI$Z>DeyI$L8x#a6c#XX zqV%ipaLZKctb~2#Xf^C`CRrH2qhh~o5}}mn4&SU8f(nkHzz~fi8?C(Ye)kt^Kt{KF z3qQZ?!a=Wds+}WVz3$sG_~U!{v~ZF<=gr{$C65yr?%LBvvNqLb(G7bpNrpqS}ui)+)xiXpidhpND3pM?tE zpb(m}DZN*-Hl#2(@alz%8Q#VLt{QRB{VDd-Nrx*FG5+&+BZ&Lb-PM(EYFL0l~ca^}}u0F`cY+ z{ZlQhG732+_0UEPR*0Jx_}7_J10??|7{K z|9{|IWREg3Lu5o&GRod7WF>oNCwpWQkr5doWR#ITGAe}Zm03pi-ZDb+>zq$I@9TSA zx0_#o^~Z64p7A*6yw3ByuIp0vTnIJ)0Nj&K*Hv0gBSr2td4l!#Bhxk8;jPxSSeh$i z?;;$=NyzIO`xE~)+s@jn|IT2)Kl{9{X z@~$BY!I1E}aHxVbzNLcZK=@)x%J~cZD81>emS&RtD%s}f)wAIFw~i=;K*A16pJ##p zZLNTP$2=Cfqn;8z4GY>kMJsBWWa_z=+Tb-{170}2{GWB6{R($BlX=c^25(4e$ft|JqUk(UQC?s6JH^Jq%`cAR@GRwyG8{z43 zj~0ZFW`&m1zngnezslzVge^oN3=*`Wim9|#MOoN+7+QEn_A0i&6Ytd*&EMX0{Hn=g z?QaYS+la!`{|J04f1Ws64X5=vFmNNr#~IW_oJCqU6nt9V<)k_8fbsi*D1<|Tr9=L8 z%7wJepCo-l2h*l87zaOxol4O4xj9X0-`aG8cikOCAp#P96Iffx4*Ooh6J2$d=vlm3 zjDJjlrohWWkn_dWJ-H7roQCJD zEAPMXJcG*dCT+WEvv26#myH>aG=ECyR{JG_D9eiAChgcoC)WFpK)Ijr<$&-+LxRqQ zVRt(;oS7E~cdVX4!Y$Ji7#GuI@YK9jS|NDla14JPP63WJRJG4e{mpQX%_0e^r z@EAYbcP7duE$F+KpZYUf9vpZcA_~tTflzvdYFzCXK4a&jjH5RDoGPAYdz&b^j*Eqa z6-!4B;O8Zd5QSJsz@PDxmgLw8Z@6)Aaj*Y4pq;~8m&+iie1;gU-ejmp7uXNK5QR8M z(DPF?-1|Z|A5Qw#K!PpDjZ$s<Q%0m5%YApsJ8;0Sc(%JP1wYB?AGN?^Jw*5e0kcmBd9 zMxr)dF7agW6gYtwPQ!E7z4%{vUO?r3zg_luTPt6+L*UXxK8(BiR_${0(HfD)c%JH= z0yMurzcxStLxC>`ga>$s_4nG<{FECtw$r0hFhg8uQof*`$0aDhI$+7-7ss*C!|Gz7 z!2?4@6p|p}ZCv2flcCJ@W=3`D%`g4=QgwRnv|FXk=WCXK>>OOs0R$MLkPHcnJR*xl z<>eKRafwTMIOjSdb)CJsFMpI)YCBju34QDU2xy4HOGp^~dB?AcCN@oC%a>t>zm*D? zeEETVbhHQ(zf`s$_RXI|aV|gjR-{7+(i)bwNjt3R7KSAx5exspev40;B@DPR9kbrS5W4oNH zMtexWF)Q}Xi*B#lJYmMz+VsfvcvA~617OSp!$%a}K*Idu{TmfjPa;JF1w~~1+=Iob+$C?+a|jF}U<8OlHY6DF%Qo$}TIf+fCak;B%Ul%}~eS^{&x6$^ye( z*m?MJKzMQ?0b}`C{K05}vewa4tP7H3z)VmW5uyN0O!#~C`@Y(yi!N)8a}Mhu zy*@KzQ^j40$o0yB-kOKe_7rw^18YSLzck0eQ7yw)0# z&uzBoy!+(njy52WAPNPLU>MP`>yRKJ`MnU!<*{Oi&v*xCnU%&tuB7O&Z7P~6FgpZB ziYNdxG5&5vmlLgBUlX9B_GgM#~5rra1Fx0qM zDznErwp%G=HE3+3N|w5wKJd_2@hvmKH6E@PK-U~b1}~h3=d35Vf8i;H%86Ck?DDOR zH%#wk>Z03Tb!x51m|L?SA?nS!F43jc4tz8cMh;&N2u}$lJSk&eqj^h|C3$4DGL?|v zg!V*`Hg_m&&AXZPiBFIK(CvUxAPS|BaOs03QT@BbM2p|3Wu2JcTrP1k8HZTRjk{bS zFRG)V06w$?qeK+SAYm58VtRpz@AoK;`7P(A9sSo#)|5J0agCG%<`D=L!Ng_faVmVKOJCH=iGy1~jVM$=LIm+@u6!?wk_&x~ zQL66M#$>aLIk@d8O)!VFM%ZBmc6T_Ttc0;gk5uKJGDDKCIlGn!sro&_mE&rc-Jnb#`=6Osg{trFk$+82T@tI ziEXJKToewI0&NLEU_cZ;KmzW_dm*W)Jo>{1Yn$7<+?o^b7US5Gt~Tz@R4Ms(tO4yh z*cC+KBP2xDdFIE9?#m88Oqmq^1o9V1(xxbAozTaXA47!ie9NZ@*M*V*0J zAn-ZWHf1{jA(p>EoQiE|C2!Sb@q)!|e{d_95QREOxR|A5qt%LK;ngg;5$!GE{%w;q zuw{=~ronD2<@^yo8?X+{@WN@c?W|9${t3^2n{6TWT>koo4MUEx5^7PXXsTleJYh>>9o~k+_JdY8cY10yh0|tJ+!azgR7epxgEZ1m7G#0^~gZ;e-oq}ol zf6cbD_UgYgxc-m+_kLB6Ekmx}mw3{?!{uOv%Ayy3)245M&5UFU=kRBUUnTH@AI1WI z%z-ob6C~s%OV(d@QC8a(w(bxTjV|yiX?OB`e<6{7z3cJkC)(i9^(vy!010@~X+ASc zL8YGgE@?*Hk>%Ki%UE(NU&(z!e{B-nVgRoJtcXG*B&f#idBpBZ7_R>K{?jh0zJ@92 z^Snf1*5Jkuxo}qRcR;5B#)c>WjncpSK{R+|RXSysk&BMM_N}VSbUHhyiO1};0jtcI z!-_o@c=r6cD*vDF*(LuB3Ey`(*Ujn*`+sg232)Re0nUb?NTwrBselP%8De1JzATO7mf0!jEoGT_XrfebzK7l4n&~^5>lI~eTjUw zOP;v2P|g#uOp>$`zrB}^jvjc=0{2_#9`K?L#tAQ+UjENI&;Es{6)HFT@D+K2fMI;! z%UD>qlq9iZO?%5lM$1H#h=3HraORx>O3X%u_xTz#{y#b(-; z4v{$z6r5kV$>XHQ3pBc5+=xOuB$ORX*Js2rQAaV9rrj&u;g`y(vsGKtU1bl+5_~yJ z2j20nBMKdmP?0;_z>?mYE7QQHkq}wyWI5L88g)jDBl zyl@(xv#z}V!qW?tlX>!)vEIH|ywXZjYTnt>A*WM3SnSRlwG_-B-y365!Evqtd^sRI zUm(Gq&ny8if#qtCw{p(BfdjVtmy1)fs&=N7vdopM-cjJ_<0hie2MP7!leU_9ewqtJ zNxB0`8h@_-k(xIxQ`IILFL$(DxO)}Y%1qXP>`*X;niE}$ zg)ukB*neZGW)3_B1QCS+NN_Lri9Gn=n0e^NQq$bh+mJnC9`cCxC)-NiW)PM`3n{P; zLWsg3B%tTExaNli%RQmzSE`ahi4SMk8A;+k>Xdj-8Mael0FFL{5rrX0pj-VKHqe=? zMNILKE2*+_<#BCTSX0SeMU9K|_4H+pz{?7l2%<0y37wc$ILuN8Me3ec#y8M~z3>B- zY-&AfZP|P#+~s9Pf!D4uQF!4rJZIgD|Apr(RPMvr1hwVrGQ-`F40ocJY}tE12c$2Z zA6JA0;@!;}ti}M!iNTix!t)Iho~w_)={rATD$=~&Lrb=}!K1C(%Y7A53y4H1r#qx6clEySE?rFvLN%+sfXATKOVH6TLot>Hz zrAY$kJWed`9^CEuc1iUbrHuC~o42381_UWYVH^^edV+no)jQ$`clTtK37lwj#t1}Mp1yD$G0lqz zl79MY>ciQ39jEG|ByY4rxY8_S=*AXmzFHfFOe?OhCe` z40fF!rJxu>E5Wy1ia4n4Prr4PO$-j*b>s1);<`rz2(s|PX?V^Wo&5{XBveka%@LP) zOyu&CJb7MlGZkG>J`U%zzSSRBr%`l1hI0cmVqtRd<$&-^LBepGhllzSCOh@))2);_ z&*I`fVvZQM2F%|g8U5-VJHV?sm^`8|4GGh>UTC2<%BG*lqI9WbFT z=)H^Lu?8M`1w>&660$}H?>xDGRq5u*7@Y#?-bRr>ZET}^dF{jgI<2M>daz%jh$zfL z!nANwTifR=elKp%&6IpXLs5U87U{yz6**wO%>L_I3wY>nBMNhnAQ;Ws)}D7RP-ogP z3|r>wY$En6%e@*U9#vF=)pC`TbHIL3LKNm9VO3Zg-yt)#P?0-V?la2|ooPXV&AQo0 zm*C=&2&|L}@W!W%C@esNJn_yin`DeTH%!VM`A1EJL+`i~P-|nqV)}CUKwqB=8~~`m z3#Z{ZYrOt1Jd04dpJXSal)dtNb3@d@j4hfHLvE@3LTJ(auAwib+6X7CfK9#wUk(V* z5+qQ2==KmVvJ~{vtvQX6yy%&T%&ELE8EG9Lzh+h8X9BkCR1t+`Na%d?-ok|rwY4q6 z)j8n3Ng?0;BO#_8?45f1M>Px0p}>?xm>Qz60tp6u3B^{Hqoc9|R|(d7QAp8p0l3d{)J}~Di?NmOQT@VBx zw!lOms2 zSdRV2a_wLNN#Fc;l&9e)@3LC+f1Hy9v37N(jw_Q8vJY5K{ z4!o_m&ZmEn7w2I(# zq$jK|bH5pWcnMes6GQ=M===@Ox;1`<>GK!f7$}7`)2-hAyC_n&3I!eo2ARGOZmhzz z0l^ee_yr060teogbmXXuL#4kApmuF!ZC=HWq45fNyd+*n({^4E5X=yTV@Nn!H??MH z%j5t4t=vV1=}0EIyLy4goc-m!xG)C4=uYs)XO1ZRh6L`#C=>UXu^~Lqd5QQK)K_9v zc4jMjOGR~CS`_2lSzy!gKB8~}2|RC~H~A&sP&${ATD;db(~&~9&BajPM2w5ZJ22Yp z1x&1jS-=aY&9<|?@9j@`{@ZN(X8t8C+SdD)5|#%ebz??RZRp{6piN)yf`tT?gpdkw zGd^u#Ii_;Et@;=U7bb+xEJTqC8jvkL_|Kwp0%2F^4bkdp{T=4r zKR)Hjyscg{w)<^T^{Opwo_UAjKZ{!3qT{C9E~Kx@zu^0;MGyaC@YwL7^s8HG^|>Vr zc0OGHS#*+&>1EX$JSJPQ*I$2pr(|2yIT)ql84Q|DRAqV!7>; ze4@P~)R7lD+7q$Po~7I0TX&q*1|06w&62cP>4{9v?fpr_@WP;*8+Cw2%v45?E}ZPy zoo5C7*+8~V7lj>@)tUK^HNdyesDnon6Qied<7T^k(Z*fYrY*Tt92Co}R&Q zKTc>L&020V_}Knpe@m%SP~DSp2IpeMW^_NfJPa8co|oW5x+VNU|8ok%{WxK^*FYNU zidVID3Z5ZNUYPZ#Z|#_w@!?GUt2$!T_1KC)Zmf_Hus<95_Z0N1CapHx`60iQuw&M= z?5}$+nlX}SEv+^a{Y+y@igbNuo z*TVGI*}+z^4H5z!B0Sakk2cNGCHma?4T$lL?n$bjJX0r<5D?NYQ5z+i2fJOiNQiR~ zk*Y0flH_3%npq7STh>*UE7DT+bIb8yAGNhqtlr zo(#mJkh@?4zvBV3hbJ2UeuL6k=Nl9vET~@UrDspZskLY0EgS9KIStCZm{A$)T!r2- z`SFd|3Xf9)^&Z0414D!j5uasM6O&5>HTNeJF-)J1vF^O4^^+-{O}zzsb^G(fX5e!* zFb5)9FY*X5b?=zX);Da zuft>y(=lhg%#EcxTwf7e?JkkA4uP9sE;#mgLPFp{M5^mZ4J~u#6&rycUc|@ElvCnI zB9*Umzhml);;%SU-~wymjD*042rK7mAA(2A&wdHd=yKl2KOV9^Un1x?EZ<<4uPHx& z9qjzNAR!1KBCB!3GlM)V(4E>O{c#RHEz^wDsI`lu>2Kr5)l1Vs-U83oO9K%5;N^9#~~}_BOVe9^O784ydsN2w!;O zG(>0JqoELyL-km>O-E+by?>8B7YH^{EABI3%zb&|NM)?6{{%yKcTNPT=LcU83=uFm z_)am+0lZ85OFXJGJVxD3 zt7WYJ%6Zcg`)Spq3Q_5rX8&UiMvl@Tbuh{SNC+y35bSPb5^)H){k)U?sF0$LX)8CP zj_5VomcjKkw7%vQ@bCp9A*dnZdt`H2P*SVox&W@*FX^zd-{lXURPDdqB0o5E^T@mc zb|iz45SJjL^tM27xPy*xmxzl@Sf|i;_Q?4qN3|!D+bb0HZb}!ySvZf85Ht{RROpQR znOX2%u_t+U{4{tQDoa_DS2Q1Y<{B(fRu*nwd9$a4%%q;en4OVMquDh_Ej< zb5#{tLW_h_oTk=@7S zP;u~AwXy|>2qXj(M08NJ_>W8K-O?;IPgGs{dIF27&DWLau|E&2uLDFBJaHPLv&QvMh*+R{J^~Xp z3gQ7hS6W$Q3iPNdj7HO>6L9uxrBhM|9c}1!fqKv2>wzJ<3K7_b@)-qM$}0Z9N^9vx z73m51UHK29*m6P)E47mQU4RM4uxKO%D@0h_qJKEYve>ngJGWdVu|+1xW7sNsHR;OH zv16KVzXAA8AqEM-1`#KAq1Q~hWu$rLnd9d}F73NB%+k!hMx!uW7|jZPRsg;beU5~< z1`*=dxlg*Yn{Jb$3^VNxe&x-6B0a&uf9=`5@QI*kkKa_lhQuNv*dd~*Mb>bfuVhRL z<$H*lE@zf;VIX~Xf$Hbd{JzH`cPYRS#UUX$AY!hgen)AzgSQH^)hu{E-`Os+D>l}z z+xFIT>2#81@P}(*@kj_xhzO~_$kf^X{KGJVM^ENUyP+KSK(ihe5y$6whu4iF_7#8) zNq{F#Lv+>?9~2_s>GSW6#95{Li-$7(d%W9kG}=}uVm^Mq|CA4_{83Dk=eWVO=ioKq z1$;d)MBEUel%gZtET*DPToUr?t@1#i_sYI@Zp+&D!6npG*rXx&fR~7bxDF9!>f|Qv zPFI^$`$ZWSpQ#ik*2hGocz3J{&YMp9smz0o)g&YY4@9gCKA*|ykn<}zHhOMxy+5q^ zW#j(0Zn-Rv4h8ZM8&U8|l#GP90TKDht*f3F&B8T3eZoa4uPBQj)#Mb`KYXk}=NLLU zP7a3XB@%)cA`T8!?L|nmq;Sim9%yI#7{**Ec~9sn<0@DM$!Dh|m+6 zC7`2K`KfMXyWIM*q+qx87Q2B(QQgbIq9yjYRl?4ZUb z8zn+n9N)rBQ;F%{;NuXDia2ma3O5rH z-8BGTsHGzzZb8INC5=UARx%7OS=~%=JQorv0*sWa(yoS4n(3ij$vNO-Z3YrT5F&;P zaFSX&sJ@q6@m|vmH=3p!+T|B*vw40WeX6%UJOsQKWg;PjAR_yDz=W!QjhP*8#=GnB z0&;};9SY5FWQgnTJhDB{Und#V@2&@1HD^o{fN6{e9or_adqxO zIzi`$7QrdyuaOWU5TQX;z7A`?QksMp7vWeG`!VWL^w4rTp9p=*jDkTmJvhXCgM<); zh(4w7qzq2&{xr?*i*GF-&H*g zfI-aZqR(GVFUra9N%?Yg<-2i|HuEy*4%daI2$0J@pRnIv0{RfAi&~((a%>JwU6ncb z)j1V(EHCzIh~CyPduDB;nKw;_cl2Mc?5vG~P9(8E{NJnb=zHP%x38W#OAGPjL}P0B za3o<+6YCgx^2U+t8_WcP;mLvD=irGX4iUj@Nh-lPSBohI%KdwJuQssdT@JV@6}%aE zTc>Tll}ZgbY`I7X35a;wJ7G4(Dkt-+Av%`-OBrR#M4M||+*P7DZZrQRS3NO+$U{O% zLPV0(otq{Wp(tLe?9+opZ(BossHLloui?+chXl-QMu9IH-XbBSAmSj{$QG^6e$;E` zR@BIC3;i5_eraqQ5|sK#lKH3-XYh2+M?y$L#0_cTxW#0xYhqeIhQ+G$9r!su22Vb} z5--+&hqK{vJNRr^fP|2Nh~Nw7TW_?QC}`U8QRft!5{lKdRk;Rdh+E#)+GWAI1HShu zL_)|yM7tQXBQ z*Ur{+K!dH43^;tn@b$nD$wP#p{#)G`4mP@O z-q%tt_GieE@ea)u~Hj2k4BG+jXa`5t_!xveIzj+l!@G$~w zQHF#7I_7^*C{h7_)!r7({H2KYq}0Fz5v-o@bmpnF*L))0D!#VH;260a384fLy}Vj8 z3Vv=X$K?Fj2HV5;^;%c)dT0{s_-F~g=DB2n{hA6Sgfc{+?C__U$0jsvbh58vTvW%n zrkMI_xsY^1NJwDg;|875A zV+y7L_eCWDJSYvR4h%d=h6j~tZO^~uCBW(?-#F#xu@8VR8W5!9yL zZ+5g!GDa>rDP_N{4*8**PcS_fMD%`%t|F;c5N!O{AR*KtA|jbAzLa8Rh)&?3rR!~* z&<_*F-0w=U@x+}xTT+8f;G_0?B!mV;&^;xrV-pN}zYy#CgMXRl!$(Zs))BKZyZxTH zDobYYXEIk$7=!WufQj-VeWlc8wYf;A|dWV zME#&rLENg%hQtanUM10$4rI_hGY+4Ev{It6;ux2@(c@i(d>o+L<15+ z7b2`vQEAd#B~YT1Zpgj}$~u>FE=$jSj%-Fa&J5 zHzOeoA>w4y#&lHfcY7}FIb-y1RW*YsH&9IRuX}m5A1L}Qo&!Fg4r_rYPD6Co;0X$m z5mawAmbo%0$@gYpPv@r`$(8hvhPeZ;#|e!O^M&yDMT+!*dadyFzz`WjMC$#P7Z#h? z78~;Q65;WJJdaE0ZDRBm#}o4M0?U|4ZvsRc62b%`-aU|qtrufp>+G0W58~-3n7EI6 zPdXGfWyf<7e5&RJ2h{CI2vdl-9KqaBw?qZd(36&uSNN zE<*hlpjhH^+MhVpKQ z?*FF!_rMc6|N9L>4x*j)k$j8>bo`wdzPtO|L!T3=$elAe($tD)BaOd```_b6^VgS- z_Tdn^zq(|ky!D~>S`F3}Vb)yY?!g;b;fGxKr<{~L+|Ah0?7#oN^}kK}z=zHq zM8b$Z#KN!PxU3*{;=6p)=&p2&>r`M3Zb)-xsM!DhDWIIQX)$0oJ&%HdBK*HU#n#t( zZ*r??qGCq;8o^Jr%^B`i%+zg)mF8ZJ2^5^lR)0-Y;VKN?p{Xo$tNtXJt$}FvNW97m z-v9gS2zvtTNol^vRsNQ7U3atBIlGNenAREcrS#o5={~iK1^hW+rw=};T`|66T^<65 hHP=P1FW^aOP=y8Vj>TSj7Hn?5p|b^y{QiFz{eKuB5d#1K From 7c4225d01c8239d09c5192bdae568730c79e15b9 Mon Sep 17 00:00:00 2001 From: Mitch Wagner Date: Thu, 18 Jun 2020 21:31:26 -0400 Subject: [PATCH 214/379] Remove redundant glossary item The excised entry previously rendered twice in the glossary under two different keys. This commit removes one of those KV pairs to avoid that. --- documentation/en/.glossary.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/documentation/en/.glossary.json b/documentation/en/.glossary.json index 41126f974..bdc43e319 100644 --- a/documentation/en/.glossary.json +++ b/documentation/en/.glossary.json @@ -63,10 +63,6 @@ "title": "Proof-of-Spacetime(s)", "value": "Filecoin is a protocol token whose blockchain runs on a novel proof, called Proof-of-Spacetime, where blocks are created by miners that are storing data." }, - "lotus-testnet": { - "title": "Filecoin Testnet", - "value": "Until we launch, we are making lots of changes to Lotus. The Testnet is expected to bring a few significant fixes/improvements. During Testnet, you can retrieve test filecoin from our network faucet to use as collateral to start mining. Test filecoin do not have any value – the official filecoin tokens will not be released until Mainnet launch." - }, "filecoin-testnet": { "title": "Filecoin Testnet", "value": "Until we launch, we are making lots of changes to Lotus. The Testnet is expected to bring a few significant fixes/improvements. During Testnet, you can retrieve test filecoin from our network faucet to use as collateral to start mining. Test filecoin do not have any value – the official filecoin tokens will not be released until Mainnet launch." From 5e77b5da9f2e45377e76087a93193af29821ce35 Mon Sep 17 00:00:00 2001 From: laser Date: Fri, 19 Jun 2020 08:51:06 -0700 Subject: [PATCH 215/379] bump from 3 to 4 digits in format-string Fixes #1993 --- chain/types/bigint.go | 2 +- chain/types/bigint_test.go | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/chain/types/bigint.go b/chain/types/bigint.go index 22ecf833c..a7b25870a 100644 --- a/chain/types/bigint.go +++ b/chain/types/bigint.go @@ -76,7 +76,7 @@ func SizeStr(bi BigInt) string { } f, _ := r.Float64() - return fmt.Sprintf("%.3g %s", f, byteSizeUnits[i]) + return fmt.Sprintf("%.4g %s", f, byteSizeUnits[i]) } var deciUnits = []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} diff --git a/chain/types/bigint_test.go b/chain/types/bigint_test.go index 2f632d1d7..43e5633b2 100644 --- a/chain/types/bigint_test.go +++ b/chain/types/bigint_test.go @@ -3,7 +3,12 @@ package types import ( "bytes" "math/big" + "math/rand" + "strings" "testing" + "time" + + "github.com/docker/go-units" "github.com/stretchr/testify/assert" ) @@ -60,8 +65,10 @@ func TestSizeStr(t *testing.T) { }{ {0, "0 B"}, {1, "1 B"}, + {1016, "1016 B"}, {1024, "1 KiB"}, - {2000, "1.95 KiB"}, + {1000 * 1024, "1000 KiB"}, + {2000, "1.953 KiB"}, {5 << 20, "5 MiB"}, {11 << 60, "11 EiB"}, } @@ -71,6 +78,22 @@ func TestSizeStr(t *testing.T) { } } +func TestSizeStrUnitsSymmetry(t *testing.T) { + s := rand.NewSource(time.Now().UnixNano()) + r := rand.New(s) + + for i := 0; i < 1000000; i++ { + n := r.Uint64() + l := strings.ReplaceAll(units.BytesSize(float64(n)), " ", "") + r := strings.ReplaceAll(SizeStr(NewInt(n)), " ", "") + + assert.NotContains(t, l, "e+") + assert.NotContains(t, r, "e+") + + assert.Equal(t, l, r, "wrong formatting for %d", n) + } +} + func TestSizeStrBig(t *testing.T) { ZiB := big.NewInt(50000) ZiB = ZiB.Lsh(ZiB, 70) From fbeaab466acd181f5da39ffc22cd9aa97609bf8a Mon Sep 17 00:00:00 2001 From: laser Date: Fri, 19 Jun 2020 09:19:46 -0700 Subject: [PATCH 216/379] obey the linter --- cmd/lotus-storage-miner/market.go | 2 +- node/modules/dtypes/miner.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 110411bc6..c668456f0 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -343,7 +343,7 @@ var setBlocklistCmd = &cli.Command{ if err != nil { log.Fatal(err) } - defer file.Close() + defer file.Close() //nolint:errcheck scanner = bufio.NewScanner(file) } diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 3f0d81d6d..584642a3b 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -18,11 +18,11 @@ type AcceptingStorageDealsConfigFunc func() (bool, error) // storage deal acceptance. type SetAcceptingStorageDealsConfigFunc func(bool) error -// StorageDealCidBlocklistConfigFunc is a function which reads from miner config +// StorageDealPieceCidBlocklistConfigFunc is a function which reads from miner config // to obtain a list of CIDs for which the storage miner will not accept storage // proposals. type StorageDealPieceCidBlocklistConfigFunc func() ([]cid.Cid, error) -// SetStorageDealCidBlocklistConfigFunc is a function which is used to set a +// SetStorageDealPieceCidBlocklistConfigFunc is a function which is used to set a // list of CIDs for which the storage miner will reject deal proposals. type SetStorageDealPieceCidBlocklistConfigFunc func([]cid.Cid) error From 6b86dcde4ac851f551b7a0549b2cd10514528be7 Mon Sep 17 00:00:00 2001 From: Nathaniel Jensen Date: Fri, 19 Jun 2020 15:41:54 +1000 Subject: [PATCH 217/379] doc: Fix architecture broken link --- documentation/en/architecture.md | 124 +++++++++++++++---------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/documentation/en/architecture.md b/documentation/en/architecture.md index 970f2a13d..e4808a877 100644 --- a/documentation/en/architecture.md +++ b/documentation/en/architecture.md @@ -1,11 +1,11 @@ # Lotus Lotus is an implementation of the [Filecoin Distributed Storage Network](https://filecoin.io/). -A Lotus node syncs blockchains that follow the +A Lotus node syncs blockchains that follow the Filecoin protocol, validating the blocks and state transitions. The specification for the Filecoin protocol can be found [here](https://filecoin-project.github.io/specs/). -For information on how to setup and operate a Lotus node, +For information on how to setup and operate a Lotus node, please follow the instructions [here](https://lotu.sh/en+getting-started). # Components @@ -24,7 +24,7 @@ FIXME: No mention of block production here, cross-reference with schomatis's min - Other PL dependencies (IPFS, libp2p, IPLD? FIXME, missing) - External libraries used by Lotus and other deps (FIXME, missing) -# Preliminaries +# Preliminaries We discuss some key Filecoin concepts here, aiming to explain them by contrasting them with analogous concepts in other well-known blockchains like Ethereum. We only provide brief descriptions here; elaboration @@ -34,10 +34,10 @@ can be found in the [spec](https://filecoin-project.github.io/specs/). Unlike in Ethereum, a block can have multiple parents in Filecoin. We thus refer to the parent set of a block, instead of a single parent. -A [tipset](https://filecoin-project.github.io/specs/#systems__filecoin_blockchain__struct__tipset) -is any set of blocks that share the same parent set. +A [tipset](https://filecoin-project.github.io/specs/#systems__filecoin_blockchain__struct__tipset) +is any set of blocks that share the same parent set. -There is no concept of "block difficulty" in Filecoin. Instead, +There is no concept of "block difficulty" in Filecoin. Instead, the weight of a tipset is simply the number of blocks in the chain that ends in that tipset. Note that a longer chain can have less weight than a shorter chain with more blocks per tipset. @@ -49,8 +49,8 @@ We call the heaviest tipset in a chain the "head" of the chain. ### Actors and Messages An [Actor](https://filecoin-project.github.io/specs/#systems__filecoin_vm__actor) - is analogous to a smart contract in Ethereum. Filecoin does not allow users to define their own -actors, but comes with several [builtin actors](https://github.com/filecoin-project/specs-actors), + is analogous to a smart contract in Ethereum. Filecoin does not allow users to define their own +actors, but comes with several [builtin actors](https://github.com/filecoin-project/specs-actors), which can be thought of as pre-compiled contracts. A [Message](https://filecoin-project.github.io/specs/#systems__filecoin_vm__message) @@ -70,8 +70,8 @@ We now discuss the various stages of the sync process. ## Sync setup -When a Lotus node connects to a new peer, we exchange the head of our chain -with the new peer through [the `hello` protocol](https://github.com/filecoin-project/lotus/blob/master/node/hello/hello.go). +When a Lotus node connects to a new peer, we exchange the head of our chain +with the new peer through [the `hello` protocol](https://github.com/filecoin-project/lotus/blob/master/node/hello/hello.go). If the peer's head is heavier than ours, we try to sync to it. Note that we do NOT update our chain head at this stage. @@ -79,7 +79,7 @@ that we do NOT update our chain head at this stage. Note: The API refers to these stages as `StageHeaders` and `StagePersistHeaders`. -We proceed in the sync process by requesting block headers from the peer, +We proceed in the sync process by requesting block headers from the peer, moving back from their head, until we reach a tipset that we have in common (such a common tipset must exist, thought it may simply be the genesis block). The functionality can be found in `Syncer::collectHeaders()`. @@ -90,7 +90,7 @@ drop part of our chain to connect to the peer's head (referred to as "forking"). FIXME: This next para might be best replaced with a link to the validation doc Some of the possible causes of failure in this stage include: -- The chain is linked to a block that we have previously marked as bad, +- The chain is linked to a block that we have previously marked as bad, and stored in a [`BadBlockCache`](https://github.com/filecoin-project/lotus/blob/master/chain/badtscache.go). - The beacon entries in a block are inconsistent (FIXME: more details about what is validated here wouldn't be bad). - Switching to this new chain would involve a chain reorganization beyond the allowed threshold (SPECK-CHECK). @@ -101,7 +101,7 @@ Note: The API refers to this stage as `StageMessages`. Having acquired the headers and found a common tipset, we then move forward, requesting the full blocks, including the messages. -For each block, we first confirm the syntactic validity of the block (SPECK-CHECK), +For each block, we first confirm the syntactic validity of the block (SPECK-CHECK), which includes the syntactic validity of messages included in the block. We then apply the messages, running all the state transitions, and compare the state root we calculate with the provided state root. @@ -121,11 +121,11 @@ syntactic validation of messages. Note: The API refers to this stage as `StageSyncComplete`. -If all validations pass we will now set that head as our heaviest tipset in +If all validations pass we will now set that head as our heaviest tipset in [`ChainStore`](https://github.com/filecoin-project/lotus/blob/master/chain/store/store.go). We already have the full state, since we calculated it during the sync process. - + FIXME (aayush) I don't fuilly understand the next 2 paragraphs, but it seems important. Confirm and polish. Relevant issue in IPFS: https://github.com/ipfs/ipfs-docs/issues/264 @@ -135,7 +135,7 @@ FIXME: Create a further reading appendix, move this next para to it, along with extraneous content This is one of the few items we store in `Datastore` by key, location, allowing its contents to change on every sync. This is reflected in the `(*ChainStore) writeHead()` function (called by `takeHeaviestTipSet()` above) where we reference the pointer by the explicit `chainHeadKey` address (the string `"head"`, not a hash embedded in a CID), and similarly in `(*ChainStore).Load()` when we start the node and create the `ChainStore`. Compare this to a Filecoin block or message which are immutable, stored in the `Blockstore` by CID, once created they never change. -## Keeping up with the chain +## Keeping up with the chain A Lotus node also listens for new blocks broadcast by its peers over the `gossipsub` channel (see FIXME for more). If we have validated such a block's parent tipset, and adding it to our tipset at its height would lead to a heavier @@ -144,11 +144,11 @@ process (indeed, it's the same codepath). # State -In Filecoin, the chain state at any given point is a collection of data stored under a root CID +In Filecoin, the chain state at any given point is a collection of data stored under a root CID encapsulated in the [`StateTree`](https://github.com/filecoin-project/lotus/blob/master/chain/state/statetree.go), -and accessed through the +and accessed through the [`StateManager`](https://github.com/filecoin-project/lotus/blob/master/chain/stmgr/stmgr.go). -The state at the chain's head is thus easily tracked and updated in a state root CID. +The state at the chain's head is thus easily tracked and updated in a state root CID. (FIXME: Talk about CIDs somewhere, we might want to explain some of the modify/flush/update-root mechanism here.)) ## Calculating a Tipset State @@ -156,7 +156,7 @@ The state at the chain's head is thus easily tracked and updated in a state root Recall that a tipset is a set of blocks that have identical parents (that is, that are built on top of the same tipset). The genesis tipset comprises the genesis block(s), and has some state corresponding to it. -The methods `TipSetState()` and `computeTipSetState()` in +The methods `TipSetState()` and `computeTipSetState()` in [`StateManager`](https://github.com/filecoin-project/lotus/blob/master/chain/stmgr/stmgr.go) are responsible for computing the state that results from applying a tipset. This involves applying all the messages included @@ -168,25 +168,25 @@ State Root (which is to be expected, since they have the same parent tipset) ### Preparing to apply a tipset -When `StateManager::computeTipsetState()` is called with a tipset, `ts`, +When `StateManager::computeTipsetState()` is called with a tipset, `ts`, it retrieves the parent state root of the blocks in `ts`. It also creates a list of `BlockMessages`, which wraps the BLS -and SecP messages in a block along with the miner that produced the block. +and SecP messages in a block along with the miner that produced the block. -Control then flows to `StateManager::ApplyBlocks()`, which builds a VM to apply the messages given to it. The VM +Control then flows to `StateManager::ApplyBlocks()`, which builds a VM to apply the messages given to it. The VM is initialized with the parent state root of the blocks in `ts`. We apply the blocks in `ts` in order (see FIXME for ordering of blocks in a tipset). ### Applying a block -For each block, we prepare to apply the ordered messages (first BLS, then SecP). Before applying a message, we check if +For each block, we prepare to apply the ordered messages (first BLS, then SecP). Before applying a message, we check if we have already applied a message with that CID within the scope of this method. If so, we simply skip that message; this is how duplicate messages included in the same tipset are skipped (with only the miner of the "first" block to include the message getting the reward). For the actual process of message application, see FIXME (need an -internal link here), for now we -simply assume that the outcome of the VM applying a message is either an error, or a +internal link here), for now we +simply assume that the outcome of the VM applying a message is either an error, or a [`MessageReceipt`](https://github.com/filecoin-project/lotus/blob/master/chain/types/message_receipt.go) and some -other information. +other information. We treat an error from the VM as a showstopper; there is no recovery, and no meaningful state can be computed for `ts`. Given a successful receipt, we add the rewards and penalties to what the miner has earned so far. Once all the messages @@ -205,8 +205,8 @@ is the computed state of the tipset. # Virtual Machine -The Virtual Machine (VM) is responsible for executing messages. -The [Lotus Virtual Machine](https://github.com/filecoin-project/lotus/blob/master/chain/vm/vm.go) +The Virtual Machine (VM) is responsible for executing messages. +The [Lotus Virtual Machine](https://github.com/filecoin-project/lotus/blob/master/chain/vm/vm.go) invokes the appropriate methods in the builtin actors, and provides a [`Runtime`](https://github.com/filecoin-project/specs-actors/blob/master/actors/runtime/runtime.go) interface to the [builtin actors](https://github.com/filecoin-project/specs-actors) @@ -233,10 +233,10 @@ It then transfers the message's value to the recipient, creating a new account a ### Method Invocation We use reflection to translate a Filecoin message for the VM to an actual Go function, relying on the VM's -[`invoker`](https://github.com/filecoin-project/lotus/blob/master/chain/vm/invoker.go) structure. +[`invoker`](https://github.com/filecoin-project/lotus/blob/master/chain/vm/invoker.go) structure. Each actor has its own set of codes defined in `specs-actors/actors/builtin/methods.go`. The `invoker` structure maps the builtin actors' CIDs - to a list of `invokeFunc` (one per exported method), which each take the `Runtime` (for state manipulation) + to a list of `invokeFunc` (one per exported method), which each take the `Runtime` (for state manipulation) and the serialized input parameters. FIXME (aayush) Polish this next para. @@ -245,39 +245,39 @@ The basic layout (without reflection details) of `(*invoker).transform()` is as ### Returning from the VM -Once method invocation is complete (including any subcalls), we return to `ApplyMessage()`, which receives -the serialized response and the [`ActorError`](https://github.com/filecoin-project/lotus/blob/master/chain/actors/aerrors/error.go). +Once method invocation is complete (including any subcalls), we return to `ApplyMessage()`, which receives +the serialized response and the [`ActorError`](https://github.com/filecoin-project/lotus/blob/master/chain/actors/aerrors/error.go). The sender will be charged the appropriate amount of gas for the returned response, which gets put into the [`MessageReceipt`](https://github.com/filecoin-project/lotus/blob/master/chain/types/message_receipt.go). -The method then refunds any unused gas to the sender, sets up the gas reward for the miner, and +The method then refunds any unused gas to the sender, sets up the gas reward for the miner, and wraps all of this into an `ApplyRet`, which is returned. # Building a Lotus node -When we launch a Lotus node with the command `./lotus daemon` +When we launch a Lotus node with the command `./lotus daemon` (see [here](https://github.com/filecoin-project/lotus/blob/master/cmd/lotus/daemon.go) for more), the node is created through [dependency injection](https://godoc.org/go.uber.org/fx). -This relies on reflection, which makes some of the references hard to follow. +This relies on reflection, which makes some of the references hard to follow. The node sets up all of the subsystems it needs to run, such as the repository, the network connections, thechain sync -service, etc. +service, etc. This setup is orchestrated through calls to the `node.Override` function. -The structure of each call indicates the type of component it will set up +The structure of each call indicates the type of component it will set up (many defined in [`node/modules/dtypes/`](https://github.com/filecoin-project/lotus/tree/master/node/modules/dtypes)), -and the function that will provide it. +and the function that will provide it. The dependency is implicit in the argument of the provider function. As an example, consider the `modules.ChainStore()` function that provides the [`ChainStore`](https://github.com/filecoin-project/lotus/blob/master/chain/store/store.go) structure. It takes as one of its parameters the [`ChainBlockstore`](https://github.com/filecoin-project/lotus/blob/master/node/modules/dtypes/storage.go) -type, which becomes one of its dependencies. +type, which becomes one of its dependencies. For the node to be built successfully the `ChainBlockstore` will need to be provided before `ChainStore`, a requirement that is made explicit in another `Override()` call that sets the provider of that type as the `ChainBlockstore()` function. ## The Repository The repo is the directory where all of a node's information is stored. The node is entirely defined by its repo, which -makes it easy to port to another location. This one-to-one relationship means we can speak +makes it easy to port to another location. This one-to-one relationship means we can speak of the node as the repo it is associated with, instead of the daemon process that runs from that repo. Only one daemon can run be running with an associated repo at a time. @@ -292,17 +292,17 @@ lsof ~/.lotus/repo.lock Trying to launch a second daemon hooked to the same repo leads to a `repo is already locked (lotus daemon already running)` error. -The `node.Repo()` function (`node/builder.go`) contains most of the dependencies (specified as `Override()` calls) +The `node.Repo()` function (`node/builder.go`) contains most of the dependencies (specified as `Override()` calls) needed to properly set up the node's repo. We list the most salient ones here. ### Datastore -`Datastore` and `ChainBlockstore`: Data related to the node state is saved in the repo's `Datastore`, -an IPFS interface defined [here](github.com/ipfs/go-datastore/datastore.go). +`Datastore` and `ChainBlockstore`: Data related to the node state is saved in the repo's `Datastore`, +an IPFS interface defined [here](https://github.com/ipfs/go-datastore/blob/master/datastore.go). Lotus creates this interface from a [Badger DB](https://github.com/dgraph-io/badger) in [`FsRepo`](https://github.com/filecoin-project/lotus/blob/master/node/repo/fsrepo.go). Every piece of data is fundamentally a key-value pair in the `datastore` directory of the repo. -There are several abstractions laid on top of it that appear through the code depending on *how* we access it, +There are several abstractions laid on top of it that appear through the code depending on *how* we access it, but it is important to remember that we're always accessing it from the same place. FIXME: Maybe mention the `Batching` interface as the developer will stumble upon it before reaching the `Datastore` one. @@ -314,8 +314,8 @@ FIXME: IPFS blocks vs Filecoin blocks ideally happens before this / here The [`Blockstore` interface](`github.com/ipfs/go-ipfs-blockstore/blockstore.go`) structures the key-value pair into the CID format for the key and the [`Block` interface](`github.com/ipfs/go-block-format/blocks.go`) for the value. The `Block` value is just a raw string of bytes addressed by its hash, which is included in the CID key. - -`ChainBlockstore` creates a `Blockstore` in the repo under the `/blocks` namespace. + +`ChainBlockstore` creates a `Blockstore` in the repo under the `/blocks` namespace. Every key stored there will have the `blocks` prefix so that it does not collide with other stores that use the same repo. FIXME: Link to IPFS documentation about DAG, CID, and related, especially we need a diagram that shows how do we wrap each datastore inside the next layer (datastore, batching, block store, gc, etc). @@ -323,7 +323,7 @@ FIXME: Link to IPFS documentation about DAG, CID, and related, especially we nee #### Metadata `modules.Datastore()` creates a `dtypes.MetadataDS`, which is an alias for the basic `Datastore` interface. -Metadata is stored here under the `/metadata` prefix. +Metadata is stored here under the `/metadata` prefix. (FIXME: Explain *what* is metadata in contrast with the block store, namely we store the pointer to the heaviest chain, we might just link to that unwritten section here later.) FIXME: Explain the key store related calls (maybe remove, per Schomatis) @@ -331,10 +331,10 @@ FIXME: Explain the key store related calls (maybe remove, per Schomatis) ### LockedRepo `LockedRepo()`: This method doesn't create or initialize any new structures, but rather registers an - `OnStop` [hook](https://godoc.org/go.uber.org/fx/internal/lifecycle#Hook) + `OnStop` [hook](https://godoc.org/go.uber.org/fx/internal/lifecycle#Hook) that will close the locked repository associated with it on shutdown. - - + + ### Repo types / Node types FIXME: This section needs to be clarified / corrected...I don't fully understand the config differences (what do they have in common, if anything?) @@ -351,19 +351,19 @@ As we said, the repo fully identifies the node so a repo type is also a *node* t FIXME: Much of this might need to be subsumed into the p2p section The `node.Online()` configuration function (`node/builder.go`) initializes components that involve connecting to, -or interacting with, the Filecoin network. These connections are managed through the libp2p stack (FIXME link to this section when it exists). +or interacting with, the Filecoin network. These connections are managed through the libp2p stack (FIXME link to this section when it exists). We discuss some of the components found in the full node type (that is, included in the `ApplyIf(isType(repo.FullNode),` call). #### Chainstore -`modules.ChainStore()` creates the [`store.ChainStore`](https://github.com/filecoin-project/lotus/blob/master/chain/store/store.go)) +`modules.ChainStore()` creates the [`store.ChainStore`](https://github.com/filecoin-project/lotus/blob/master/chain/store/store.go)) that wraps the stores - previously instantiated in `Repo()`. It is the main point of entry for the node to all chain-related data - (FIXME: this is incorrect, we sometimes access its underlying block store directly, and probably shouldn't). + previously instantiated in `Repo()`. It is the main point of entry for the node to all chain-related data + (FIXME: this is incorrect, we sometimes access its underlying block store directly, and probably shouldn't). It also holds the crucial `heaviest` pointer, which indicates the current head of the chain. - + #### ChainExchange and ChainBlockservice -`ChainExchange()` and `ChainBlockservice()` establish a BitSwap connection (FIXME libp2p link) +`ChainExchange()` and `ChainBlockservice()` establish a BitSwap connection (FIXME libp2p link) to exchange chain information in the form of `blocks.Block`s stored in the repo. (See sync section for more details, the Filecoin blocks and messages are backed by these raw IPFS blocks that together form the different structures that define the state of the current/heaviest chain.) #### Incoming handlers @@ -371,7 +371,7 @@ to exchange chain information in the form of `blocks.Block`s stored in the repo. and messages from the network (see `` for more information about the topics the node is subscribed to, FIXME: should that be part of the libp2p section or should we expand on gossipsub separately?). #### Hello -`RunHello()`: starts the services to both send (`(*Service).SayHello()`) and receive (`(*Service).HandleStream()`, `node/hello/hello.go`) +`RunHello()`: starts the services to both send (`(*Service).SayHello()`) and receive (`(*Service).HandleStream()`, `node/hello/hello.go`) `hello` messages. When nodes establish a new connection with each other, they exchange these messages to share chain-related information (namely their genesis block and their heaviest tipset). @@ -381,14 +381,14 @@ to share chain-related information (namely their genesis block and their heavies ### Ordering the dependencies We can establish the dependency relations by looking at the parameters that each function needs and by understanding -the architecture of the node and how the different components relate to each other (the chief purpose of this document). +the architecture of the node and how the different components relate to each other (the chief purpose of this document). As an example, the sync mechanism depends on the node being able to exchange different IPFS blocks with the network, so as to be able to request the "missing pieces" needed to construct the chain. This dependency is reflected by `NewSyncer()` -having a `blocksync.BlockSync` parameter, which in turn depends on `ChainBlockservice()` and `ChainExchange()`. -The chain exchange service further depends on the chain store to save and retrieve chain data, which is reflected +having a `blocksync.BlockSync` parameter, which in turn depends on `ChainBlockservice()` and `ChainExchange()`. +The chain exchange service further depends on the chain store to save and retrieve chain data, which is reflected in `ChainExchange()` having `ChainGCBlockstore` as a parameter (which is just a wrapper around `ChainBlockstore` capable of garbage collection). This block store is the same store underlying the chain store, which is an indirect dependency of `NewSyncer()` (through the `StateManager`). -(FIXME: This last line is flaky, we need to resolve the hierarchy better, we sometimes refer to the chain store and sometimes to its underlying block store. We need a diagram to visualize all the different components just mentioned otherwise it is too hard to follow. We probably even need to skip some of the connections mentioned.) \ No newline at end of file +(FIXME: This last line is flaky, we need to resolve the hierarchy better, we sometimes refer to the chain store and sometimes to its underlying block store. We need a diagram to visualize all the different components just mentioned otherwise it is too hard to follow. We probably even need to skip some of the connections mentioned.) From 956c397c3c9489b64d8c55b6a4ff4fdbb0c73fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=87?= Date: Mon, 22 Jun 2020 16:00:29 +0800 Subject: [PATCH 218/379] Add provingFaultsCmd for getting sectors information for the currently known faults --- cmd/lotus-storage-miner/proving.go | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 8d3965fa8..d9d7da8e3 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -3,6 +3,7 @@ package main import ( "bytes" "fmt" + "math" "os" "text/tabwriter" "time" @@ -26,6 +27,60 @@ var provingCmd = &cli.Command{ Subcommands: []*cli.Command{ provingInfoCmd, provingDeadlinesCmd, + provingFaultsCmd, + }, +} + +var provingFaultsCmd = &cli.Command{ + Name: "faults", + Usage: "View the currently known proving faulty sectors information", + Action: func(cctx *cli.Context) error { + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + maddr, err := nodeApi.ActorAddress(ctx) + if err != nil { + return xerrors.Errorf("getting actor address: %w", err) + } + + var mas miner.State + { + mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + rmas, err := api.ChainReadObj(ctx, mact.Head) + if err != nil { + return err + } + if err := mas.UnmarshalCBOR(bytes.NewReader(rmas)); err != nil { + return err + } + } + faults, err := mas.Faults.All(100000000000) + if err != nil { + return err + } + if len(faults) == 0 { + fmt.Println("no sector fault") + } + for _, num := range faults { + num2 := num % (mas.Info.WindowPoStPartitionSectors * (miner.WPoStPeriodDeadlines - 1)) + deadline := uint64(math.Floor(float64(num2)/float64(mas.Info.WindowPoStPartitionSectors))) + 1 + fmt.Printf("sector number = %d,deadline = %d\n", num, deadline) + } + return nil }, } From 49595965279f6ba49092255620b21b55bc0371ae Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Mon, 22 Jun 2020 11:42:26 -0400 Subject: [PATCH 219/379] Clarify expected block win when below minimum power threshold --- cmd/lotus-storage-miner/info.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 9d98f8569..01077bc83 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "github.com/filecoin-project/specs-actors/actors/builtin/power" "sort" "time" @@ -119,16 +120,20 @@ var infoCmd = &cli.Command{ faultyPercentage) } - expWinChance := float64(types.BigMul(qpercI, types.NewInt(build.BlocksPerEpoch)).Int64()) / 1000000 - if expWinChance > 0 { - if expWinChance > 1 { - expWinChance = 1 - } - winRate := time.Duration(float64(time.Second*build.BlockDelay) / expWinChance) - winPerDay := float64(time.Hour*24) / float64(winRate) + if pow.MinerPower.RawBytePower.LessThan(power.ConsensusMinerMinPower) { + fmt.Print("Below minimum power threshold, no blocks will be won") + } else { + expWinChance := float64(types.BigMul(qpercI, types.NewInt(build.BlocksPerEpoch)).Int64()) / 1000000 + if expWinChance > 0 { + if expWinChance > 1 { + expWinChance = 1 + } + winRate := time.Duration(float64(time.Second*build.BlockDelay) / expWinChance) + winPerDay := float64(time.Hour*24) / float64(winRate) - fmt.Print("Expected block win rate: ") - color.Blue("%.4f/day (every %s)", winPerDay, winRate.Truncate(time.Second)) + fmt.Print("Expected block win rate: ") + color.Blue("%.4f/day (every %s)", winPerDay, winRate.Truncate(time.Second)) + } } fmt.Println() From 8cd2012d27445058fa5730badf94ed9572612e45 Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Mon, 22 Jun 2020 12:45:24 -0300 Subject: [PATCH 220/379] doc: report a vulnerability --- README.md | 4 ++++ SECURITY.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 SECURITY.md diff --git a/README.md b/README.md index cd64073a6..a15276ee2 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more For instructions on how to build lotus from source, please visit [https://docs.lotu.sh](https://docs.lotu.sh) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation). +## Reporting a Vulnerability + +Please send an email to security@filecoin.org. See our [security policy](SECURITY.md) for more details. + ## Development All work is tracked via issues. An attempt at keeping an up-to-date view on remaining work is in the [lotus testnet github project board](https://github.com/filecoin-project/lotus/projects/1). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..ecb600deb --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,29 @@ +# Security Policy + +## Reporting a Vulnerability + +For *critical* bugs, please send an email to security@filecoin.org. + +The bug reporting process differs between bugs that are critical and may crash the network, and others that are unlikely to cause problems if malicious parties know about it. For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md). + +Please try to provide a clear description of any bugs reported, along with how to reproduce the bug if possible. More detailed bug reports (especially those with a PoC included) will help us move forward much faster. Additionally, please avoid reporting bugs that already have open issues. Take a moment to search the issue list of the related GitHub repositories before writing up a new report. + +Here are some examples of bugs we would consider 'critical': + +* If you can spend from a `multisig` wallet you do not control the keys for. +* If you can cause a miner to be slashed without them actually misbehaving. +* If you can maintain power without submitting windowed posts regularly. +* If you can craft a message that causes lotus nodes to panic. +* If you can cause your miner to win significantly more blocks than it should. +* If you can craft a message that causes a persistent fork in the network. +* If you can cause the total amount of Filecoin in the network to no longer be 2 billion. + +This is not an exhaustive list, but should provide some idea of what we consider 'critical'. + +## Supported Versions + +* TODO: This should be defined and set up by Mainnet launch. + +| Version | Supported | +| ------- | ------------------ | +| Testnet | :white_check_mark: | From 101ba0b79667a6d885506861a65bbcb8eb757f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 22 Jun 2020 19:03:35 +0200 Subject: [PATCH 221/379] Update deps to support removing sectors --- api/apistruct/struct.go | 26 ++++++++++++++++++-------- cmd/lotus-seed/seed/seed.go | 2 +- go.mod | 6 +++--- go.sum | 10 ++++++---- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 0d69174ab..c9646204a 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -241,12 +241,14 @@ type WorkerStruct struct { Paths func(context.Context) ([]stores.StoragePath, error) `perm:"admin"` Info func(context.Context) (storiface.WorkerInfo, error) `perm:"admin"` - SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) `perm:"admin"` - SealPreCommit2 func(context.Context, abi.SectorID, storage.PreCommit1Out) (cids storage.SectorCids, err error) `perm:"admin"` - SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"` - SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"` - FinalizeSector func(context.Context, abi.SectorID) error `perm:"admin"` - MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` + SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) `perm:"admin"` + SealPreCommit2 func(context.Context, abi.SectorID, storage.PreCommit1Out) (cids storage.SectorCids, err error) `perm:"admin"` + SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"` + SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"` + FinalizeSector func(context.Context, abi.SectorID, []storage.Range) error `perm:"admin"` + ReleaseUnsealed func(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error `perm:"admin"` + Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` + MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"` ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error `perm:"admin"` @@ -910,8 +912,16 @@ func (w *WorkerStruct) SealCommit2(ctx context.Context, sector abi.SectorID, c1o return w.Internal.SealCommit2(ctx, sector, c1o) } -func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID) error { - return w.Internal.FinalizeSector(ctx, sector) +func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID, keepUnsealed []storage.Range) error { + return w.Internal.FinalizeSector(ctx, sector, keepUnsealed) +} + +func (w *WorkerStruct) ReleaseUnsealed(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error { + return w.Internal.ReleaseUnsealed(ctx, sector, safeToFree) +} + +func (w *WorkerStruct) Remove(ctx context.Context, sector abi.SectorID) error { + return w.Internal.Remove(ctx, sector) } func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID) error { diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index be366d4db..08ae91200 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -88,7 +88,7 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect return nil, nil, xerrors.Errorf("commit: %w", err) } - if err := sb.FinalizeSector(context.TODO(), sid); err != nil { + if err := sb.FinalizeSector(context.TODO(), sid, nil); err != nil { return nil, nil, xerrors.Errorf("trim cache: %w", err) } diff --git a/go.mod b/go.mod index 68ac9a884..1fc21978a 100644 --- a/go.mod +++ b/go.mod @@ -29,10 +29,10 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4 + github.com/filecoin-project/sector-storage v0.0.0-20200622150609-07cf84cbc787 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 - github.com/filecoin-project/specs-storage v0.1.0 - github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 + github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea + github.com/filecoin-project/storage-fsm v0.0.0-20200622165553-628c590c009b github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index e21c27f74..79f3fad57 100644 --- a/go.sum +++ b/go.sum @@ -253,8 +253,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= -github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4 h1:lQC8Fbyn31/H4QxYAYwVV3PYZ9vS61EmjktZc5CaiYs= -github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= +github.com/filecoin-project/sector-storage v0.0.0-20200622150609-07cf84cbc787 h1:MOnK9/z+ELvPv3+jO7GwnEj5d7tBdUvP+asOj7bvpog= +github.com/filecoin-project/sector-storage v0.0.0-20200622150609-07cf84cbc787/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= @@ -262,8 +262,10 @@ github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= -github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 h1:zPKiZPMgkFF0Lq13hsk8lcWlxeVAs6vvJaa3uHn9v70= -github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0= +github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY= +github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= +github.com/filecoin-project/storage-fsm v0.0.0-20200622165553-628c590c009b h1:4GlA3f/9GAAE4onNE7FzZbZvOeQoHbmwkO4GhKEuYzU= +github.com/filecoin-project/storage-fsm v0.0.0-20200622165553-628c590c009b/go.mod h1:LcDXEG2pUkTxKhIF2W1G5ZZO1S6QyCLzxFypT6NFW30= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= From 5adc18846656549356f99e95432266297fa5b6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 22 Jun 2020 19:35:14 +0200 Subject: [PATCH 222/379] miner: Command to remove sectors --- api/api_storage.go | 1 + api/apistruct/struct.go | 5 +++++ cmd/lotus-storage-miner/sectors.go | 34 ++++++++++++++++++++++++++++++ node/impl/storminer.go | 4 ++++ storage/sealing.go | 4 ++++ 5 files changed, 48 insertions(+) diff --git a/api/api_storage.go b/api/api_storage.go index 90de01fb9..fb7dd4ae3 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -36,6 +36,7 @@ type StorageMiner interface { SectorsRefs(context.Context) (map[string][]SealedRef, error) SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error + SectorRemove(context.Context, abi.SectorNumber) error StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) StorageLocal(ctx context.Context) (map[stores.ID]string, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index c9646204a..4f5e5e3a7 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -206,6 +206,7 @@ type StorageMinerStruct struct { SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"` SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"` SectorsUpdate func(context.Context, abi.SectorNumber, api.SectorState) error `perm:"write"` + SectorRemove func(context.Context, abi.SectorNumber) error `perm:"admin"` WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"` @@ -786,6 +787,10 @@ func (c *StorageMinerStruct) SectorsUpdate(ctx context.Context, id abi.SectorNum return c.Internal.SectorsUpdate(ctx, id, state) } +func (c *StorageMinerStruct) SectorRemove(ctx context.Context, number abi.SectorNumber) error { + return c.Internal.SectorRemove(ctx, number) +} + func (c *StorageMinerStruct) WorkerConnect(ctx context.Context, url string) error { return c.Internal.WorkerConnect(ctx, url) } diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index 4a3109f37..f042edd35 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -27,6 +27,7 @@ var sectorsCmd = &cli.Command{ sectorsRefsCmd, sectorsUpdateCmd, sectorsPledgeCmd, + sectorsRemoveCmd, }, } @@ -208,6 +209,39 @@ var sectorsRefsCmd = &cli.Command{ }, } + +var sectorsRemoveCmd = &cli.Command{ + Name: "remove", + Usage: "Forcefully remove a sector (WARNING: This means losing power and collateral for the removed sector)", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "really-do-it", + Usage: "pass this flag if you know what you are doing", + }, + }, + Action: func(cctx *cli.Context) error { + if !cctx.Bool("really-do-it") { + return xerrors.Errorf("this is a command for advanced users, only use it if you are sure of what you are doing") + } + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := lcli.ReqContext(cctx) + if cctx.Args().Len() != 1 { + return xerrors.Errorf("must pass sector ID") + } + + id, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64) + if err != nil { + return xerrors.Errorf("could not parse sector ID: %w", err) + } + + return nodeApi.SectorRemove(ctx, abi.SectorNumber(id)) + }, +} + var sectorsUpdateCmd = &cli.Command{ Name: "update-state", Usage: "ADVANCED: manually update the state of a sector, this may aid in error recovery", diff --git a/node/impl/storminer.go b/node/impl/storminer.go index ed94e173d..a9eb0b86d 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -172,6 +172,10 @@ func (sm *StorageMinerAPI) SectorsUpdate(ctx context.Context, id abi.SectorNumbe return sm.Miner.ForceSectorState(ctx, id, sealing.SectorState(state)) } +func (sm *StorageMinerAPI) SectorRemove(ctx context.Context, id abi.SectorNumber) error { + return sm.Miner.RemoveSector(ctx, id) +} + func (sm *StorageMinerAPI) WorkerConnect(ctx context.Context, url string) error { w, err := connectRemoteWorker(ctx, sm, url) if err != nil { diff --git a/storage/sealing.go b/storage/sealing.go index c8b485379..f5716e85d 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -39,3 +39,7 @@ func (m *Miner) PledgeSector() error { func (m *Miner) ForceSectorState(ctx context.Context, id abi.SectorNumber, state sealing.SectorState) error { return m.sealing.ForceSectorState(ctx, id, state) } + +func (m *Miner) RemoveSector(ctx context.Context, id abi.SectorNumber) error { + return m.sealing.Remove(ctx, id) +} From e2435be0b92ada9438cc114338e1a7176a03ce43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 22 Jun 2020 19:36:26 +0200 Subject: [PATCH 223/379] build: Bump API version --- build/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/version.go b/build/version.go index d5766ce6e..03d5c0792 100644 --- a/build/version.go +++ b/build/version.go @@ -53,7 +53,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool { } // APIVersion is a semver version of the rpc api exposed -var APIVersion Version = newVer(0, 3, 0) +var APIVersion Version = newVer(0, 4, 0) //nolint:varcheck,deadcode const ( From cd91e42a56f91f4d56e8455c6c4e25cd8e8e285e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 22 Jun 2020 19:39:08 +0200 Subject: [PATCH 224/379] ci: lint-changes based on master --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b502c8986..0c4f29c87 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -314,7 +314,7 @@ workflows: ci: jobs: - lint-changes: - args: "--new-from-rev origin/next" + args: "--new-from-rev origin/master" - mod-tidy-check - gofmt - test: From d20255b1b4b27596bbd8a27489dd029a31edc124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Mon, 22 Jun 2020 19:41:52 +0100 Subject: [PATCH 225/379] provide an option to disable loading of built-in assets. --- build/bootstrap.go | 4 ++++ build/flags.go | 15 +++++++++++++++ node/modules/storageminer.go | 6 ++++++ 3 files changed, 25 insertions(+) create mode 100644 build/flags.go diff --git a/build/bootstrap.go b/build/bootstrap.go index 0710f0dc0..6343a0172 100644 --- a/build/bootstrap.go +++ b/build/bootstrap.go @@ -13,6 +13,10 @@ import ( ) func BuiltinBootstrap() ([]peer.AddrInfo, error) { + if DisableBuiltinAssets { + return nil, nil + } + var out []peer.AddrInfo b := rice.MustFindBox("bootstrap") diff --git a/build/flags.go b/build/flags.go new file mode 100644 index 000000000..33e9f6ede --- /dev/null +++ b/build/flags.go @@ -0,0 +1,15 @@ +package build + +// DisableBuiltinAssets disables the resolution of go.rice boxes that store +// built-in assets, such as proof parameters, bootstrap peers, genesis blocks, +// etc. +// +// When this value is set to true, it is expected that the user will +// provide any such configurations through the Lotus API itself. +// +// This is useful when you're using Lotus as a library, such as to orchestrate +// test scenarios, or for other purposes where you don't need to use the +// defaults shipped with the binary. +// +// For this flag to be effective, it must be enabled _before_ instantiating Lotus. +var DisableBuiltinAssets = false diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 67e0e0842..c6cadec34 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -75,6 +75,12 @@ func GetParams(sbc *ffiwrapper.Config) error { return err } + // If built-in assets are disabled, we expect the user to have placed the right + // parameters in the right location on the filesystem (/var/tmp/filecoin-proof-parameters). + if build.DisableBuiltinAssets { + return nil + } + if err := paramfetch.GetParams(context.TODO(), build.ParametersJSON(), uint64(ssize)); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } From 8649baccf7625c61f3619e778926ff4c02e0bb1c Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Thu, 18 Jun 2020 22:18:31 -0400 Subject: [PATCH 226/379] Remove dev values from chainwatch.service --- scripts/chainwatch.service | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/chainwatch.service b/scripts/chainwatch.service index e958ec857..74afee0e9 100644 --- a/scripts/chainwatch.service +++ b/scripts/chainwatch.service @@ -1,15 +1,15 @@ [Unit] Description=Chainwatch -PartOf=sentinel.service After=lotus-daemon.service Requires=lotus-daemon.service [Service] Environment=GOLOG_FILE="/var/log/lotus/chainwatch.log" Environment=GOLOG_LOG_FMT="json" -Environment=LOTUS_DB="postgres://postgres:password@localhost:5432/postgres?sslmode=disable" -Environment=LOTUS_PATH="/root/.lotus" +Environment=LOTUS_DB="" +Environment=LOTUS_PATH="%h/.lotus" +EnvironmentFile=-/etc/lotus/chainwatch.env ExecStart=/usr/local/bin/chainwatch run [Install] -WantedBy=multiuser.target +WantedBy=multi-user.target From b71f771acbfcdbaa273a15e126051b79a51fc542 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 22 Jun 2020 16:09:05 -0700 Subject: [PATCH 227/379] run block validation for tipsets in parallel --- chain/sync.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/chain/sync.go b/chain/sync.go index 26f30d95b..19ddac108 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -466,16 +466,25 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet) return nil } + var futures []async.ErrorFuture for _, b := range fts.Blocks { - if err := syncer.ValidateBlock(ctx, b); err != nil { - if isPermanent(err) { - syncer.bad.Add(b.Cid(), err.Error()) + futures = append(futures, async.Err(func() error { + if err := syncer.ValidateBlock(ctx, b); err != nil { + if isPermanent(err) { + syncer.bad.Add(b.Cid(), err.Error()) + } + return xerrors.Errorf("validating block %s: %w", b.Cid(), err) } - return xerrors.Errorf("validating block %s: %w", b.Cid(), err) - } - if err := syncer.sm.ChainStore().AddToTipSetTracker(b.Header); err != nil { - return xerrors.Errorf("failed to add validated header to tipset tracker: %w", err) + if err := syncer.sm.ChainStore().AddToTipSetTracker(b.Header); err != nil { + return xerrors.Errorf("failed to add validated header to tipset tracker: %w", err) + } + return nil + })) + } + for _, f := range futures { + if err := f.AwaitContext(ctx); err != nil { + return err } } return nil From 3752311f44f016b8111da3fe28ad0c93587be823 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 22 Jun 2020 16:25:41 -0700 Subject: [PATCH 228/379] update to latest libp2p release --- go.mod | 15 ++++++++------- go.sum | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 68ac9a884..70fa0d19e 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/GeertJohan/go.rice v1.0.0 github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 // indirect github.com/coreos/go-systemd/v22 v22.0.0 github.com/docker/go-units v0.4.0 github.com/drand/drand v0.9.2-0.20200616080806-a94e9c1636a4 @@ -45,7 +46,7 @@ require ( github.com/ipfs/go-bitswap v0.2.8 github.com/ipfs/go-block-format v0.0.2 github.com/ipfs/go-blockservice v0.1.3 - github.com/ipfs/go-cid v0.0.6-0.20200501230655-7c82f3b81c00 + github.com/ipfs/go-cid v0.0.6 github.com/ipfs/go-cidutil v0.0.2 github.com/ipfs/go-datastore v0.4.4 github.com/ipfs/go-ds-badger2 v0.1.0 @@ -76,20 +77,20 @@ require ( github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.2.0 github.com/libp2p/go-eventbus v0.2.1 - github.com/libp2p/go-libp2p v0.9.4 + github.com/libp2p/go-libp2p v0.10.0 github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.5.7 + github.com/libp2p/go-libp2p-core v0.6.0 github.com/libp2p/go-libp2p-discovery v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.8.1 github.com/libp2p/go-libp2p-mplex v0.2.3 github.com/libp2p/go-libp2p-peer v0.2.0 - github.com/libp2p/go-libp2p-peerstore v0.2.4 + github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-pubsub v0.3.2 github.com/libp2p/go-libp2p-quic-transport v0.5.0 github.com/libp2p/go-libp2p-record v0.1.2 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-libp2p-secio v0.2.2 - github.com/libp2p/go-libp2p-swarm v0.2.6 + github.com/libp2p/go-libp2p-swarm v0.2.7 github.com/libp2p/go-libp2p-tls v0.1.3 github.com/libp2p/go-libp2p-yamux v0.2.8 github.com/libp2p/go-maddr-filter v0.1.0 @@ -100,11 +101,11 @@ require ( github.com/multiformats/go-multiaddr v0.2.2 github.com/multiformats/go-multiaddr-dns v0.2.0 github.com/multiformats/go-multiaddr-net v0.1.5 - github.com/multiformats/go-multibase v0.0.2 + github.com/multiformats/go-multibase v0.0.3 github.com/multiformats/go-multihash v0.0.13 github.com/opentracing/opentracing-go v1.1.0 github.com/stretchr/objx v0.2.0 // indirect - github.com/stretchr/testify v1.5.1 + github.com/stretchr/testify v1.6.1 github.com/syndtr/goleveldb v1.0.0 github.com/urfave/cli/v2 v2.2.0 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba diff --git a/go.sum b/go.sum index e21c27f74..1c9dc6627 100644 --- a/go.sum +++ b/go.sum @@ -472,6 +472,8 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6-0.20200501230655-7c82f3b81c00 h1:QN88Q0kT2QiDaLxpR/SDsqOBtNIEF/F3n96gSDUimkA= github.com/ipfs/go-cid v0.0.6-0.20200501230655-7c82f3b81c00/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-cid v0.0.6 h1:go0y+GcDOGeJIV01FeBsta4FHngoA4Wz7KMeLkXAhMs= +github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cidutil v0.0.2 h1:CNOboQf1t7Qp0nuNh8QMmhJs0+Q//bRL1axtCnIB1Yo= github.com/ipfs/go-cidutil v0.0.2/go.mod h1:ewllrvrxG6AMYStla3GD7Cqn+XYSLqjK0vc+086tB6s= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -557,6 +559,8 @@ github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRD github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-cbor v0.0.1/go.mod h1:RXHr8s4k0NE0TKhnrxqZC9M888QfsBN9rhS5NjfKzY8= github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= @@ -725,6 +729,8 @@ github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ= github.com/libp2p/go-libp2p v0.9.4 h1:yighwjFvsF/qQaGtHPZfxcF+ph4ydCNnsKvg712lYRo= github.com/libp2p/go-libp2p v0.9.4/go.mod h1:NzQcC2o19xgwGqCmjx7DN+4h2F13qPCZ9UJmweYzsnU= +github.com/libp2p/go-libp2p v0.10.0 h1:7ooOvK1wi8eLpyTppy8TeH43UHy5uI75GAHGJxenUi0= +github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8= github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -750,6 +756,8 @@ github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3 github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= github.com/libp2p/go-libp2p-circuit v0.2.2 h1:87RLabJ9lrhoiSDDZyCJ80ZlI5TLJMwfyoGAaWXzWqA= github.com/libp2p/go-libp2p-circuit v0.2.2/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4= +github.com/libp2p/go-libp2p-circuit v0.2.3 h1:3Uw1fPHWrp1tgIhBz0vSOxRUmnKL8L/NGUyEd5WfSGM= +github.com/libp2p/go-libp2p-circuit v0.2.3/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4= github.com/libp2p/go-libp2p-connmgr v0.1.1/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= github.com/libp2p/go-libp2p-connmgr v0.2.3/go.mod h1:Gqjg29zI8CwXX21zRxy6gOg8VYu3zVerJRt2KyktzH4= github.com/libp2p/go-libp2p-connmgr v0.2.4 h1:TMS0vc0TCBomtQJyWr7fYxcVYYhx+q/2gF++G5Jkl/w= @@ -776,6 +784,8 @@ github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqe github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.5.7 h1:QK3xRwFxqd0Xd9bSZL+8yZ8ncZZbl6Zngd/+Y+A6sgQ= github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.6.0 h1:u03qofNYTBN+yVg08PuAKylZogVf0xcTEeM8skGf+ak= +github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= @@ -835,6 +845,8 @@ github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= github.com/libp2p/go-libp2p-peerstore v0.2.4 h1:jU9S4jYN30kdzTpDAR7SlHUD+meDUjTODh4waLWF1ws= github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= +github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= @@ -873,6 +885,8 @@ github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHv github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h/GGZes8Wku/M5Y= github.com/libp2p/go-libp2p-swarm v0.2.6 h1:UhMXIa+yCOALQyceENEIStMlbTCzOM6aWo6vw8QW17Q= github.com/libp2p/go-libp2p-swarm v0.2.6/go.mod h1:F9hrkZjO7dDbcEiYii/fAB1QdpLuU6h1pa4P5VNsEgc= +github.com/libp2p/go-libp2p-swarm v0.2.7 h1:4lV/sf7f0NuVqunOpt1I11+Z54+xp+m0eeAvxj/LyRc= +github.com/libp2p/go-libp2p-swarm v0.2.7/go.mod h1:ZSJ0Q+oq/B1JgfPHJAT2HTall+xYRNYp1xs4S2FBWKA= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -1042,6 +1056,8 @@ github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= @@ -1071,6 +1087,8 @@ github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysj github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.2 h1:2pAgScmS1g9XjH7EtAfNhTuyrWYEWcxy0G5Wo85hWDA= github.com/multiformats/go-multibase v0.0.2/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.7/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA+H1IhmjoCDtJc7PXM= @@ -1290,6 +1308,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -1777,6 +1797,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= From 9903eba7fb4ca4a827a3d637c133e4da3eecebfd Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 22 Jun 2020 20:08:19 -0700 Subject: [PATCH 229/379] stream bench import results to disk --- cmd/lotus-bench/import.go | 42 ++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f9c20ac9a..f7538daec 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "io" "io/ioutil" "math" "os" @@ -119,14 +120,22 @@ var importBenchCmd = &cli.Command{ ts = next } - out := make([]TipSetExec, 0, len(tschain)) + ibj, err := os.Create("import-bench.json") + if err != nil { + return err + } + defer ibj.Close() //nolint:errcheck + + enc := json.NewEncoder(ibj) + + var lastTse *TipSetExec lastState := tschain[len(tschain)-1].ParentState() for i := len(tschain) - 2; i >= 0; i-- { cur := tschain[i] log.Infof("computing state (height: %d, ts=%s)", cur.Height(), cur.Cids()) if cur.ParentState() != lastState { - lastTrace := out[len(out)-1].Trace + lastTrace := lastTse.Trace d, err := json.MarshalIndent(lastTrace, "", " ") if err != nil { panic(err) @@ -140,26 +149,20 @@ var importBenchCmd = &cli.Command{ if err != nil { return err } - out = append(out, TipSetExec{ + + lastTse = &TipSetExec{ TipSet: cur.Key(), Trace: trace, Duration: time.Since(start), - }) + } lastState = st + if err := enc.Encode(lastTse); err != nil { + return xerrors.Errorf("failed to write out tipsetexec: %w", err) + } } pprof.StopCPUProfile() - ibj, err := os.Create("import-bench.json") - if err != nil { - return err - } - defer ibj.Close() //nolint:errcheck - - if err := json.NewEncoder(ibj).Encode(out); err != nil { - return err - } - return nil }, @@ -236,8 +239,15 @@ var importAnalyzeCmd = &cli.Command{ } var results []TipSetExec - if err := json.NewDecoder(fi).Decode(&results); err != nil { - return err + for { + var tse TipSetExec + if err := json.NewDecoder(fi).Decode(&tse); err != nil { + if err != io.EOF { + return err + } + break + } + results = append(results, tse) } chargeDeltas := make(map[string][]float64) From abd400801c1b40b92f3c9442cf86c4d3145340cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Jun 2020 11:46:20 +0200 Subject: [PATCH 230/379] mod tidy --- go.mod | 1 - go.sum | 10 ++-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 70fa0d19e..655f402c9 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/GeertJohan/go.rice v1.0.0 github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect - github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 // indirect github.com/coreos/go-systemd/v22 v22.0.0 github.com/docker/go-units v0.4.0 github.com/drand/drand v0.9.2-0.20200616080806-a94e9c1636a4 diff --git a/go.sum b/go.sum index 1c9dc6627..113c73c53 100644 --- a/go.sum +++ b/go.sum @@ -62,7 +62,6 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE= 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= @@ -727,8 +726,6 @@ github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniV github.com/libp2p/go-libp2p v0.8.2/go.mod h1:NQDA/F/qArMHGe0J7sDScaKjW8Jh4y/ozQqBbYJ+BnA= github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM= github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ= -github.com/libp2p/go-libp2p v0.9.4 h1:yighwjFvsF/qQaGtHPZfxcF+ph4ydCNnsKvg712lYRo= -github.com/libp2p/go-libp2p v0.9.4/go.mod h1:NzQcC2o19xgwGqCmjx7DN+4h2F13qPCZ9UJmweYzsnU= github.com/libp2p/go-libp2p v0.10.0 h1:7ooOvK1wi8eLpyTppy8TeH43UHy5uI75GAHGJxenUi0= github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8= github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= @@ -852,12 +849,10 @@ github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYc github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= -github.com/libp2p/go-libp2p-pubsub v0.3.1/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-pubsub v0.3.2-0.20200527132641-c0712c6e92cf/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-pubsub v0.3.2 h1:k3cJm5JW5mjaWZkobS50sJLJWaB2mBi0HW4eRlE8mSo= github.com/libp2p/go-libp2p-pubsub v0.3.2/go.mod h1:Uss7/Cfz872KggNb+doCVPHeCDmXB7z500m/R8DaAUk= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= -github.com/libp2p/go-libp2p-quic-transport v0.3.7/go.mod h1:Kr4aDtnfHHNeENn5J+sZIVc+t8HpQn9W6BOxhVGHbgI= github.com/libp2p/go-libp2p-quic-transport v0.5.0 h1:BUN1lgYNUrtv4WLLQ5rQmC9MCJ6uEXusezGvYRNoJXE= github.com/libp2p/go-libp2p-quic-transport v0.5.0/go.mod h1:IEcuC5MLxvZ5KuHKjRu+dr3LjCT1Be3rcD/4d8JrX8M= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= @@ -883,8 +878,6 @@ github.com/libp2p/go-libp2p-swarm v0.2.1/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+ github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h/GGZes8Wku/M5Y= -github.com/libp2p/go-libp2p-swarm v0.2.6 h1:UhMXIa+yCOALQyceENEIStMlbTCzOM6aWo6vw8QW17Q= -github.com/libp2p/go-libp2p-swarm v0.2.6/go.mod h1:F9hrkZjO7dDbcEiYii/fAB1QdpLuU6h1pa4P5VNsEgc= github.com/libp2p/go-libp2p-swarm v0.2.7 h1:4lV/sf7f0NuVqunOpt1I11+Z54+xp+m0eeAvxj/LyRc= github.com/libp2p/go-libp2p-swarm v0.2.7/go.mod h1:ZSJ0Q+oq/B1JgfPHJAT2HTall+xYRNYp1xs4S2FBWKA= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -985,7 +978,6 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= -github.com/lucas-clemente/quic-go v0.15.7/go.mod h1:Myi1OyS0FOjL3not4BxT7KN29bRkcMUV5JVVFLKtDp8= github.com/lucas-clemente/quic-go v0.16.0 h1:jJw36wfzGJhmOhAOaOC2lS36WgeqXQszH47A7spo1LI= github.com/lucas-clemente/quic-go v0.16.0/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE= github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg= @@ -1309,6 +1301,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= @@ -1797,6 +1790,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= From 9e70e9524231ae98375a2ac93b3be4bd22e78992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Jun 2020 13:21:01 +0200 Subject: [PATCH 231/379] sync: Correctly pass blocks to ValidateBlock --- chain/sync.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chain/sync.go b/chain/sync.go index 19ddac108..f20637c9e 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -468,6 +468,8 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet) var futures []async.ErrorFuture for _, b := range fts.Blocks { + b := b // rebind to a scoped variable + futures = append(futures, async.Err(func() error { if err := syncer.ValidateBlock(ctx, b); err != nil { if isPermanent(err) { From f8e7901b895a63cfab6d146866cd3d95086ab4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Jun 2020 14:44:34 +0200 Subject: [PATCH 232/379] Address review --- api/apistruct/struct.go | 2 +- cmd/lotus-storage-miner/sectors.go | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 4f5e5e3a7..9e71155b3 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -206,7 +206,7 @@ type StorageMinerStruct struct { SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"` SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"` SectorsUpdate func(context.Context, abi.SectorNumber, api.SectorState) error `perm:"write"` - SectorRemove func(context.Context, abi.SectorNumber) error `perm:"admin"` + SectorRemove func(context.Context, abi.SectorNumber) error `perm:"admin"` WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"` diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index f042edd35..0dfce2f38 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -47,8 +47,9 @@ var sectorsPledgeCmd = &cli.Command{ } var sectorsStatusCmd = &cli.Command{ - Name: "status", - Usage: "Get the seal status of a sector by its ID", + Name: "status", + Usage: "Get the seal status of a sector by its number", + ArgsUsage: "", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "log", @@ -64,7 +65,7 @@ var sectorsStatusCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) if !cctx.Args().Present() { - return fmt.Errorf("must specify sector ID to get status of") + return fmt.Errorf("must specify sector number to get status of") } id, err := strconv.ParseUint(cctx.Args().First(), 10, 64) @@ -209,10 +210,10 @@ var sectorsRefsCmd = &cli.Command{ }, } - var sectorsRemoveCmd = &cli.Command{ - Name: "remove", - Usage: "Forcefully remove a sector (WARNING: This means losing power and collateral for the removed sector)", + Name: "remove", + Usage: "Forcefully remove a sector (WARNING: This means losing power and collateral for the removed sector)", + ArgsUsage: "", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "really-do-it", @@ -230,12 +231,12 @@ var sectorsRemoveCmd = &cli.Command{ defer closer() ctx := lcli.ReqContext(cctx) if cctx.Args().Len() != 1 { - return xerrors.Errorf("must pass sector ID") + return xerrors.Errorf("must pass sector number") } id, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64) if err != nil { - return xerrors.Errorf("could not parse sector ID: %w", err) + return xerrors.Errorf("could not parse sector number: %w", err) } return nodeApi.SectorRemove(ctx, abi.SectorNumber(id)) @@ -262,12 +263,12 @@ var sectorsUpdateCmd = &cli.Command{ defer closer() ctx := lcli.ReqContext(cctx) if cctx.Args().Len() < 2 { - return xerrors.Errorf("must pass sector ID and new state") + return xerrors.Errorf("must pass sector number and new state") } id, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64) if err != nil { - return xerrors.Errorf("could not parse sector ID: %w", err) + return xerrors.Errorf("could not parse sector number: %w", err) } return nodeApi.SectorsUpdate(ctx, abi.SectorNumber(id), api.SectorState(cctx.Args().Get(1))) From 55ed45f108aa4a3dd6ed36c91e824c091ac25e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=87?= Date: Tue, 23 Jun 2020 20:46:41 +0800 Subject: [PATCH 233/379] Get the good sectors to run windowPost --- storage/wdpost_run.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 5c1170551..fe42d2940 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -383,25 +383,25 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo return nil, xerrors.Errorf("get need prove sectors: %w", err) } - var skipped *abi.BitField - { - good, err := s.checkSectors(ctx, nps) - if err != nil { - return nil, xerrors.Errorf("checking sectors to skip: %w", err) - } - - skipped, err = bitfield.SubtractBitField(nps, good) - if err != nil { - return nil, xerrors.Errorf("nps - good: %w", err) - } + // var skipped *abi.BitField + // { + good, err := s.checkSectors(ctx, nps) + if err != nil { + return nil, xerrors.Errorf("checking sectors to skip: %w", err) } + skipped, err := bitfield.SubtractBitField(nps, good) + if err != nil { + return nil, xerrors.Errorf("nps - good: %w", err) + } + // } + skipCount, err := skipped.Count() if err != nil { return nil, xerrors.Errorf("getting skipped sector count: %w", err) } - ssi, err := s.sortedSectorInfo(ctx, nps, ts) + ssi, err := s.sortedSectorInfo(ctx, good, ts) if err != nil { return nil, xerrors.Errorf("getting sorted sector info: %w", err) } From 566a99240d9314f925b7aa25c86812960182a818 Mon Sep 17 00:00:00 2001 From: Yusef Napora Date: Tue, 23 Jun 2020 13:23:04 -0400 Subject: [PATCH 234/379] allow overriding drand config --- chain/beacon/drand/drand.go | 27 ++++++++++++++++++--------- node/modules/services.go | 3 ++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 21bd2501a..91fc31aad 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -27,18 +27,22 @@ import ( var log = logging.Logger("drand") -var drandServers = []string{ - "https://pl-eu.testnet.drand.sh", - "https://pl-us.testnet.drand.sh", - "https://pl-sin.testnet.drand.sh", +type DrandConfig struct { + Servers []string + ChainInfo *dchain.Info } -var drandChain *dchain.Info +var defaultConfig = DrandConfig{ + Servers: []string{ + "https://pl-eu.testnet.drand.sh", + "https://pl-us.testnet.drand.sh", + "https://pl-sin.testnet.drand.sh", + }, +} func init() { - var err error - drandChain, err = dchain.InfoFromJSON(bytes.NewReader([]byte(build.DrandChain))) + defaultConfig.ChainInfo, err = dchain.InfoFromJSON(bytes.NewReader([]byte(build.DrandChain))) if err != nil { panic("could not unmarshal chain info: " + err.Error()) } @@ -73,16 +77,21 @@ type DrandBeacon struct { localCache map[uint64]types.BeaconEntry } -func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon, error) { +func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config *DrandConfig) (*DrandBeacon, error) { if genesisTs == 0 { panic("what are you doing this cant be zero") } + if config == nil { + config = &defaultConfig + } + drandChain := config.ChainInfo + dlogger := dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger( log.SugaredLogger.Desugar(), zapcore.InfoLevel)) var clients []dclient.Client - for _, url := range drandServers { + for _, url := range config.Servers { hc, err := hclient.NewWithInfo(url, drandChain, nil) if err != nil { return nil, xerrors.Errorf("could not create http drand client: %w", err) diff --git a/node/modules/services.go b/node/modules/services.go index 27244ad3a..cbd0fb882 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -108,6 +108,7 @@ func RetrievalResolver(l *discovery.Local) retrievalmarket.PeerResolver { type RandomBeaconParams struct { fx.In + DrandConfig *drand.DrandConfig `optional:"true"` PubSub *pubsub.PubSub `optional:"true"` Cs *store.ChainStore } @@ -119,5 +120,5 @@ func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.Random } //return beacon.NewMockBeacon(build.BlockDelay * time.Second) - return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub) + return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub, p.DrandConfig) } From 8adc831a3174cb47dc90ab8bfee83a01470bdcec Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 23 Jun 2020 11:08:04 -0700 Subject: [PATCH 235/379] return error if retrieval deal rejected --- node/impl/client/client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index df6fb862c..9f8dd6bb9 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -348,6 +348,8 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref unsubscribe := a.Retrieval.SubscribeToEvents(func(event retrievalmarket.ClientEvent, state retrievalmarket.ClientDealState) { if state.PayloadCID.Equals(order.Root) { switch state.Status { + case retrievalmarket.DealStatusRejected: + retrievalResult <- xerrors.Errorf("Retrieval Proposal Rejected: %s", state.Message) case retrievalmarket.DealStatusFailed, retrievalmarket.DealStatusErrored: retrievalResult <- xerrors.Errorf("Retrieval Error: %s", state.Message) case retrievalmarket.DealStatusCompleted: From fb04b17fad43ac9c8cd7d08c856f4ce2900d90ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Jun 2020 20:55:13 +0200 Subject: [PATCH 236/379] state: Get correct locked table in StateMarketParticipants --- node/impl/full/state.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index e39527201..048ae7858 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -425,7 +425,7 @@ func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSet if err != nil { return nil, err } - locked, err := hamt.LoadNode(ctx, cst, state.EscrowTable, hamt.UseTreeBitWidth(5)) + locked, err := hamt.LoadNode(ctx, cst, state.LockedTable, hamt.UseTreeBitWidth(5)) if err != nil { return nil, err } @@ -489,13 +489,11 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (m var s market.DealState if err := sa.Get(ctx, i, &s); err != nil { - if err != nil { - if _, ok := err.(*amt.ErrNotFound); !ok { - return xerrors.Errorf("failed to get state for deal in proposals array: %w", err) - } - - s.SectorStartEpoch = -1 + if _, ok := err.(*amt.ErrNotFound); !ok { + return xerrors.Errorf("failed to get state for deal in proposals array: %w", err) } + + s.SectorStartEpoch = -1 } out[strconv.FormatInt(int64(i), 10)] = api.MarketDeal{ Proposal: d, From 960523f45f87c8925ad9ac268b595917e4527361 Mon Sep 17 00:00:00 2001 From: Yusef Napora Date: Tue, 23 Jun 2020 15:09:28 -0400 Subject: [PATCH 237/379] fix drand test --- chain/beacon/drand/drand_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/beacon/drand/drand_test.go b/chain/beacon/drand/drand_test.go index f35f3e4cc..219c86990 100644 --- a/chain/beacon/drand/drand_test.go +++ b/chain/beacon/drand/drand_test.go @@ -10,7 +10,7 @@ import ( ) func TestPrintGroupInfo(t *testing.T) { - c, err := hclient.New(drandServers[0], nil, nil) + c, err := hclient.New(defaultConfig.Servers[0], nil, nil) assert.NoError(t, err) cg := c.(interface { FetchChainInfo(groupHash []byte) (*dchain.Info, error) From 628872d0e425f3d38af8c19f345a846288dfcbf7 Mon Sep 17 00:00:00 2001 From: Yusef Napora Date: Tue, 23 Jun 2020 15:10:27 -0400 Subject: [PATCH 238/379] forgot my go fmt hook --- chain/beacon/drand/drand.go | 2 +- node/modules/services.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 91fc31aad..c800366d1 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -28,7 +28,7 @@ import ( var log = logging.Logger("drand") type DrandConfig struct { - Servers []string + Servers []string ChainInfo *dchain.Info } diff --git a/node/modules/services.go b/node/modules/services.go index cbd0fb882..c5d61d580 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -109,8 +109,8 @@ type RandomBeaconParams struct { fx.In DrandConfig *drand.DrandConfig `optional:"true"` - PubSub *pubsub.PubSub `optional:"true"` - Cs *store.ChainStore + PubSub *pubsub.PubSub `optional:"true"` + Cs *store.ChainStore } func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) { From 06162290af86de9cb3a438bbb491e603104a7f0f Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 23 Jun 2020 12:14:41 -0700 Subject: [PATCH 239/379] explicitly handle each deal status, as per PR feedback --- node/impl/client/client.go | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 9f8dd6bb9..72beda7ac 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -348,12 +348,34 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref unsubscribe := a.Retrieval.SubscribeToEvents(func(event retrievalmarket.ClientEvent, state retrievalmarket.ClientDealState) { if state.PayloadCID.Equals(order.Root) { switch state.Status { - case retrievalmarket.DealStatusRejected: - retrievalResult <- xerrors.Errorf("Retrieval Proposal Rejected: %s", state.Message) - case retrievalmarket.DealStatusFailed, retrievalmarket.DealStatusErrored: - retrievalResult <- xerrors.Errorf("Retrieval Error: %s", state.Message) - case retrievalmarket.DealStatusCompleted: + case + retrievalmarket.DealStatusCompleted: retrievalResult <- nil + case + retrievalmarket.DealStatusRejected: + retrievalResult <- xerrors.Errorf("Retrieval Proposal Rejected: %s", state.Message) + case + retrievalmarket.DealStatusDealNotFound, + retrievalmarket.DealStatusErrored, + retrievalmarket.DealStatusFailed: + retrievalResult <- xerrors.Errorf("Retrieval Error: %s", state.Message) + case + retrievalmarket.DealStatusAccepted, + retrievalmarket.DealStatusAwaitingAcceptance, + retrievalmarket.DealStatusBlocksComplete, + retrievalmarket.DealStatusFinalizing, + retrievalmarket.DealStatusFundsNeeded, + retrievalmarket.DealStatusFundsNeededLastPayment, + retrievalmarket.DealStatusNew, + retrievalmarket.DealStatusOngoing, + retrievalmarket.DealStatusPaymentChannelAddingFunds, + retrievalmarket.DealStatusPaymentChannelAllocatingLane, + retrievalmarket.DealStatusPaymentChannelCreating, + retrievalmarket.DealStatusPaymentChannelReady, + retrievalmarket.DealStatusVerified: + return + default: + retrievalResult <- xerrors.Errorf("Unhandled Retrieval Status: %+v", state.Status) } } }) From 309fbc15b2399421800a17fc25d4fad19e503f92 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 23 Jun 2020 12:22:33 -0700 Subject: [PATCH 240/379] import aliasing, for legibility --- node/impl/client/client.go | 62 ++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 72beda7ac..6e7f50f26 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -31,7 +31,7 @@ import ( "go.uber.org/fx" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-fil-markets/retrievalmarket" + rm "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" @@ -59,8 +59,8 @@ type API struct { paych.PaychAPI SMDealClient storagemarket.StorageClient - RetDiscovery retrievalmarket.PeerResolver - Retrieval retrievalmarket.RetrievalClient + RetDiscovery rm.PeerResolver + Retrieval rm.RetrievalClient Chain *store.ChainStore LocalDAG dtypes.ClientDAG @@ -202,7 +202,7 @@ func (a *API) ClientFindData(ctx context.Context, root cid.Cid) ([]api.QueryOffe out := make([]api.QueryOffer, len(peers)) for k, p := range peers { - out[k] = a.makeRetrievalQuery(ctx, p, root, retrievalmarket.QueryParams{}) + out[k] = a.makeRetrievalQuery(ctx, p, root, rm.QueryParams{}) } return out, nil @@ -213,25 +213,25 @@ func (a *API) ClientMinerQueryOffer(ctx context.Context, payload cid.Cid, miner if err != nil { return api.QueryOffer{}, err } - rp := retrievalmarket.RetrievalPeer{ + rp := rm.RetrievalPeer{ Address: miner, ID: mi.PeerId, } - return a.makeRetrievalQuery(ctx, rp, payload, retrievalmarket.QueryParams{}), nil + return a.makeRetrievalQuery(ctx, rp, payload, rm.QueryParams{}), nil } -func (a *API) makeRetrievalQuery(ctx context.Context, rp retrievalmarket.RetrievalPeer, payload cid.Cid, qp retrievalmarket.QueryParams) api.QueryOffer { +func (a *API) makeRetrievalQuery(ctx context.Context, rp rm.RetrievalPeer, payload cid.Cid, qp rm.QueryParams) api.QueryOffer { queryResponse, err := a.Retrieval.Query(ctx, rp, payload, qp) if err != nil { return api.QueryOffer{Err: err.Error(), Miner: rp.Address, MinerPeerID: rp.ID} } var errStr string switch queryResponse.Status { - case retrievalmarket.QueryResponseAvailable: + case rm.QueryResponseAvailable: errStr = "" - case retrievalmarket.QueryResponseUnavailable: + case rm.QueryResponseUnavailable: errStr = fmt.Sprintf("retrieval query offer was unavailable: %s", queryResponse.Message) - case retrievalmarket.QueryResponseError: + case rm.QueryResponseError: errStr = fmt.Sprintf("retrieval query offer errored: %s", queryResponse.Message) } @@ -345,34 +345,32 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref retrievalResult := make(chan error, 1) - unsubscribe := a.Retrieval.SubscribeToEvents(func(event retrievalmarket.ClientEvent, state retrievalmarket.ClientDealState) { + unsubscribe := a.Retrieval.SubscribeToEvents(func(event rm.ClientEvent, state rm.ClientDealState) { if state.PayloadCID.Equals(order.Root) { switch state.Status { - case - retrievalmarket.DealStatusCompleted: + case rm.DealStatusCompleted: retrievalResult <- nil - case - retrievalmarket.DealStatusRejected: + case rm.DealStatusRejected: retrievalResult <- xerrors.Errorf("Retrieval Proposal Rejected: %s", state.Message) case - retrievalmarket.DealStatusDealNotFound, - retrievalmarket.DealStatusErrored, - retrievalmarket.DealStatusFailed: + rm.DealStatusDealNotFound, + rm.DealStatusErrored, + rm.DealStatusFailed: retrievalResult <- xerrors.Errorf("Retrieval Error: %s", state.Message) case - retrievalmarket.DealStatusAccepted, - retrievalmarket.DealStatusAwaitingAcceptance, - retrievalmarket.DealStatusBlocksComplete, - retrievalmarket.DealStatusFinalizing, - retrievalmarket.DealStatusFundsNeeded, - retrievalmarket.DealStatusFundsNeededLastPayment, - retrievalmarket.DealStatusNew, - retrievalmarket.DealStatusOngoing, - retrievalmarket.DealStatusPaymentChannelAddingFunds, - retrievalmarket.DealStatusPaymentChannelAllocatingLane, - retrievalmarket.DealStatusPaymentChannelCreating, - retrievalmarket.DealStatusPaymentChannelReady, - retrievalmarket.DealStatusVerified: + rm.DealStatusAccepted, + rm.DealStatusAwaitingAcceptance, + rm.DealStatusBlocksComplete, + rm.DealStatusFinalizing, + rm.DealStatusFundsNeeded, + rm.DealStatusFundsNeededLastPayment, + rm.DealStatusNew, + rm.DealStatusOngoing, + rm.DealStatusPaymentChannelAddingFunds, + rm.DealStatusPaymentChannelAllocatingLane, + rm.DealStatusPaymentChannelCreating, + rm.DealStatusPaymentChannelReady, + rm.DealStatusVerified: return default: retrievalResult <- xerrors.Errorf("Unhandled Retrieval Status: %+v", state.Status) @@ -385,7 +383,7 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref _, err := a.Retrieval.Retrieve( ctx, order.Root, - retrievalmarket.NewParamsV0(ppb, order.PaymentInterval, order.PaymentIntervalIncrease), + rm.NewParamsV0(ppb, order.PaymentInterval, order.PaymentIntervalIncrease), order.Total, order.MinerPeerID, order.Client, From b448de422e1f929b02a9ddd719d594c66046d438 Mon Sep 17 00:00:00 2001 From: Yusef Napora Date: Tue, 23 Jun 2020 15:56:03 -0400 Subject: [PATCH 241/379] improve DrandConfig dependency injection --- build/params_shared.go | 9 ++++++++- chain/beacon/drand/drand.go | 32 ++++++++------------------------ chain/beacon/drand/drand_test.go | 5 ++++- node/builder.go | 1 + node/modules/dtypes/beacon.go | 6 ++++++ node/modules/lp2p/pubsub.go | 7 ++++--- node/modules/services.go | 14 +++++++++++--- 7 files changed, 42 insertions(+), 32 deletions(-) create mode 100644 node/modules/dtypes/beacon.go diff --git a/build/params_shared.go b/build/params_shared.go index 4da70aaeb..5ab07bd3f 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -121,4 +121,11 @@ const VerifSigCacheSize = 32000 const BlockMessageLimit = 512 const BlockGasLimit = 100_000_000_000 -var DrandChain = `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}` +var DrandConfig = dtypes.DrandConfig{ + Servers: []string{ + "https://pl-eu.testnet.drand.sh", + "https://pl-us.testnet.drand.sh", + "https://pl-sin.testnet.drand.sh", + }, + ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}`, +} diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index c800366d1..9769a8436 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -19,33 +19,17 @@ import ( logging "github.com/ipfs/go-log" pubsub "github.com/libp2p/go-libp2p-pubsub" - "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/specs-actors/actors/abi" ) var log = logging.Logger("drand") type DrandConfig struct { - Servers []string - ChainInfo *dchain.Info -} - -var defaultConfig = DrandConfig{ - Servers: []string{ - "https://pl-eu.testnet.drand.sh", - "https://pl-us.testnet.drand.sh", - "https://pl-sin.testnet.drand.sh", - }, -} - -func init() { - var err error - defaultConfig.ChainInfo, err = dchain.InfoFromJSON(bytes.NewReader([]byte(build.DrandChain))) - if err != nil { - panic("could not unmarshal chain info: " + err.Error()) - } + Servers []string + ChainInfoJSON string } type drandPeer struct { @@ -77,15 +61,15 @@ type DrandBeacon struct { localCache map[uint64]types.BeaconEntry } -func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config *DrandConfig) (*DrandBeacon, error) { +func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config DrandConfig) (*DrandBeacon, error) { if genesisTs == 0 { panic("what are you doing this cant be zero") } - if config == nil { - config = &defaultConfig + drandChain, err := dchain.InfoFromJSON(bytes.NewReader([]byte(config.ChainInfoJSON))) + if err != nil { + return nil, xerrors.Errorf("unable to unmarshal drand chain info: %w", err) } - drandChain := config.ChainInfo dlogger := dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger( log.SugaredLogger.Desugar(), zapcore.InfoLevel)) diff --git a/chain/beacon/drand/drand_test.go b/chain/beacon/drand/drand_test.go index 219c86990..d7d9c4d18 100644 --- a/chain/beacon/drand/drand_test.go +++ b/chain/beacon/drand/drand_test.go @@ -7,10 +7,13 @@ import ( dchain "github.com/drand/drand/chain" hclient "github.com/drand/drand/client/http" "github.com/stretchr/testify/assert" + + "github.com/filecoin-project/lotus/build" ) func TestPrintGroupInfo(t *testing.T) { - c, err := hclient.New(defaultConfig.Servers[0], nil, nil) + server := build.DrandConfig.Servers[0] + c, err := hclient.New(server, nil, nil) assert.NoError(t, err) cg := c.(interface { FetchChainInfo(groupHash []byte) (*dchain.Info, error) diff --git a/node/builder.go b/node/builder.go index e84c4422c..3b6c6fbda 100644 --- a/node/builder.go +++ b/node/builder.go @@ -218,6 +218,7 @@ func Online() Option { Override(new(dtypes.BootstrapPeers), modules.BuiltinBootstrap), Override(new(dtypes.DrandBootstrap), modules.DrandBootstrap), + Override(new(dtypes.DrandConfig), modules.BuiltinDrandConfig), Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages), diff --git a/node/modules/dtypes/beacon.go b/node/modules/dtypes/beacon.go new file mode 100644 index 000000000..f3ebc4fac --- /dev/null +++ b/node/modules/dtypes/beacon.go @@ -0,0 +1,6 @@ +package dtypes + +type DrandConfig struct { + Servers []string + ChainInfoJSON string +} diff --git a/node/modules/lp2p/pubsub.go b/node/modules/lp2p/pubsub.go index bf9d88d42..ac23f56a8 100644 --- a/node/modules/lp2p/pubsub.go +++ b/node/modules/lp2p/pubsub.go @@ -44,13 +44,14 @@ type GossipIn struct { Db dtypes.DrandBootstrap Cfg *config.Pubsub Sk *dtypes.ScoreKeeper + Dr dtypes.DrandConfig } -func getDrandTopic() (string, error) { +func getDrandTopic(chainInfoJSON string) (string, error) { var drandInfo = struct { Hash string `json:"hash"` }{} - err := json.Unmarshal([]byte(build.DrandChain), &drandInfo) + err := json.Unmarshal([]byte(chainInfoJSON), &drandInfo) if err != nil { return "", xerrors.Errorf("could not unmarshal drand chain info: %w", err) } @@ -68,7 +69,7 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { } isBootstrapNode := in.Cfg.Bootstrapper - drandTopic, err := getDrandTopic() + drandTopic, err := getDrandTopic(in.Dr.ChainInfoJSON) if err != nil { return nil, err } diff --git a/node/modules/services.go b/node/modules/services.go index c5d61d580..ad7eb056f 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -108,9 +108,13 @@ func RetrievalResolver(l *discovery.Local) retrievalmarket.PeerResolver { type RandomBeaconParams struct { fx.In - DrandConfig *drand.DrandConfig `optional:"true"` - PubSub *pubsub.PubSub `optional:"true"` + PubSub *pubsub.PubSub `optional:"true"` Cs *store.ChainStore + DrandConfig dtypes.DrandConfig +} + +func BuiltinDrandConfig() dtypes.DrandConfig { + return build.DrandConfig } func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) { @@ -120,5 +124,9 @@ func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.Random } //return beacon.NewMockBeacon(build.BlockDelay * time.Second) - return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub, p.DrandConfig) + config := drand.DrandConfig{ + Servers: p.DrandConfig.Servers, + ChainInfoJSON: p.DrandConfig.ChainInfoJSON, + } + return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub, config) } From 5074cf8beb2947c2615a73d5506df8a8974423e8 Mon Sep 17 00:00:00 2001 From: Yusef Napora Date: Tue, 23 Jun 2020 16:23:06 -0400 Subject: [PATCH 242/379] import DrandConfig from dtypes --- chain/beacon/drand/drand.go | 8 ++------ node/modules/services.go | 6 +----- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 9769a8436..eb51a2af3 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -23,15 +23,11 @@ import ( "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/modules/dtypes" ) var log = logging.Logger("drand") -type DrandConfig struct { - Servers []string - ChainInfoJSON string -} - type drandPeer struct { addr string tls bool @@ -61,7 +57,7 @@ type DrandBeacon struct { localCache map[uint64]types.BeaconEntry } -func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config DrandConfig) (*DrandBeacon, error) { +func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) { if genesisTs == 0 { panic("what are you doing this cant be zero") } diff --git a/node/modules/services.go b/node/modules/services.go index ad7eb056f..2cba3a0be 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -124,9 +124,5 @@ func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.Random } //return beacon.NewMockBeacon(build.BlockDelay * time.Second) - config := drand.DrandConfig{ - Servers: p.DrandConfig.Servers, - ChainInfoJSON: p.DrandConfig.ChainInfoJSON, - } - return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub, config) + return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub, p.DrandConfig) } From d524821c86c488e00190931308f96c4127c69820 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 23 Jun 2020 14:25:45 -0700 Subject: [PATCH 243/379] add command to change registered multiaddrs for miner --- cmd/lotus-storage-miner/info.go | 76 ++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 01077bc83..667df5342 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -4,19 +4,22 @@ import ( "bytes" "context" "fmt" - "github.com/filecoin-project/specs-actors/actors/builtin/power" "sort" "time" "github.com/fatih/color" + ma "github.com/multiformats/go-multiaddr" "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/power" sealing "github.com/filecoin-project/storage-fsm" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -24,6 +27,9 @@ import ( var infoCmd = &cli.Command{ Name: "info", Usage: "Print storage miner info", + Subcommands: []*cli.Command{ + infoSetAddrsCmd, + }, Flags: []cli.Flag{ &cli.BoolFlag{Name: "color"}, }, @@ -248,3 +254,71 @@ func sectorsInfo(ctx context.Context, napi api.StorageMiner) error { return nil } + +var infoSetAddrsCmd = &cli.Command{ + Name: "set-addrs", + Usage: "set addresses that your miner can be publically dialed on", + Flags: []cli.Flag{ + &cli.Int64Flag{ + Name: "gas-limit", + Usage: "set gas limit", + Value: 100000, + }, + }, + Action: func(cctx *cli.Context) error { + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + var addrs []abi.Multiaddrs + for _, a := range cctx.Args().Slice() { + maddr, err := ma.NewMultiaddr(a) + if err != nil { + return fmt.Errorf("failed to parse %q as a multiaddr: %w", a, err) + } + + addrs = append(addrs, maddr.Bytes()) + } + + maddr, err := nodeApi.ActorAddress(ctx) + if err != nil { + return err + } + + minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + params, err := actors.SerializeParams(&miner.ChangeMultiaddrsParams{addrs}) + if err != nil { + return err + } + + gasLimit := cctx.Int64("gas-limit") + + smsg, err := api.MpoolPushMessage(ctx, &types.Message{ + To: maddr, + From: minfo.Worker, + Value: types.NewInt(0), + GasPrice: types.NewInt(1), + GasLimit: gasLimit, + Method: 18, + Params: params, + }) + + fmt.Printf("Requested multiaddrs change in message %s\n", smsg.Cid()) + return nil + + }, +} From 69559bcf4f8a1428ffff97e09fffce8b84bc6a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Jun 2020 23:32:12 +0200 Subject: [PATCH 244/379] Use fsm, sector-storage master --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 1fc21978a..53344428d 100644 --- a/go.mod +++ b/go.mod @@ -29,10 +29,10 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200622150609-07cf84cbc787 + github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea - github.com/filecoin-project/storage-fsm v0.0.0-20200622165553-628c590c009b + github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index 79f3fad57..5cd3fda3f 100644 --- a/go.sum +++ b/go.sum @@ -253,8 +253,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= -github.com/filecoin-project/sector-storage v0.0.0-20200622150609-07cf84cbc787 h1:MOnK9/z+ELvPv3+jO7GwnEj5d7tBdUvP+asOj7bvpog= -github.com/filecoin-project/sector-storage v0.0.0-20200622150609-07cf84cbc787/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= +github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d h1:yJJqXCMEhvXJoOS6T1O46FXl+A3mlttXhgjcTCp+Tgo= +github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= @@ -264,8 +264,8 @@ github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sg github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY= github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= -github.com/filecoin-project/storage-fsm v0.0.0-20200622165553-628c590c009b h1:4GlA3f/9GAAE4onNE7FzZbZvOeQoHbmwkO4GhKEuYzU= -github.com/filecoin-project/storage-fsm v0.0.0-20200622165553-628c590c009b/go.mod h1:LcDXEG2pUkTxKhIF2W1G5ZZO1S6QyCLzxFypT6NFW30= +github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 h1:nH3L7YVqrHINOmvZ+5jFjFNSi9/swXcm+uufXpkFJfo= +github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3/go.mod h1:Nl0JX9I3fIVtPEJ9HzGzO4D8LXehT9PqvUQUbNvcstc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= From c8104a03e61f56f17c4a39d5efbf0ad23069dc07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 23 Jun 2020 22:51:25 +0100 Subject: [PATCH 245/379] some initial godocs. (#2118) --- chain/beacon/beacon.go | 4 + chain/beacon/drand/drand.go | 7 ++ chain/blocksync/blocksync.go | 19 +++++ chain/blocksync/blocksync_client.go | 8 ++ chain/store/fts.go | 3 + chain/store/index.go | 2 +- chain/store/store.go | 19 +++++ chain/sync.go | 127 ++++++++++++++++++++++++++-- miner/miner.go | 6 ++ 9 files changed, 188 insertions(+), 7 deletions(-) diff --git a/chain/beacon/beacon.go b/chain/beacon/beacon.go index 34405f3c8..2be2e7f1c 100644 --- a/chain/beacon/beacon.go +++ b/chain/beacon/beacon.go @@ -17,6 +17,10 @@ type Response struct { Err error } +// RandomBeacon represents a system that provides randomness to Lotus. +// Other components interrogate the RandomBeacon to acquire randomness that's +// valid for a specific chain epoch. Also to verify beacon entries that have +// been posted on chain. type RandomBeacon interface { Entry(context.Context, uint64) <-chan Response VerifyEntry(types.BeaconEntry, types.BeaconEntry) error diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index eb51a2af3..00ff05f81 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -41,6 +41,13 @@ func (dp *drandPeer) IsTLS() bool { return dp.tls } +// DrandBeacon connects Lotus with a drand network in order to provide +// randomness to the system in a way that's aligned with Filecoin rounds/epochs. +// +// We connect to drand peers via their public HTTP endpoints. The peers are +// enumerated in the drandServers variable. +// +// The root trust for the Drand chain is configured from build.DrandChain. type DrandBeacon struct { client dclient.Client diff --git a/chain/blocksync/blocksync.go b/chain/blocksync/blocksync.go index daca9ce20..a9251c419 100644 --- a/chain/blocksync/blocksync.go +++ b/chain/blocksync/blocksync.go @@ -10,6 +10,7 @@ import ( "golang.org/x/xerrors" cborutil "github.com/filecoin-project/go-cbor-util" + "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -27,6 +28,24 @@ const BlockSyncProtocolID = "/fil/sync/blk/0.0.1" const BlockSyncMaxRequestLength = 800 +// BlockSyncService is the component that services BlockSync requests from +// peers. +// +// BlockSync is the basic chain synchronization protocol of Filecoin. BlockSync +// is an RPC-oriented protocol, with a single operation to request blocks. +// +// A request contains a start anchor block (referred to with a CID), and a +// amount of blocks requested beyond the anchor (including the anchor itself). +// +// A client can also pass options, encoded as a 64-bit bitfield. Lotus supports +// two options at the moment: +// +// - include block contents +// - include block messages +// +// The response will include a status code, an optional message, and the +// response payload in case of success. The payload is a slice of serialized +// tipsets. type BlockSyncService struct { cs *store.ChainStore } diff --git a/chain/blocksync/blocksync_client.go b/chain/blocksync/blocksync_client.go index 129e8d332..daa4b6335 100644 --- a/chain/blocksync/blocksync_client.go +++ b/chain/blocksync/blocksync_client.go @@ -64,6 +64,11 @@ func (bs *BlockSync) processStatus(req *BlockSyncRequest, res *BlockSyncResponse } } +// GetBlocks fetches count blocks from the network, from the provided tipset +// *backwards*, returning as many tipsets as count. +// +// {hint/usage}: This is used by the Syncer during normal chain syncing and when +// resolving forks. func (bs *BlockSync) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error) { ctx, span := trace.StartSpan(ctx, "bsync.GetBlocks") defer span.End() @@ -80,7 +85,9 @@ func (bs *BlockSync) GetBlocks(ctx context.Context, tsk types.TipSetKey, count i Options: BSOptBlocks, } + // this peerset is sorted by latency and failure counting. peers := bs.getPeers() + // randomize the first few peers so we don't always pick the same peer shufflePrefix(peers) @@ -356,6 +363,7 @@ func (bs *BlockSync) RemovePeer(p peer.ID) { bs.syncPeers.removePeer(p) } +// getPeers returns a preference-sorted set of peers to query. func (bs *BlockSync) getPeers() []peer.ID { return bs.syncPeers.prefSortedPeers() } diff --git a/chain/store/fts.go b/chain/store/fts.go index f9ec4459e..0324938d7 100644 --- a/chain/store/fts.go +++ b/chain/store/fts.go @@ -32,8 +32,11 @@ func (fts *FullTipSet) Cids() []cid.Cid { return cids } +// TipSet returns a narrower view of this FullTipSet elliding the block +// messages. func (fts *FullTipSet) TipSet() *types.TipSet { if fts.tipset != nil { + // FIXME: fts.tipset is actually never set. Should it memoize? return fts.tipset } diff --git a/chain/store/index.go b/chain/store/index.go index bb363ec18..7edbf251f 100644 --- a/chain/store/index.go +++ b/chain/store/index.go @@ -34,7 +34,7 @@ type lbEntry struct { target types.TipSetKey } -func (ci *ChainIndex) GetTipsetByHeight(ctx context.Context, from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) { +func (ci *ChainIndex) GetTipsetByHeight(_ context.Context, from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) { if from.Height()-to <= ci.skipLength { return ci.walkBack(from, to) } diff --git a/chain/store/store.go b/chain/store/store.go index 0edccb95c..4dabb96f7 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -52,6 +52,15 @@ var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation") // ReorgNotifee represents a callback that gets called upon reorgs. type ReorgNotifee func(rev, app []*types.TipSet) error +// ChainStore is the main point of access to chain data. +// +// Raw chain data is stored in the Blockstore, with relevant markers (genesis, +// latest head tipset references) being tracked in the Datastore (key-value +// store). +// +// To alleviate disk access, the ChainStore has two ARC caches: +// 1. a tipset cache +// 2. a block => messages references cache. type ChainStore struct { bs bstore.Blockstore ds dstore.Datastore @@ -266,6 +275,9 @@ func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error { return nil } +// MaybeTakeHeavierTipSet evaluates the incoming tipset and locks it in our +// internal state as our new head, if and only if it is heavier than the current +// head. func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipSet) error { cs.heaviestLk.Lock() defer cs.heaviestLk.Unlock() @@ -331,6 +343,9 @@ func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNo return out } +// takeHeaviestTipSet actually sets the incoming tipset as our head both in +// memory and in the ChainStore. It also sends a notification to deliver to +// ReorgNotifees. func (cs *ChainStore) takeHeaviestTipSet(ctx context.Context, ts *types.TipSet) error { _, span := trace.StartSpan(ctx, "takeHeaviestTipSet") defer span.End() @@ -368,6 +383,7 @@ func (cs *ChainStore) SetHead(ts *types.TipSet) error { return cs.takeHeaviestTipSet(context.TODO(), ts) } +// Contains returns whether our BlockStore has all blocks in the supplied TipSet. func (cs *ChainStore) Contains(ts *types.TipSet) (bool, error) { for _, c := range ts.Cids() { has, err := cs.bs.Has(c) @@ -382,6 +398,8 @@ func (cs *ChainStore) Contains(ts *types.TipSet) (bool, error) { return true, nil } +// GetBlock fetches a BlockHeader with the supplied CID. It returns +// blockstore.ErrNotFound if the block was not found in the BlockStore. func (cs *ChainStore) GetBlock(c cid.Cid) (*types.BlockHeader, error) { sb, err := cs.bs.Get(c) if err != nil { @@ -474,6 +492,7 @@ func (cs *ChainStore) ReorgOps(a, b *types.TipSet) ([]*types.TipSet, []*types.Ti return leftChain, rightChain, nil } +// GetHeaviestTipSet returns the current heaviest tipset known (i.e. our head). func (cs *ChainStore) GetHeaviestTipSet() *types.TipSet { cs.heaviestLk.Lock() defer cs.heaviestLk.Unlock() diff --git a/chain/sync.go b/chain/sync.go index f20637c9e..0a08e8b15 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -53,6 +53,29 @@ var log = logging.Logger("chain") var LocalIncoming = "incoming" +// Syncer is in charge of running the chain synchronization logic. As such, it +// is tasked with these functions, amongst others: +// +// * Fast-forwards the chain as it learns of new TipSets from the network via +// the SyncManager. +// * Applies the fork choice rule to select the correct side when confronted +// with a fork in the network. +// * Requests block headers and messages from other peers when not available +// in our BlockStore. +// * Tracks blocks marked as bad in a cache. +// * Keeps the BlockStore and ChainStore consistent with our view of the world, +// the latter of which in turn informs other components when a reorg has been +// committed. +// +// The Syncer does not run workers itself. It's mainly concerned with +// ensuring a consistent state of chain consensus. The reactive and network- +// interfacing processes are part of other components, such as the SyncManager +// (which owns the sync scheduler and sync workers), BlockSync, the HELLO +// protocol, and the gossipsub block propagation layer. +// +// {hint/concept} The fork-choice rule as it currently stands is: "pick the +// chain with the heaviest weight, so long as it hasn’t deviated one finality +// threshold from our head (900 epochs, parameter determined by spec-actors)". type Syncer struct { // The interface for accessing and putting tipsets into local storage store *store.ChainStore @@ -85,6 +108,7 @@ type Syncer struct { verifier ffiwrapper.Verifier } +// NewSyncer creates a new Syncer object. func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*Syncer, error) { gen, err := sm.ChainStore().GetGenesis() if err != nil { @@ -182,6 +206,11 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool { return true } +// IncomingBlocks spawns a goroutine that subscribes to the local eventbus to +// receive new block headers as they arrive from the network, and sends them to +// the returned channel. +// +// These blocks have not necessarily been incorporated to our view of the chain. func (syncer *Syncer) IncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) { sub := syncer.incoming.Sub(LocalIncoming) out := make(chan *types.BlockHeader, 10) @@ -209,11 +238,15 @@ func (syncer *Syncer) IncomingBlocks(ctx context.Context) (<-chan *types.BlockHe return out, nil } +// ValidateMsgMeta performs structural and content hash validation of the +// messages within this block. If validation passes, it stores the messages in +// the underlying IPLD block store. func (syncer *Syncer) ValidateMsgMeta(fblk *types.FullBlock) error { if msgc := len(fblk.BlsMessages) + len(fblk.SecpkMessages); msgc > build.BlockMessageLimit { return xerrors.Errorf("block %s has too many messages (%d)", fblk.Header.Cid(), msgc) } + // Collect the CIDs of both types of messages separately: BLS and Secpk. var bcids, scids []cbg.CBORMarshaler for _, m := range fblk.BlsMessages { c := cbg.CborCid(m.Cid()) @@ -231,11 +264,14 @@ func (syncer *Syncer) ValidateMsgMeta(fblk *types.FullBlock) error { blockstore := syncer.store.Blockstore() bs := cbor.NewCborStore(blockstore) + + // Compute the root CID of the combined message trie. smroot, err := computeMsgMeta(bs, bcids, scids) if err != nil { return xerrors.Errorf("validating msgmeta, compute failed: %w", err) } + // Check that the message trie root matches with what's in the block. if fblk.Header.Messages != smroot { return xerrors.Errorf("messages in full block did not match msgmeta root in header (%s != %s)", fblk.Header.Messages, smroot) } @@ -345,6 +381,8 @@ func zipTipSetAndMessages(bs cbor.IpldStore, ts *types.TipSet, allbmsgs []*types return fts, nil } +// computeMsgMeta computes the root CID of the combined arrays of message CIDs +// of both types (BLS and Secpk). func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cbg.CBORMarshaler) (cid.Cid, error) { ctx := context.TODO() bmroot, err := amt.FromArray(ctx, bs, bmsgCids) @@ -368,14 +406,24 @@ func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cbg.CBORMarshaler) ( return mrcid, nil } +// FetchTipSet tries to load the provided tipset from the store, and falls back +// to the network (BlockSync) by querying the supplied peer if not found +// locally. +// +// {hint/usage} This is used from the HELLO protocol, to fetch the greeting +// peer's heaviest tipset if we don't have it. func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, tsk types.TipSetKey) (*store.FullTipSet, error) { if fts, err := syncer.tryLoadFullTipSet(tsk); err == nil { return fts, nil } + // fall back to the network. return syncer.Bsync.GetFullTipSet(ctx, p, tsk) } +// tryLoadFullTipSet queries the tipset in the ChainStore, and returns a full +// representation of it containing FullBlocks. If ALL blocks are not found +// locally, it errors entirely with blockstore.ErrNotFound. func (syncer *Syncer) tryLoadFullTipSet(tsk types.TipSetKey) (*store.FullTipSet, error) { ts, err := syncer.store.LoadTipSet(tsk) if err != nil { @@ -400,6 +448,12 @@ func (syncer *Syncer) tryLoadFullTipSet(tsk types.TipSetKey) (*store.FullTipSet, return fts, nil } +// Sync tries to advance our view of the chain to `maybeHead`. It does nothing +// if our current head is heavier than the requested tipset, or if we're already +// at the requested head, or if the head is the genesis. +// +// Most of the heavy-lifting logic happens in syncer#collectChain. Refer to the +// godocs on that method for a more detailed view. func (syncer *Syncer) Sync(ctx context.Context, maybeHead *types.TipSet) error { ctx, span := trace.StartSpan(ctx, "chain.Sync") defer span.End() @@ -1004,6 +1058,39 @@ func extractSyncState(ctx context.Context) *SyncerState { return nil } +// collectHeaders collects the headers from the blocks between any two tipsets. +// +// `from` is the heaviest/projected/target tipset we have learned about, and +// `to` is usually an anchor tipset we already have in our view of the chain +// (which could be the genesis). +// +// collectHeaders checks if portions of the chain are in our ChainStore; falling +// down to the network to retrieve the missing parts. If during the process, any +// portion we receive is in our denylist (bad list), we short-circuit. +// +// {hint/naming}: `from` and `to` is in inverse order. `from` is the highest, +// and `to` is the lowest. This method traverses the chain backwards. +// +// {hint/usage}: This is used by collectChain, which is in turn called from the +// main Sync method (Syncer#Sync), so it's a pretty central method. +// +// {hint/logic}: The logic of this method is as follows: +// +// 1. Check that the from tipset is not linked to a parent block known to be +// bad. +// 2. Check the consistency of beacon entries in the from tipset. We check +// total equality of the BeaconEntries in each block. +// 3. Travers the chain backwards, for each tipset: +// 3a. Load it from the chainstore; if found, it move on to its parent. +// 3b. Query our peers via BlockSync in batches, requesting up to a +// maximum of 500 tipsets every time. +// +// Once we've concluded, if we find a mismatching tipset at the height where the +// anchor tipset should be, we are facing a fork, and we invoke Syncer#syncFork +// to resolve it. Refer to the godocs there. +// +// All throughout the process, we keep checking if the received blocks are in +// the deny list, and short-circuit the process if so. func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to *types.TipSet) ([]*types.TipSet, error) { ctx, span := trace.StartSpan(ctx, "collectHeaders") defer span.End() @@ -1020,6 +1107,8 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to } } + // Check if the parents of the from block are in the denylist. + // i.e. if a fork of the chain has been requested that we know to be bad. for _, pcid := range from.Parents().Cids() { if reason, ok := syncer.bad.Has(pcid); ok { markBad("linked to %s", pcid) @@ -1090,8 +1179,8 @@ loop: } // NB: GetBlocks validates that the blocks are in-fact the ones we - // requested, and that they are correctly linked to eachother. It does - // not validate any state transitions + // requested, and that they are correctly linked to one another. It does + // not validate any state transitions. window := 500 if gap := int(blockSet[len(blockSet)-1].Height() - untilHeight); gap < window { window = gap @@ -1132,7 +1221,6 @@ loop: at = blks[len(blks)-1].Parents() } - // We have now ascertained that this is *not* a 'fast forward' if !types.CidArrsEqual(blockSet[len(blockSet)-1].Parents().Cids(), to.Cids()) { last := blockSet[len(blockSet)-1] if last.Parents() == to.Parents() { @@ -1140,6 +1228,8 @@ loop: return blockSet, nil } + // We have now ascertained that this is *not* a 'fast forward' + log.Warnf("(fork detected) synced header chain (%s - %d) does not link to our best block (%s - %d)", from.Cids(), from.Height(), to.Cids(), to.Height()) fork, err := syncer.syncFork(ctx, last, to) if err != nil { @@ -1161,6 +1251,12 @@ loop: var ErrForkTooLong = fmt.Errorf("fork longer than threshold") +// syncFork tries to obtain the chain fragment that links a fork into a common +// ancestor in our view of the chain. +// +// If the fork is too long (build.ForkLengthThreshold), we add the entire subchain to the +// denylist. Else, we find the common ancestor, and add the missing chain +// fragment until the fork point to the returned []TipSet. func (syncer *Syncer) syncFork(ctx context.Context, from *types.TipSet, to *types.TipSet) ([]*types.TipSet, error) { tips, err := syncer.Bsync.GetBlocks(ctx, from.Parents(), int(build.ForkLengthThreshold)) if err != nil { @@ -1312,6 +1408,25 @@ func persistMessages(bs bstore.Blockstore, bst *blocksync.BSTipSet) error { return nil } +// collectChain tries to advance our view of the chain to the purported head. +// +// It goes through various stages: +// +// 1. StageHeaders: we proceed in the sync process by requesting block headers +// from our peers, moving back from their heads, until we reach a tipset +// that we have in common (such a common tipset must exist, thought it may +// simply be the genesis block). +// +// If the common tipset is our head, we treat the sync as a "fast-forward", +// else we must drop part of our chain to connect to the peer's head +// (referred to as "forking"). +// +// 2. StagePersistHeaders: now that we've collected the missing headers, +// augmented by those on the other side of a fork, we persist them to the +// BlockStore. +// +// 3. StageMessages: having acquired the headers and found a common tipset, +// we then move forward, requesting the full blocks, including the messages. func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error { ctx, span := trace.StartSpan(ctx, "collectChain") defer span.End() @@ -1361,9 +1476,8 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error func VerifyElectionPoStVRF(ctx context.Context, worker address.Address, rand []byte, evrf []byte) error { if build.InsecurePoStValidation { return nil - } else { - return gen.VerifyVRF(ctx, worker, rand, evrf) } + return gen.VerifyVRF(ctx, worker, rand, evrf) } func (syncer *Syncer) State() []SyncerState { @@ -1374,6 +1488,7 @@ func (syncer *Syncer) State() []SyncerState { return out } +// MarkBad manually adds a block to the "bad blocks" cache. func (syncer *Syncer) MarkBad(blk cid.Cid) { syncer.bad.Add(blk, "manually marked bad") } @@ -1381,7 +1496,7 @@ func (syncer *Syncer) MarkBad(blk cid.Cid) { func (syncer *Syncer) CheckBadBlockCache(blk cid.Cid) (string, bool) { return syncer.bad.Has(blk) } -func (syncer *Syncer) getLatestBeaconEntry(ctx context.Context, ts *types.TipSet) (*types.BeaconEntry, error) { +func (syncer *Syncer) getLatestBeaconEntry(_ context.Context, ts *types.TipSet) (*types.BeaconEntry, error) { cur := ts for i := 0; i < 20; i++ { cbe := cur.Blocks()[0].BeaconEntries diff --git a/miner/miner.go b/miner/miner.go index bdeed8ac5..fa97bd265 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -252,6 +252,12 @@ func (m *Miner) hasPower(ctx context.Context, addr address.Address, ts *types.Ti return mpower.MinerPower.QualityAdjPower.GreaterThanEqual(power.ConsensusMinerMinPower), nil } +// mineOne mines a single block, and does so synchronously, if and only if we +// have won the current round. +// +// {hint/landmark}: This method coordinates all the steps involved in mining a +// block, including the condition of whether mine or not at all depending on +// whether we win the round or not. func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, error) { log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.TipSet.Cids())) start := time.Now() From a7d662a7d8876b11b7125279d248a0ef38b738c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 24 Jun 2020 00:23:39 +0200 Subject: [PATCH 246/379] Update to actually working sector-storage --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e09898888..33e0e628b 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d + github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 diff --git a/go.sum b/go.sum index ca866bba5..7b692a145 100644 --- a/go.sum +++ b/go.sum @@ -254,6 +254,8 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d h1:yJJqXCMEhvXJoOS6T1O46FXl+A3mlttXhgjcTCp+Tgo= github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= +github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8 h1:lqv3F5WgjRUH6qLbWQp3Of5IIQXLRT37R1AsFEFAJPc= +github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= From 11c53c26ffa3e581d3dfc82b47b6b8a4a0d27f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 24 Jun 2020 00:47:47 +0200 Subject: [PATCH 247/379] Update sector-storage to fix #2080 and #1917 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 33e0e628b..4c7c91d10 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8 + github.com/filecoin-project/sector-storage v0.0.0-20200623224636-de544b531601 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 diff --git a/go.sum b/go.sum index 7b692a145..76d99cc85 100644 --- a/go.sum +++ b/go.sum @@ -254,8 +254,8 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d h1:yJJqXCMEhvXJoOS6T1O46FXl+A3mlttXhgjcTCp+Tgo= github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= -github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8 h1:lqv3F5WgjRUH6qLbWQp3Of5IIQXLRT37R1AsFEFAJPc= -github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= +github.com/filecoin-project/sector-storage v0.0.0-20200623224636-de544b531601 h1:EgMmHLoJ4caLU8RzgKQux4TyX/ZploXGtIu5Q1SaxKw= +github.com/filecoin-project/sector-storage v0.0.0-20200623224636-de544b531601/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= From d7bb284e577971f7305a85f5e284cd94e4049c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 24 Jun 2020 00:54:28 +0200 Subject: [PATCH 248/379] miner: Move set-addrs command to a new 'actor' namespace --- cmd/lotus-storage-miner/actor.go | 91 ++++++++++++++++++++++++++++++++ cmd/lotus-storage-miner/info.go | 74 -------------------------- cmd/lotus-storage-miner/main.go | 1 + 3 files changed, 92 insertions(+), 74 deletions(-) create mode 100644 cmd/lotus-storage-miner/actor.go diff --git a/cmd/lotus-storage-miner/actor.go b/cmd/lotus-storage-miner/actor.go new file mode 100644 index 000000000..87dfd7254 --- /dev/null +++ b/cmd/lotus-storage-miner/actor.go @@ -0,0 +1,91 @@ +package main + +import ( + "fmt" + + ma "github.com/multiformats/go-multiaddr" + "github.com/urfave/cli/v2" + + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" +) + +var actorCmd = &cli.Command{ + Name: "actor", + Usage: "manipulate the miner actor", + Subcommands: []*cli.Command{ + actorSetAddrsCmd, + }, +} + +var actorSetAddrsCmd = &cli.Command{ + Name: "set-addrs", + Usage: "set addresses that your miner can be publically dialed on", + Flags: []cli.Flag{ + &cli.Int64Flag{ + Name: "gas-limit", + Usage: "set gas limit", + Value: 100000, + }, + }, + Action: func(cctx *cli.Context) error { + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + var addrs []abi.Multiaddrs + for _, a := range cctx.Args().Slice() { + maddr, err := ma.NewMultiaddr(a) + if err != nil { + return fmt.Errorf("failed to parse %q as a multiaddr: %w", a, err) + } + + addrs = append(addrs, maddr.Bytes()) + } + + maddr, err := nodeApi.ActorAddress(ctx) + if err != nil { + return err + } + + minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + params, err := actors.SerializeParams(&miner.ChangeMultiaddrsParams{addrs}) + if err != nil { + return err + } + + gasLimit := cctx.Int64("gas-limit") + + smsg, err := api.MpoolPushMessage(ctx, &types.Message{ + To: maddr, + From: minfo.Worker, + Value: types.NewInt(0), + GasPrice: types.NewInt(1), + GasLimit: gasLimit, + Method: 18, + Params: params, + }) + + fmt.Printf("Requested multiaddrs change in message %s\n", smsg.Cid()) + return nil + + }, +} diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 667df5342..17e06e214 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -8,18 +8,15 @@ import ( "time" "github.com/fatih/color" - ma "github.com/multiformats/go-multiaddr" "github.com/urfave/cli/v2" "golang.org/x/xerrors" - "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/builtin/power" sealing "github.com/filecoin-project/storage-fsm" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -27,9 +24,6 @@ import ( var infoCmd = &cli.Command{ Name: "info", Usage: "Print storage miner info", - Subcommands: []*cli.Command{ - infoSetAddrsCmd, - }, Flags: []cli.Flag{ &cli.BoolFlag{Name: "color"}, }, @@ -254,71 +248,3 @@ func sectorsInfo(ctx context.Context, napi api.StorageMiner) error { return nil } - -var infoSetAddrsCmd = &cli.Command{ - Name: "set-addrs", - Usage: "set addresses that your miner can be publically dialed on", - Flags: []cli.Flag{ - &cli.Int64Flag{ - Name: "gas-limit", - Usage: "set gas limit", - Value: 100000, - }, - }, - Action: func(cctx *cli.Context) error { - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - - api, acloser, err := lcli.GetFullNodeAPI(cctx) - if err != nil { - return err - } - defer acloser() - - ctx := lcli.ReqContext(cctx) - - var addrs []abi.Multiaddrs - for _, a := range cctx.Args().Slice() { - maddr, err := ma.NewMultiaddr(a) - if err != nil { - return fmt.Errorf("failed to parse %q as a multiaddr: %w", a, err) - } - - addrs = append(addrs, maddr.Bytes()) - } - - maddr, err := nodeApi.ActorAddress(ctx) - if err != nil { - return err - } - - minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } - - params, err := actors.SerializeParams(&miner.ChangeMultiaddrsParams{addrs}) - if err != nil { - return err - } - - gasLimit := cctx.Int64("gas-limit") - - smsg, err := api.MpoolPushMessage(ctx, &types.Message{ - To: maddr, - From: minfo.Worker, - Value: types.NewInt(0), - GasPrice: types.NewInt(1), - GasLimit: gasLimit, - Method: 18, - Params: params, - }) - - fmt.Printf("Requested multiaddrs change in message %s\n", smsg.Cid()) - return nil - - }, -} diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index dc6de7029..bda94f54a 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -22,6 +22,7 @@ func main() { lotuslog.SetupLogLevels() local := []*cli.Command{ + actorCmd, dealsCmd, infoCmd, initCmd, From 001d4ab0029c0a71ae0ab8fa1ee10a3fbdae43d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 24 Jun 2020 01:00:32 +0200 Subject: [PATCH 249/379] Appease the linter --- cmd/lotus-storage-miner/actor.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-storage-miner/actor.go b/cmd/lotus-storage-miner/actor.go index 87dfd7254..44eb7a0e4 100644 --- a/cmd/lotus-storage-miner/actor.go +++ b/cmd/lotus-storage-miner/actor.go @@ -15,7 +15,7 @@ import ( ) var actorCmd = &cli.Command{ - Name: "actor", + Name: "actor", Usage: "manipulate the miner actor", Subcommands: []*cli.Command{ actorSetAddrsCmd, @@ -33,7 +33,7 @@ var actorSetAddrsCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + nodeAPI, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { return err } @@ -57,7 +57,7 @@ var actorSetAddrsCmd = &cli.Command{ addrs = append(addrs, maddr.Bytes()) } - maddr, err := nodeApi.ActorAddress(ctx) + maddr, err := nodeAPI.ActorAddress(ctx) if err != nil { return err } @@ -67,7 +67,7 @@ var actorSetAddrsCmd = &cli.Command{ return err } - params, err := actors.SerializeParams(&miner.ChangeMultiaddrsParams{addrs}) + params, err := actors.SerializeParams(&miner.ChangeMultiaddrsParams{NewMultiaddrs: addrs}) if err != nil { return err } @@ -83,6 +83,9 @@ var actorSetAddrsCmd = &cli.Command{ Method: 18, Params: params, }) + if err != nil { + return err + } fmt.Printf("Requested multiaddrs change in message %s\n", smsg.Cid()) return nil From 24c7f47566c8e0e85e4611b0d50d620131767a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=87?= Date: Wed, 24 Jun 2020 10:14:20 +0800 Subject: [PATCH 250/379] Modify print faulty sectors in provingFaultsCmd --- cmd/lotus-storage-miner/proving.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index d9d7da8e3..60cf2ab99 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -3,7 +3,6 @@ package main import ( "bytes" "fmt" - "math" "os" "text/tabwriter" "time" @@ -73,14 +72,29 @@ var provingFaultsCmd = &cli.Command{ return err } if len(faults) == 0 { - fmt.Println("no sector fault") + fmt.Println("no faulty sectors") } - for _, num := range faults { - num2 := num % (mas.Info.WindowPoStPartitionSectors * (miner.WPoStPeriodDeadlines - 1)) - deadline := uint64(math.Floor(float64(num2)/float64(mas.Info.WindowPoStPartitionSectors))) + 1 - fmt.Printf("sector number = %d,deadline = %d\n", num, deadline) + head, err := api.ChainHead(ctx) + if err != nil { + return xerrors.Errorf("getting chain head: %w", err) } - return nil + deadlines, err := api.StateMinerDeadlines(ctx, maddr, head.Key()) + if err != nil { + return xerrors.Errorf("getting miner deadlines: %w", err) + } + tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) + _, _ = fmt.Fprintln(tw, "deadline\tsectors") + for deadline, sectors := range deadlines.Due { + intersectSectors, _ := bitfield.IntersectBitField(sectors, mas.Faults) + if intersectSectors != nil { + allSectors, _ := intersectSectors.All(100000000000) + for _, num := range allSectors { + _, _ = fmt.Fprintf(tw, "%d\t%d\n", deadline, num) + } + } + + } + return tw.Flush() }, } From 0b1fa54a4dd23b395ece8125591c6a87f3d132e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 24 Jun 2020 12:38:46 +0200 Subject: [PATCH 251/379] wdpost: Remove commented code --- storage/wdpost_run.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index fe42d2940..fcace70dd 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -383,8 +383,6 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo return nil, xerrors.Errorf("get need prove sectors: %w", err) } - // var skipped *abi.BitField - // { good, err := s.checkSectors(ctx, nps) if err != nil { return nil, xerrors.Errorf("checking sectors to skip: %w", err) @@ -394,7 +392,6 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo if err != nil { return nil, xerrors.Errorf("nps - good: %w", err) } - // } skipCount, err := skipped.Count() if err != nil { From 358b36bc66b3923f6b4d82accac9acd22d23a6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 24 Jun 2020 14:34:53 +0200 Subject: [PATCH 252/379] chainwatch: state_heights_uindex is not unique --- cmd/lotus-chainwatch/storage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index 020ca1d7f..f7f80a9c6 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -118,7 +118,7 @@ create unique index if not exists block_cid_uindex create materialized view if not exists state_heights as select distinct height, parentstateroot from blocks; -create unique index if not exists state_heights_uindex +create index if not exists state_heights_index on state_heights (height); create index if not exists state_heights_height_index From 008a2969b2706988036d79f2753d8fa6318329b0 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 24 Jun 2020 17:05:24 +0200 Subject: [PATCH 253/379] Fix two races in events Also race fix: depends on https://github.com/ipfs/go-blockservice/pull/65 Resolves #2092, #2099, #2108, #1930, #2110 Signed-off-by: Jakub Sztandera --- api/test/deals.go | 13 +++++++------ api/test/mining.go | 5 +++-- chain/events/events_called.go | 4 +++- chain/events/events_height.go | 14 +++++++++++--- go.mod | 2 +- go.sum | 2 ++ miner/miner.go | 3 +++ 7 files changed, 30 insertions(+), 13 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 0150a1315..22152d7ab 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -8,6 +8,7 @@ import ( "math/rand" "os" "path/filepath" + "sync/atomic" "testing" "time" @@ -52,11 +53,11 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport } time.Sleep(time.Second) - mine := true + mine := int64(1) done := make(chan struct{}) go func() { defer close(done) - for mine { + for atomic.LoadInt64(&mine) == 1 { time.Sleep(blocktime) if err := sn[0].MineOne(ctx, func(bool) {}); err != nil { t.Error(err) @@ -66,7 +67,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport makeDeal(t, ctx, 6, client, miner, carExport) - mine = false + atomic.AddInt64(&mine, -1) fmt.Println("shutting down mining") <-done } @@ -89,12 +90,12 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) { } time.Sleep(time.Second) - mine := true + mine := int64(1) done := make(chan struct{}) go func() { defer close(done) - for mine { + for atomic.LoadInt64(&mine) == 1 { time.Sleep(blocktime) if err := sn[0].MineOne(ctx, func(bool) {}); err != nil { t.Error(err) @@ -105,7 +106,7 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) { makeDeal(t, ctx, 6, client, miner, false) makeDeal(t, ctx, 7, client, miner, false) - mine = false + atomic.AddInt64(&mine, -1) fmt.Println("shutting down mining") <-done } diff --git a/api/test/mining.go b/api/test/mining.go index b19095450..f43af2cd5 100644 --- a/api/test/mining.go +++ b/api/test/mining.go @@ -126,6 +126,7 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo minedTwo := make(chan struct{}) go func() { + doneMinedTwo := false defer close(done) prevExpect := 0 @@ -175,9 +176,9 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo time.Sleep(blocktime) } - if prevExpect == 2 && expect == 2 && minedTwo != nil { + if prevExpect == 2 && expect == 2 && !doneMinedTwo { close(minedTwo) - minedTwo = nil + doneMinedTwo = true } prevExpect = expect diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 04e7be715..0bae99404 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -84,6 +84,9 @@ type calledEvents struct { } func (e *calledEvents) headChangeCalled(rev, app []*types.TipSet) error { + e.lk.Lock() + defer e.lk.Unlock() + for _, ts := range rev { e.handleReverts(ts) e.at = ts.Height() @@ -134,7 +137,6 @@ func (e *calledEvents) checkNewCalls(ts *types.TipSet) { e.messagesForTs(pts, func(msg *types.Message) { // TODO: provide receipts - for tid, matchFns := range e.matchers { var matched bool for _, matchFn := range matchFns { diff --git a/chain/events/events_height.go b/chain/events/events_height.go index cbf756c20..fc94d6262 100644 --- a/chain/events/events_height.go +++ b/chain/events/events_height.go @@ -26,12 +26,15 @@ type heightEvents struct { } func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { + ctx, span := trace.StartSpan(e.ctx, "events.HeightHeadChange") defer span.End() span.AddAttributes(trace.Int64Attribute("endHeight", int64(app[0].Height()))) span.AddAttributes(trace.Int64Attribute("reverts", int64(len(rev)))) span.AddAttributes(trace.Int64Attribute("applies", int64(len(app)))) + e.lk.Lock() + defer e.lk.Unlock() for _, ts := range rev { // TODO: log error if h below gcconfidence // revert height-based triggers @@ -40,7 +43,10 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { for _, tid := range e.htHeights[h] { ctx, span := trace.StartSpan(ctx, "events.HeightRevert") - err := e.heightTriggers[tid].revert(ctx, ts) + rev := e.heightTriggers[tid].revert + e.lk.Unlock() + err := rev(ctx, ts) + e.lk.Lock() e.heightTriggers[tid].called = false span.End() @@ -98,8 +104,10 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error { ctx, span := trace.StartSpan(ctx, "events.HeightApply") span.AddAttributes(trace.BoolAttribute("immediate", false)) - - err = hnd.handle(ctx, incTs, h) + handle := hnd.handle + e.lk.Unlock() + err = handle(ctx, incTs, h) + e.lk.Lock() span.End() if err != nil { diff --git a/go.mod b/go.mod index 4c7c91d10..3b8ecf76f 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/ipfs/go-bitswap v0.2.8 github.com/ipfs/go-block-format v0.0.2 - github.com/ipfs/go-blockservice v0.1.3 + github.com/ipfs/go-blockservice v0.1.4-0.20200624145336-a978cec6e834 github.com/ipfs/go-cid v0.0.6 github.com/ipfs/go-cidutil v0.0.2 github.com/ipfs/go-datastore v0.4.4 diff --git a/go.sum b/go.sum index 76d99cc85..7fb39f472 100644 --- a/go.sum +++ b/go.sum @@ -467,6 +467,8 @@ github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbR github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.1.3 h1:9XgsPMwwWJSC9uVr2pMDsW2qFTBSkxpGMhmna8mIjPM= github.com/ipfs/go-blockservice v0.1.3/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= +github.com/ipfs/go-blockservice v0.1.4-0.20200624145336-a978cec6e834 h1:hFJoI1D2a3MqiNkSb4nKwrdkhCngUxUTFNwVwovZX2s= +github.com/ipfs/go-blockservice v0.1.4-0.20200624145336-a978cec6e834/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= diff --git a/miner/miner.go b/miner/miner.go index fa97bd265..1f5f8dad5 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -215,6 +215,9 @@ type MiningBase struct { } func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) { + m.lk.Lock() + defer m.lk.Unlock() + bts, err := m.api.ChainHead(ctx) if err != nil { return nil, err From ef0abf2b98ada6a96fcebc4c9c56bccb4fa40681 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 23 Jun 2020 09:04:46 -0700 Subject: [PATCH 254/379] disable/enable retrieval deal consideration via config --- node/builder.go | 2 ++ node/config/def.go | 10 +++++---- node/modules/dtypes/miner.go | 8 +++++++ node/modules/storageminer.go | 43 ++++++++++++++++++++++++++++++++---- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/node/builder.go b/node/builder.go index 3b6c6fbda..6b987dc28 100644 --- a/node/builder.go +++ b/node/builder.go @@ -313,6 +313,8 @@ func Online() Option { Override(new(gen.WinningPoStProver), storage.NewWinningPoStProver), Override(new(*miner.Miner), modules.SetupBlockProducer), + Override(new(dtypes.AcceptingRetrievalDealsConfigFunc), modules.NewAcceptingRetrievalDealsConfigFunc), + Override(new(dtypes.SetAcceptingRetrievalDealsConfigFunc), modules.NewSetAcceptingRetrievalDealsConfigFunc), Override(new(dtypes.AcceptingStorageDealsConfigFunc), modules.NewAcceptingStorageDealsConfigFunc), Override(new(dtypes.SetAcceptingStorageDealsConfigFunc), modules.NewSetAcceptingStorageDealsConfigFunc), Override(new(dtypes.StorageDealPieceCidBlocklistConfigFunc), modules.NewStorageDealPieceCidBlocklistConfigFunc), diff --git a/node/config/def.go b/node/config/def.go index 76a6a89ea..a86f87d24 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -34,8 +34,9 @@ type StorageMiner struct { } type DealmakingConfig struct { - AcceptingStorageDeals bool - PieceCidBlocklist []cid.Cid + AcceptingStorageDeals bool + AcceptingRetrievalDeals bool + PieceCidBlocklist []cid.Cid } // API contains configs for API endpoint @@ -123,8 +124,9 @@ func DefaultStorageMiner() *StorageMiner { }, Dealmaking: DealmakingConfig{ - AcceptingStorageDeals: true, - PieceCidBlocklist: []cid.Cid{}, + AcceptingStorageDeals: true, + AcceptingRetrievalDeals: true, + PieceCidBlocklist: []cid.Cid{}, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 584642a3b..a0acb8f18 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -18,6 +18,14 @@ type AcceptingStorageDealsConfigFunc func() (bool, error) // storage deal acceptance. type SetAcceptingStorageDealsConfigFunc func(bool) error +// AcceptingRetrievalDealsFunc is a function which reads from miner config to +// determine if the user has disabled retrieval acceptance (or not). +type AcceptingRetrievalDealsConfigFunc func() (bool, error) + +// SetAcceptingRetrievalDealsFunc is a function which is used to disable or enable +// retrieval deal acceptance. +type SetAcceptingRetrievalDealsConfigFunc func(bool) error + // StorageDealPieceCidBlocklistConfigFunc is a function which reads from miner config // to obtain a list of CIDs for which the storage miner will not accept storage // proposals. diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index c6cadec34..3ccc5daa7 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -357,14 +357,31 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con } // RetrievalProvider creates a new retrieval provider attached to the provider blockstore -func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, full lapi.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, ibs dtypes.StagingBlockstore) (retrievalmarket.RetrievalProvider, error) { +func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, full lapi.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, ibs dtypes.StagingBlockstore, isAcceptingFunc dtypes.AcceptingRetrievalDealsConfigFunc) (retrievalmarket.RetrievalProvider, error) { adapter := retrievaladapter.NewRetrievalProviderNode(miner, sealer, full) - address, err := minerAddrFromDS(ds) + + maddr, err := minerAddrFromDS(ds) if err != nil { return nil, err } - network := rmnet.NewFromLibp2pHost(h) - return retrievalimpl.NewProvider(address, adapter, network, pieceStore, ibs, namespace.Wrap(ds, datastore.NewKey("/retrievals/provider"))) + + netwk := rmnet.NewFromLibp2pHost(h) + + opt := retrievalimpl.DealDeciderOpt(func(ctx context.Context, state retrievalmarket.ProviderDealState) (bool, string, error) { + b, err := isAcceptingFunc() + if err != nil { + return false, "miner error", err + } + + if !b { + log.Warn("retrieval deal acceptance disabled; rejecting retrieval deal proposal from client") + return false, "miner is not accepting retrieval deals", nil + } + + return true, "", nil + }) + + return retrievalimpl.NewProvider(maddr, adapter, netwk, pieceStore, ibs, namespace.Wrap(ds, datastore.NewKey("/retrievals/provider")), opt) } func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStorage, si stores.SectorIndex, cfg *ffiwrapper.Config, sc sectorstorage.SealerConfig, urls sectorstorage.URLs, sa sectorstorage.StorageAuth) (*sectorstorage.Manager, error) { @@ -399,6 +416,24 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA return sectorstorage.StorageAuth(headers), nil } +func NewAcceptingRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.AcceptingRetrievalDealsConfigFunc, error) { + return func() (out bool, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.AcceptingRetrievalDeals + }) + return + }, nil +} + +func NewSetAcceptingRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.SetAcceptingRetrievalDealsConfigFunc, error) { + return func(b bool) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.AcceptingRetrievalDeals = b + }) + return + }, nil +} + func NewAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.AcceptingStorageDealsConfigFunc, error) { return func() (out bool, err error) { err = readCfg(r, func(cfg *config.StorageMiner) { From bc90b857c9fe89d8206f563232b16e6347c6dd23 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 23 Jun 2020 09:30:34 -0700 Subject: [PATCH 255/379] change "lotus-storage-miner deals" to "lotus-storage-miner storage-deals" --- cmd/lotus-storage-miner/main.go | 2 +- cmd/lotus-storage-miner/market.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index bda94f54a..6d99645fa 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -23,7 +23,7 @@ func main() { local := []*cli.Command{ actorCmd, - dealsCmd, + storageDealsCmd, infoCmd, initCmd, rewardsCmd, diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index c668456f0..1985d0004 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -217,9 +217,9 @@ var getAskCmd = &cli.Command{ }, } -var dealsCmd = &cli.Command{ - Name: "deals", - Usage: "interact with your deals", +var storageDealsCmd = &cli.Command{ + Name: "storage-deals", + Usage: "interact with your storage deals", Subcommands: []*cli.Command{ dealsImportDataCmd, dealsListCmd, From 176d0bb7c0f94e4c64267ceed02b84bb2d825987 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 23 Jun 2020 10:17:31 -0700 Subject: [PATCH 256/379] add "lotus-storage-miner retrieval-deals" subcommands - enable retrieval - disable retrieval --- api/api_storage.go | 1 + api/apistruct/struct.go | 15 +++++--- cmd/lotus-storage-miner/main.go | 1 + cmd/lotus-storage-miner/market.go | 2 +- cmd/lotus-storage-miner/retrieval-deals.go | 45 ++++++++++++++++++++++ node/impl/storminer.go | 5 +++ 6 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 cmd/lotus-storage-miner/retrieval-deals.go diff --git a/api/api_storage.go b/api/api_storage.go index 6ce8e7f2e..6d8fe384e 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -57,6 +57,7 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) DealsSetAcceptingStorageDeals(context.Context, bool) error + DealsSetAcceptingRetrievalDeals(context.Context, bool) error DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error) DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index e09b57df6..0c0acd05e 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -224,11 +224,12 @@ type StorageMinerStruct struct { StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` - DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` - DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` - DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` - DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` + DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` + DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsSetAcceptingRetrievalDeals func(context.Context, bool) error `perm:"admin"` + DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` + DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -881,6 +882,10 @@ func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, return c.Internal.DealsSetAcceptingStorageDeals(ctx, b) } +func (c *StorageMinerStruct) DealsSetAcceptingRetrievalDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetAcceptingRetrievalDeals(ctx, b) +} + func (c *StorageMinerStruct) DealsPieceCidBlocklist(ctx context.Context) ([]cid.Cid, error) { return c.Internal.DealsPieceCidBlocklist(ctx) } diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index 6d99645fa..62efe9370 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -24,6 +24,7 @@ func main() { local := []*cli.Command{ actorCmd, storageDealsCmd, + retrievalDealsCmd, infoCmd, initCmd, rewardsCmd, diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 1985d0004..e658be1cf 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -219,7 +219,7 @@ var getAskCmd = &cli.Command{ var storageDealsCmd = &cli.Command{ Name: "storage-deals", - Usage: "interact with your storage deals", + Usage: "Manage storage deals and related configuration", Subcommands: []*cli.Command{ dealsImportDataCmd, dealsListCmd, diff --git a/cmd/lotus-storage-miner/retrieval-deals.go b/cmd/lotus-storage-miner/retrieval-deals.go new file mode 100644 index 000000000..ee503fb2b --- /dev/null +++ b/cmd/lotus-storage-miner/retrieval-deals.go @@ -0,0 +1,45 @@ +package main + +import ( + lcli "github.com/filecoin-project/lotus/cli" + "github.com/urfave/cli/v2" +) + +var retrievalDealsCmd = &cli.Command{ + Name: "retrieval-deals", + Usage: "Manage retrieval deals and related configuration", + Subcommands: []*cli.Command{ + enableRetrievalCmd, + disableRetrievalCmd, + }, +} + +var enableRetrievalCmd = &cli.Command{ + Name: "enable", + Usage: "Configure the miner to consider retrieval deal proposals", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + return api.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), true) + }, +} + +var disableRetrievalCmd = &cli.Command{ + Name: "disable", + Usage: "Configure the miner to reject all retrieval deal proposals", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + return api.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), false) + }, +} diff --git a/node/impl/storminer.go b/node/impl/storminer.go index d7a8d4d33..b993d1b46 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -44,6 +44,7 @@ type StorageMinerAPI struct { *stores.Index SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc + SetAcceptingRetrievalDealsConfigFunc dtypes.SetAcceptingRetrievalDealsConfigFunc StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc } @@ -228,6 +229,10 @@ func (sm *StorageMinerAPI) DealsSetAcceptingStorageDeals(ctx context.Context, b return sm.SetAcceptingStorageDealsConfigFunc(b) } +func (sm *StorageMinerAPI) DealsSetAcceptingRetrievalDeals(ctx context.Context, b bool) error { + return sm.SetAcceptingRetrievalDealsConfigFunc(b) +} + func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fname string) error { fi, err := os.Open(fname) if err != nil { From 4c760ec1b108d9d279cad1ea3501cfeb1cddbd94 Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 23 Jun 2020 13:48:07 -0700 Subject: [PATCH 257/379] lint: update comments to match type declarations --- node/modules/dtypes/miner.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index a0acb8f18..9ea8c3440 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -10,20 +10,20 @@ import ( type MinerAddress address.Address type MinerID abi.ActorID -// AcceptingStorageDealsFunc is a function which reads from miner config to -// determine if the user has disabled storage deals (or not). +// AcceptingStorageDealsConfigFunc is a function which reads from miner config +// to determine if the user has disabled storage deals (or not). type AcceptingStorageDealsConfigFunc func() (bool, error) -// SetAcceptingStorageDealsFunc is a function which is used to disable or enable -// storage deal acceptance. +// SetAcceptingStorageDealsConfigFunc is a function which is used to disable or +// enable storage deal acceptance. type SetAcceptingStorageDealsConfigFunc func(bool) error -// AcceptingRetrievalDealsFunc is a function which reads from miner config to -// determine if the user has disabled retrieval acceptance (or not). +// AcceptingRetrievalDealsConfigFunc is a function which reads from miner config +// to determine if the user has disabled retrieval acceptance (or not). type AcceptingRetrievalDealsConfigFunc func() (bool, error) -// SetAcceptingRetrievalDealsFunc is a function which is used to disable or enable -// retrieval deal acceptance. +// SetAcceptingRetrievalDealsConfigFunc is a function which is used to disable +// or enable retrieval deal acceptance. type SetAcceptingRetrievalDealsConfigFunc func(bool) error // StorageDealPieceCidBlocklistConfigFunc is a function which reads from miner config From a98c4038f40256074d5a4a44ce3e206306fd65b3 Mon Sep 17 00:00:00 2001 From: frrist Date: Wed, 24 Jun 2020 10:39:45 -0700 Subject: [PATCH 258/379] fix: use tipset corresponding to stateroot - Use te tipsetkey corresponding to the stateroot when fetching actor data from the lotus api. --- cmd/lotus-chainwatch/sync.go | 48 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index d42a72b9b..88afb647e 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -53,6 +53,7 @@ type minerKey struct { addr address.Address act types.Actor stateroot cid.Cid + tsKey types.TipSetKey } type minerInfo struct { @@ -66,10 +67,11 @@ type minerInfo struct { type actorInfo struct { stateroot cid.Cid + tsKey types.TipSetKey state string } -func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipSet, maxBatch int) { +func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types.TipSet, maxBatch int) { var alk sync.Mutex log.Infof("Getting synced block list") @@ -81,7 +83,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS allToSync := map[cid.Cid]*types.BlockHeader{} toVisit := list.New() - for _, header := range ts.Blocks() { + for _, header := range headTs.Blocks() { toVisit.PushBack(header) } @@ -116,7 +118,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS for len(allToSync) > 0 { actors := map[address.Address]map[types.Actor]actorInfo{} - addresses := map[address.Address]address.Address{} + addressToID := map[address.Address]address.Address{} minH := abi.ChainEpoch(math.MaxInt64) for _, header := range allToSync { @@ -129,7 +131,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS for c, header := range allToSync { if header.Height < minH+abi.ChainEpoch(maxBatch) { toSync[c] = header - addresses[header.Miner] = address.Undef + addressToID[header.Miner] = address.Undef } } for c := range toSync { @@ -146,20 +148,20 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS } if len(bh.Parents) == 0 { // genesis case - ts, _ := types.NewTipSet([]*types.BlockHeader{bh}) - aadrs, err := api.StateListActors(ctx, ts.Key()) + genesisTs, _ := types.NewTipSet([]*types.BlockHeader{bh}) + aadrs, err := api.StateListActors(ctx, genesisTs.Key()) if err != nil { log.Error(err) return } parmap.Par(50, aadrs, func(addr address.Address) { - act, err := api.StateGetActor(ctx, addr, ts.Key()) + act, err := api.StateGetActor(ctx, addr, genesisTs.Key()) if err != nil { log.Error(err) return } - ast, err := api.StateReadState(ctx, act, ts.Key()) + ast, err := api.StateReadState(ctx, act, genesisTs.Key()) if err != nil { log.Error(err) return @@ -177,9 +179,10 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS } actors[addr][*act] = actorInfo{ stateroot: bh.ParentStateRoot, + tsKey: genesisTs.Key(), state: string(state), } - addresses[addr] = address.Undef + addressToID[addr] = address.Undef alk.Unlock() }) @@ -206,11 +209,13 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS log.Error(err) return } + ast, err := api.StateReadState(ctx, &act, pts.Key()) if err != nil { log.Error(err) return } + state, err := json.Marshal(ast.State) if err != nil { log.Error(err) @@ -225,8 +230,9 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS actors[addr][act] = actorInfo{ stateroot: bh.ParentStateRoot, state: string(state), + tsKey: pts.Key(), } - addresses[addr] = address.Undef + addressToID[addr] = address.Undef alk.Unlock() } }) @@ -238,18 +244,20 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS log.Infof("Resolving addresses") for _, message := range msgs { - addresses[message.To] = address.Undef - addresses[message.From] = address.Undef + addressToID[message.To] = address.Undef + addressToID[message.From] = address.Undef } - parmap.Par(50, parmap.KMapArr(addresses), func(addr address.Address) { + parmap.Par(50, parmap.KMapArr(addressToID), func(addr address.Address) { + // FIXME: cannot use EmptyTSK here since actorID's can change during reorgs, need to use the corresponding tipset. + // TODO: figure out a way to get the corresponding tipset... raddr, err := api.StateLookupID(ctx, addr, types.EmptyTSK) if err != nil { log.Warn(err) return } alk.Lock() - addresses[addr] = raddr + addressToID[addr] = raddr alk.Unlock() }) @@ -267,6 +275,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS addr: addr, act: actor, stateroot: c.stateroot, + tsKey: c.tsKey, }] = &minerInfo{} } } @@ -274,14 +283,17 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS parmap.Par(50, parmap.KVMapArr(miners), func(it func() (minerKey, *minerInfo)) { k, info := it() - pow, err := api.StateMinerPower(ctx, k.addr, types.EmptyTSK) + // TODO: get the storage power actors state and and pull the miner power from there, currently this hits the + // storage power actor once for each miner for each tipset, we can do better by just getting it for each tipset + // and reading each miner power from the result. + pow, err := api.StateMinerPower(ctx, k.addr, k.tsKey) if err != nil { log.Error(err) // Not sure why this would fail, but its probably worth continuing } info.power = pow.MinerPower.QualityAdjPower - sszs, err := api.StateMinerSectorCount(ctx, k.addr, types.EmptyTSK) + sszs, err := api.StateMinerSectorCount(ctx, k.addr, k.tsKey) if err != nil { log.Error(err) return @@ -316,7 +328,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS log.Info("Storing address mapping") - if err := st.storeAddressMap(addresses); err != nil { + if err := st.storeAddressMap(addressToID); err != nil { log.Error(err) return } @@ -361,7 +373,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS log.Infof("Get deals") // TODO: incremental, gather expired - deals, err := api.StateMarketDeals(ctx, ts.Key()) + deals, err := api.StateMarketDeals(ctx, headTs.Key()) if err != nil { log.Error(err) return From 10c4fae8c08ae2931ea1fd88c5cce7c2fafde9b6 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 25 Jun 2020 16:46:50 +0200 Subject: [PATCH 259/379] Make gas traces smaller, strip callers in import-bench Signed-off-by: Jakub Sztandera --- chain/types/execresult.go | 18 +++++++++--------- chain/vm/runtime.go | 2 +- cmd/lotus-bench/import.go | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/chain/types/execresult.go b/chain/types/execresult.go index 443147f9e..6fc93fac6 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -21,16 +21,16 @@ type ExecutionTrace struct { type GasTrace struct { Name string - Location []Loc - TotalGas int64 - ComputeGas int64 - StorageGas int64 - TotalVirtualGas int64 - VirtualComputeGas int64 - VirtualStorageGas int64 + Location []Loc `json:"loc"` + TotalGas int64 `json:"tg"` + ComputeGas int64 `json:"cg"` + StorageGas int64 `json:"sg"` + TotalVirtualGas int64 `json:"vtg"` + VirtualComputeGas int64 `json:"vcg"` + VirtualStorageGas int64 `json:"vsg"` - TimeTaken time.Duration - Extra interface{} `json:",omitempty"` + TimeTaken time.Duration `json:"tt"` + Extra interface{} `json:"ex,omitempty"` Callers []uintptr `json:"-"` } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index d6d49c214..595664de1 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -408,7 +408,7 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, if subrt != nil { rt.numActorsCreated = subrt.numActorsCreated } - rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace) //&er) + rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace) return ret, errSend } diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f7538daec..647bb58ed 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -149,6 +149,7 @@ var importBenchCmd = &cli.Command{ if err != nil { return err } + stripCallers(trace) lastTse = &TipSetExec{ TipSet: cur.Key(), @@ -168,6 +169,21 @@ var importBenchCmd = &cli.Command{ }, } +func walkExecutionTrace(et *types.ExecutionTrace) { + for _, gc := range et.GasCharges { + gc.Callers = nil + } + for _, sub := range et.Subcalls { + walkExecutionTrace(&sub) + } +} + +func stripCallers(trace []*api.InvocResult) { + for _, t := range trace { + walkExecutionTrace(&t.ExecutionTrace) + } +} + type Invocation struct { TipSet types.TipSetKey Invoc *api.InvocResult From f98063d60476c4ef6cd0e0876d72dede647a1d13 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 25 Jun 2020 16:58:55 +0200 Subject: [PATCH 260/379] In this case I want it to be not really safe Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 647bb58ed..ebc62aa5d 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -174,7 +174,7 @@ func walkExecutionTrace(et *types.ExecutionTrace) { gc.Callers = nil } for _, sub := range et.Subcalls { - walkExecutionTrace(&sub) + walkExecutionTrace(&sub) //nolint:scopelint,gosec } } From 7e342e60d177703803b3982860c6e26ad73bb418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 25 Jun 2020 00:00:11 +0200 Subject: [PATCH 261/379] sealing: Give priority to sectors with deals --- go.mod | 4 ++-- go.sum | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 3b8ecf76f..404c2d46c 100644 --- a/go.mod +++ b/go.mod @@ -29,10 +29,10 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200623224636-de544b531601 + github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea - github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 + github.com/filecoin-project/storage-fsm v0.0.0-20200625160832-379a4655b044 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index 7fb39f472..2b8a31ba6 100644 --- a/go.sum +++ b/go.sum @@ -252,10 +252,8 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= -github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d h1:yJJqXCMEhvXJoOS6T1O46FXl+A3mlttXhgjcTCp+Tgo= -github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= -github.com/filecoin-project/sector-storage v0.0.0-20200623224636-de544b531601 h1:EgMmHLoJ4caLU8RzgKQux4TyX/ZploXGtIu5Q1SaxKw= -github.com/filecoin-project/sector-storage v0.0.0-20200623224636-de544b531601/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= +github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246 h1:NfYQRmVRe0LzlNbK5Ket3vbBOwFD5TvtcNtfo/Sd8mg= +github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= @@ -265,8 +263,8 @@ github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sg github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY= github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= -github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 h1:nH3L7YVqrHINOmvZ+5jFjFNSi9/swXcm+uufXpkFJfo= -github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3/go.mod h1:Nl0JX9I3fIVtPEJ9HzGzO4D8LXehT9PqvUQUbNvcstc= +github.com/filecoin-project/storage-fsm v0.0.0-20200625160832-379a4655b044 h1:i4oMhv1kx/MAUxRN4EM5tag5fI1uagrwQwINgKrzUt4= +github.com/filecoin-project/storage-fsm v0.0.0-20200625160832-379a4655b044/go.mod h1:JD7fmV1BYADDcy4EYQnqFH/rUzXsh0Je0jXarCjZqSk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= From 7f932b96ae7a23178d3a7b540a816295d7946f5f Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Mon, 22 Jun 2020 14:38:40 -0700 Subject: [PATCH 262/379] WIP --- chain/events/state/predicates.go | 101 +++++++++++++++++++++++++++++++ chain/events/state/state.go | 57 +++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 chain/events/state/predicates.go create mode 100644 chain/events/state/state.go diff --git a/chain/events/state/predicates.go b/chain/events/state/predicates.go new file mode 100644 index 000000000..e9d9a7393 --- /dev/null +++ b/chain/events/state/predicates.go @@ -0,0 +1,101 @@ +package state + +import ( + "context" + + "github.com/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" +) + +type StatePredicates struct { + sm *stmgr.StateManager +} + +func NewStatePredicates(sm *stmgr.StateManager) *StatePredicates { + return &StatePredicates{ + sm: sm, + } +} + +type DiffStateFunc func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) + +func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFunc DiffStateFunc) DiffFunc { + return func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) { + oldActor, err := sp.sm.GetActor(addr, oldState) + if err != nil { + return false, nil, err + } + newActor, err := sp.sm.GetActor(addr, newState) + if oldActor.Head.Equals(newActor.Head) { + return false, nil, nil + } + return diffStateFunc(ctx, oldActor.Head, newActor.Head) + } +} + +type DiffStorageMarketStateFunc func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) + +func (sp *StatePredicates) OnStorageMarketActorChanged(addr address.Address, diffStorageMarketState DiffStorageMarketStateFunc) DiffFunc { + return sp.OnActorStateChanged(builtin.StorageMarketActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) { + var oldState market.State + cst := cbor.NewCborStore(sp.sm.ChainStore().Blockstore()) + if err := cst.Get(ctx, oldActorStateHead, &oldState); err != nil { + return false, nil, err + } + var newState market.State + if err := cst.Get(ctx, newActorStateHead, &newActorStateHead); err != nil { + return false, nil, err + } + return diffStorageMarketState(ctx, &oldState, &newState) + }) +} + +type DiffDealStatesFunc func(ctx context.Context, oldDealStateRoot *amt.Root, newDealStateRoot *amt.Root) (changed bool, user UserData, err error) + +func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) DiffStorageMarketStateFunc { + return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) { + if oldState.States.Equals(newState.States) { + return false, nil, nil + } + blks := cbor.NewCborStore(sp.sm.ChainStore().Blockstore()) + oldRoot, err := amt.LoadAMT(ctx, blks, oldState.States) + if err != nil { + return false, nil, err + } + newRoot, err := amt.LoadAMT(ctx, blks, newState.States) + if err != nil { + return false, nil, err + } + return diffDealStates(ctx, oldRoot, newRoot) + } +} + +func (sp *StatePredicates) DealStateChangedForIDs(ctx context.Context, dealIds []abi.DealID, oldRoot, newRoot *amt.Root) (changed bool, user UserData, err error) { + var changedDeals []abi.DealID + for _, dealId := range dealIds { + var oldDeal, newDeal market.DealState + err := oldRoot.Get(ctx, uint64(dealId), &oldDeal) + if err != nil { + return false, nil, err + } + err = newRoot.Get(ctx, uint64(dealId), &newDeal) + if err != nil { + return false, nil, err + } + if oldDeal != newDeal { + changedDeals = append(changedDeals, dealId) + } + } + if len(changedDeals) > 0 { + return true, changed, nil + } + return false, nil, nil +} diff --git a/chain/events/state/state.go b/chain/events/state/state.go new file mode 100644 index 000000000..75041ad79 --- /dev/null +++ b/chain/events/state/state.go @@ -0,0 +1,57 @@ +package state + +import ( + "context" + + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/specs-actors/actors/abi" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" +) + +type StateWatcher struct { +} + +type WatcherAPI interface { + ChainNotify(context.Context) (<-chan []*api.HeadChange, error) +} + +type UserData interface{} + +type DiffFunc func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) + +type Callback func(ctx context.Context, oldState, newState *types.TipSet, events interface{}) + +type RevertHandler func(ctx context.Context, ts *types.TipSet) error + +/* +w := NewWatcher(api, OnActorChange(t04, OnDealStateChange(123)), cb) +*/ +func NewWatcher(ctx context.Context, api WatcherAPI, d DiffFunc, apply Callback, revert RevertHandler, confidence, timeout abi.ChainEpoch) { + go func() { + notifs, err := api.ChainNotify(ctx) + if err != nil { + // bad + return + } + + curTs := (<-notifs)[0].Val + d(ctx, curTs, curTs) + + for { + select { + case update := <-notifs: + for i, change := range update { + switch change.Type { + case store.HCApply: + d(ctx, curTs, change.Val) + case store.HCRevert: + + } + } + } + } + + }() +} From dd490220d7e91e450a49af702424c13e6edafb68 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Wed, 24 Jun 2020 14:10:52 -0400 Subject: [PATCH 263/379] refactor: Extract message-specific code from calledEvents This allows us to create a general purpose head change events manager that can be used for call events and also for state change events. --- chain/events/events.go | 19 +- chain/events/events_hc.go | 589 ++++++++++++++++++++++++++++++++++++++ chain/events/utils.go | 8 +- 3 files changed, 597 insertions(+), 19 deletions(-) create mode 100644 chain/events/events_hc.go diff --git a/chain/events/events.go b/chain/events/events.go index a325b5410..408c8845e 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -51,7 +51,7 @@ type Events struct { readyOnce sync.Once heightEvents - calledEvents + hcEvents } func NewEvents(ctx context.Context, api eventAPI) *Events { @@ -74,18 +74,7 @@ func NewEvents(ctx context.Context, api eventAPI) *Events { htHeights: map[abi.ChainEpoch][]uint64{}, }, - calledEvents: calledEvents{ - cs: api, - tsc: tsc, - ctx: ctx, - gcConfidence: uint64(gcConfidence), - - confQueue: map[triggerH]map[msgH][]*queuedEvent{}, - revertQueue: map[msgH][]triggerH{}, - triggers: map[triggerID]*callHandler{}, - matchers: map[triggerID][]MatchFunc{}, - timeouts: map[abi.ChainEpoch]map[triggerID]int{}, - }, + hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)), } e.ready.Add(1) @@ -143,7 +132,7 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error { } e.readyOnce.Do(func() { - e.at = cur[0].Val.Height() + e.lastTs = cur[0].Val e.ready.Done() }) @@ -186,5 +175,5 @@ func (e *Events) headChange(rev, app []*types.TipSet) error { return err } - return e.headChangeCalled(rev, app) + return e.processHeadChangeEvent(rev, app) } diff --git a/chain/events/events_hc.go b/chain/events/events_hc.go new file mode 100644 index 000000000..ae42fd85f --- /dev/null +++ b/chain/events/events_hc.go @@ -0,0 +1,589 @@ +package events + +import ( + "context" + "math" + "sync" + + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/types" +) + +const NoTimeout = math.MaxInt64 + +type triggerID = uint64 + +// msgH is the block height at which a message was present / event has happened +type msgH = abi.ChainEpoch + +// triggerH is the block height at which the listener will be notified about the +// message (msgH+confidence) +type triggerH = abi.ChainEpoch + +type eventData interface{} + +// EventHandler arguments: +// `ts` is the tipset, in which the `msg` is included. +// `curH`-`ts.Height` = `confidence` +type EventHandler func(data eventData, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) + +// CheckFunc is used for atomicity guarantees. If the condition the callbacks +// wait for has already happened in tipset `ts` +// +// If `done` is true, timeout won't be triggered +// If `more` is false, no messages will be sent to EventHandler (RevertHandler +// may still be called) +type CheckFunc func(ts *types.TipSet) (done bool, more bool, err error) + +// Keep track of information for an event handler +type handlerInfo struct { + confidence int + timeout abi.ChainEpoch + + disabled bool // TODO: GC after gcConfidence reached + + handle EventHandler + revert RevertHandler +} + +// When a change occurs, a queuedEvent is created and put into a queue +// until the required confidence is reached +type queuedEvent struct { + trigger triggerID + + h abi.ChainEpoch + data eventData + + called bool +} + +// Manages chain head change events, which may be forward (new tipset added to +// chain) or backward (chain branch discarded in favour of heavier branch) +type hcEvents struct { + cs eventAPI + tsc *tipSetCache + ctx context.Context + gcConfidence uint64 + + lastTs *types.TipSet + + lk sync.Mutex + + ctr triggerID + + triggers map[triggerID]*handlerInfo + + // maps block heights to events + // [triggerH][msgH][event] + confQueue map[triggerH]map[msgH][]*queuedEvent + + // [msgH][triggerH] + revertQueue map[msgH][]triggerH + + // [timeoutH+confidence][triggerID]{calls} + timeouts map[abi.ChainEpoch]map[triggerID]int + + messageEvents + watcherEvents +} + +func newHCEvents(ctx context.Context, cs eventAPI, tsc *tipSetCache, gcConfidence uint64) hcEvents { + e := hcEvents{ + ctx: ctx, + cs: cs, + tsc: tsc, + gcConfidence: gcConfidence, + + confQueue: map[triggerH]map[msgH][]*queuedEvent{}, + revertQueue: map[msgH][]triggerH{}, + triggers: map[triggerID]*handlerInfo{}, + timeouts: map[abi.ChainEpoch]map[triggerID]int{}, + } + + e.messageEvents = newMessageEvents(ctx, &e, cs) + e.watcherEvents = newWatcherEvents(ctx, &e, cs) + + return e +} + +// Called when there is a change to the head with tipsets to be +// reverted / applied +func (e *hcEvents) processHeadChangeEvent(rev, app []*types.TipSet) error { + for _, ts := range rev { + e.handleReverts(ts) + e.lastTs = ts + } + + for _, ts := range app { + // Check if the head change caused any state changes that we were + // waiting for + stateChanges := e.watcherEvents.checkStateChanges(e.lastTs, ts) + + // Queue up calls until there have been enough blocks to reach + // confidence on the state changes + for tid, data := range stateChanges { + e.queueForConfidence(tid, data, ts) + } + + // Check if the head change included any new message calls + newCalls, err := e.messageEvents.checkNewCalls(ts) + if err != nil { + return err + } + + // Queue up calls until there have been enough blocks to reach + // confidence on the message calls + for tid, data := range newCalls { + e.queueForConfidence(tid, data, ts) + } + + for at := e.lastTs.Height(); at <= ts.Height(); at++ { + // Apply any events and timeouts that were queued up until the + // current chain height + e.applyWithConfidence(ts, at) + e.applyTimeouts(ts) + } + + // Update the latest known tipset + e.lastTs = ts + } + + return nil +} + +func (e *hcEvents) handleReverts(ts *types.TipSet) { + reverts, ok := e.revertQueue[ts.Height()] + if !ok { + return // nothing to do + } + + for _, triggerH := range reverts { + toRevert := e.confQueue[triggerH][ts.Height()] + for _, event := range toRevert { + if !event.called { + continue // event wasn't apply()-ied yet + } + + trigger := e.triggers[event.trigger] + + if err := trigger.revert(e.ctx, ts); err != nil { + log.Errorf("reverting chain trigger failed: %s", err) + // log.Errorf("reverting chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, ts.Height(), triggerH, err) + } + } + delete(e.confQueue[triggerH], ts.Height()) + } + delete(e.revertQueue, ts.Height()) +} + +// Queue up events until the chain has reached a height that reflects the +// desired confidence +func (e *hcEvents) queueForConfidence(trigID uint64, data eventData, ts *types.TipSet) { + trigger := e.triggers[trigID] + + appliedH := ts.Height() + + triggerH := appliedH + abi.ChainEpoch(trigger.confidence) + + byOrigH, ok := e.confQueue[triggerH] + if !ok { + byOrigH = map[abi.ChainEpoch][]*queuedEvent{} + e.confQueue[triggerH] = byOrigH + } + + byOrigH[appliedH] = append(byOrigH[appliedH], &queuedEvent{ + trigger: trigID, + h: appliedH, + data: data, + }) + + e.revertQueue[appliedH] = append(e.revertQueue[appliedH], triggerH) +} + +// Apply any events that were waiting for this chain height for confidence +func (e *hcEvents) applyWithConfidence(ts *types.TipSet, height abi.ChainEpoch) { + byOrigH, ok := e.confQueue[height] + if !ok { + return // no triggers at thin height + } + + for origH, events := range byOrigH { + triggerTs, err := e.tsc.get(origH) + if err != nil { + log.Errorf("events: applyWithConfidence didn't find tipset for event; wanted %d; current %d", origH, height) + } + + for _, event := range events { + if event.called { + continue + } + + trigger := e.triggers[event.trigger] + if trigger.disabled { + continue + } + + more, err := trigger.handle(event.data, triggerTs, height) + if err != nil { + log.Errorf("chain trigger (@H %d, called @ %d) failed: %s", origH, height, err) + // log.Errorf("chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, origH, height, err) + continue // don't revert failed calls + } + + event.called = true + + touts, ok := e.timeouts[trigger.timeout] + if ok { + touts[event.trigger]++ + } + + trigger.disabled = !more + } + } +} + +// Apply any timeouts that expire at this height +func (e *hcEvents) applyTimeouts(ts *types.TipSet) { + triggers, ok := e.timeouts[ts.Height()] + if !ok { + return // nothing to do + } + + for triggerID, calls := range triggers { + if calls > 0 { + continue // don't timeout if the method was called + } + trigger := e.triggers[triggerID] + if trigger.disabled { + continue + } + + timeoutTs, err := e.tsc.get(ts.Height() - abi.ChainEpoch(trigger.confidence)) + if err != nil { + log.Errorf("events: applyTimeouts didn't find tipset for event; wanted %d; current %d", ts.Height()-abi.ChainEpoch(trigger.confidence), ts.Height()) + } + + // more, err := trigger.handle(nil, nil, timeoutTs, ts.Height()) + more, err := trigger.handle(nil, timeoutTs, ts.Height()) + if err != nil { + log.Errorf("chain trigger (call @H %d, called @ %d) failed: %s", timeoutTs.Height(), ts.Height(), err) + continue // don't revert failed calls + } + + trigger.disabled = !more // allows messages after timeout + } +} + +// Listen for an event +// - CheckFunc: immediately checks if the event already occured +// - EventHandler: called when the event has occurred, after confidence tipsets +// - RevertHandler: called if the chain head changes causing the event to revert +// - confidence: wait this many tipsets before calling EventHandler +// - timeout: at this chain height, timeout on waiting for this event +func (e *hcEvents) onHeadChanged(check CheckFunc, hnd EventHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch) (triggerID, error) { + e.lk.Lock() + defer e.lk.Unlock() + + // Check if the even has already occurred + ts := e.tsc.best() + done, more, err := check(ts) + if err != nil { + return 0, xerrors.Errorf("called check error (h: %d): %w", ts.Height(), err) + } + if done { + timeout = NoTimeout + } + + // Create a trigger for the event + id := e.ctr + e.ctr++ + + e.triggers[id] = &handlerInfo{ + confidence: confidence, + timeout: timeout + abi.ChainEpoch(confidence), + + disabled: !more, + + handle: hnd, + revert: rev, + } + + // If there's a timeout, set up a timeout check at that height + if timeout != NoTimeout { + if e.timeouts[timeout+abi.ChainEpoch(confidence)] == nil { + e.timeouts[timeout+abi.ChainEpoch(confidence)] = map[uint64]int{} + } + e.timeouts[timeout+abi.ChainEpoch(confidence)][id] = 0 + } + + return id, nil +} + +// headChangeAPI is used to allow the composed event APIs to call back to hcEvents +// to listen for changes +type headChangeAPI interface { + onHeadChanged(check CheckFunc, hnd EventHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch) (triggerID, error) +} + +// watcherEvents watches for a state change +type watcherEvents struct { + ctx context.Context + cs eventAPI + hcApi headChangeAPI + + lk sync.RWMutex + matchers map[triggerID]StateMatchFunc +} + +func newWatcherEvents(ctx context.Context, hcApi headChangeAPI, cs eventAPI) watcherEvents { + return watcherEvents{ + ctx: ctx, + cs: cs, + hcApi: hcApi, + matchers: make(map[triggerID]StateMatchFunc), + } +} + +// Run each of the matchers against the previous and current state to see if +// there's a change +func (we *watcherEvents) checkStateChanges(oldState, newState *types.TipSet) map[triggerID]eventData { + we.lk.RLock() + defer we.lk.RUnlock() + + res := make(map[triggerID]eventData) + for tid, matchFn := range we.matchers { + ok, data, err := matchFn(we.ctx, oldState, newState) + if err != nil { + log.Errorf("event diff fn failed: %s", err) + continue + } + + if ok { + res[tid] = data + } + } + return res +} + +// Used to store the state change +type stateData interface{} + +// StateChangeHandler arguments: +// `ts` is the tipset, in which the change occured +// `curH`-`ts.Height` = `confidence` +type StateChangeHandler func(ctx context.Context, oldState, newState stateData, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) + +type StateMatchFunc func(ctx context.Context, oldState, newState *types.TipSet) (bool, eventData, error) + +// StateChanged registers a callback which is triggered when a specified state +// change occurs or a timeout is reached. +// +// * `CheckFunc` callback is invoked immediately with a recent tipset, it +// returns two booleans - `done`, and `more`. +// +// * `done` should be true when some on-chain state change we are waiting +// for has happened. When `done` is set to true, timeout trigger is disabled. +// +// * `more` should be false when we don't want to receive new notifications +// through StateChangeHandler. Note that notifications may still be delivered to +// RevertHandler +// +// * `StateChangeHandler` is called when the specified state change was observed +// on-chain, and a confidence threshold was reached, or the specified `timeout` +// height was reached with no state change observed. When this callback is +// invoked on a timeout, `oldState` and `newState` are set to nil. +// This callback returns a boolean specifying whether further notifications +// should be sent, like `more` return param from `CheckFunc` above. +// +// * `RevertHandler` is called after apply handler, when we drop the tipset +// containing the message. The tipset passed as the argument is the tipset +// that is being dropped. Note that the message dropped may be re-applied +// in a different tipset in small amount of time. +// +// * `StateMatchFunc` is called against each tipset state. If there is a match, +// the state change is queued up until the confidence interval has elapsed (and +// `StateChangeHandler` is called) +func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf StateMatchFunc) error { + hnd := func(data eventData, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { + states, ok := data.([]interface{}) + if !ok || len(states) != 2 { + panic("expected 2 element array") + } + + return scHnd(we.ctx, states[0], states[1], ts, height) + } + + id, err := we.hcApi.onHeadChanged(check, hnd, rev, confidence, timeout) + if err != nil { + return err + } + + we.lk.Lock() + we.matchers[id] = mf + defer we.lk.Unlock() + + return nil +} + +// messageEvents watches for message calls to actors +type messageEvents struct { + ctx context.Context + cs eventAPI + hcApi headChangeAPI + + lk sync.RWMutex + matchers map[triggerID][]MsgMatchFunc +} + +func newMessageEvents(ctx context.Context, hcApi headChangeAPI, cs eventAPI) messageEvents { + return messageEvents{ + ctx: ctx, + cs: cs, + hcApi: hcApi, + matchers: map[triggerID][]MsgMatchFunc{}, + } +} + +// Check if there are any new actor calls +func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID]eventData, error) { + pts, err := me.cs.ChainGetTipSet(me.ctx, ts.Parents()) // we actually care about messages in the parent tipset here + if err != nil { + log.Errorf("getting parent tipset in checkNewCalls: %s", err) + return nil, err + } + + res := make(map[triggerID]eventData) + me.messagesForTs(pts, func(msg *types.Message) { + me.lk.RLock() + defer me.lk.RUnlock() + // TODO: provide receipts + + for tid, matchFns := range me.matchers { + var matched bool + for _, matchFn := range matchFns { + ok, err := matchFn(msg) + if err != nil { + log.Errorf("event matcher failed: %s", err) + continue + } + matched = ok + + if matched { + break + } + } + + if matched { + res[tid] = msg + break + } + } + }) + + return res, nil +} + +// Get the messages in a tipset +func (me *messageEvents) messagesForTs(ts *types.TipSet, consume func(*types.Message)) { + seen := map[cid.Cid]struct{}{} + + for _, tsb := range ts.Blocks() { + + msgs, err := me.cs.ChainGetBlockMessages(context.TODO(), tsb.Cid()) + if err != nil { + log.Errorf("messagesForTs MessagesForBlock failed (ts.H=%d, Bcid:%s, B.Mcid:%s): %s", ts.Height(), tsb.Cid(), tsb.Messages, err) + // this is quite bad, but probably better than missing all the other updates + continue + } + + for _, m := range msgs.BlsMessages { + _, ok := seen[m.Cid()] + if ok { + continue + } + seen[m.Cid()] = struct{}{} + + consume(m) + } + + for _, m := range msgs.SecpkMessages { + _, ok := seen[m.Message.Cid()] + if ok { + continue + } + seen[m.Message.Cid()] = struct{}{} + + consume(&m.Message) + } + } +} + +// MsgHandler arguments: +// `ts` is the tipset, in which the `msg` is included. +// `curH`-`ts.Height` = `confidence` +type MsgHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) + +type MsgMatchFunc func(msg *types.Message) (bool, error) + +// Called registers a callback which is triggered when a specified method is +// called on an actor, or a timeout is reached. +// +// * `CheckFunc` callback is invoked immediately with a recent tipset, it +// returns two booleans - `done`, and `more`. +// +// * `done` should be true when some on-chain action we are waiting for has +// happened. When `done` is set to true, timeout trigger is disabled. +// +// * `more` should be false when we don't want to receive new notifications +// through MsgHandler. Note that notifications may still be delivered to +// RevertHandler +// +// * `MsgHandler` is called when the specified event was observed on-chain, +// and a confidence threshold was reached, or the specified `timeout` height +// was reached with no events observed. When this callback is invoked on a +// timeout, `msg` is set to nil. This callback returns a boolean specifying +// whether further notifications should be sent, like `more` return param +// from `CheckFunc` above. +// +// * `RevertHandler` is called after apply handler, when we drop the tipset +// containing the message. The tipset passed as the argument is the tipset +// that is being dropped. Note that the message dropped may be re-applied +// in a different tipset in small amount of time. +// +// * `MsgMatchFunc` is called against each message. If there is a match, the +// message is queued up until the confidence interval has elapsed (and +// `MsgHandler` is called) +func (me *messageEvents) Called(check CheckFunc, msgHnd MsgHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf MsgMatchFunc) error { + hnd := func(data eventData, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { + msg, ok := data.(*types.Message) + if data != nil && !ok { + panic("expected msg") + } + + rec, err := me.cs.StateGetReceipt(me.ctx, msg.Cid(), ts.Key()) + if err != nil { + return false, err + } + + return msgHnd(msg, rec, ts, height) + } + + id, err := me.hcApi.onHeadChanged(check, hnd, rev, confidence, timeout) + if err != nil { + return err + } + + me.lk.Lock() + defer me.lk.Unlock() + me.matchers[id] = append(me.matchers[id], mf) + + return nil +} + +// Convenience function for checking and matching messages +func (me *messageEvents) CalledMsg(ctx context.Context, hnd MsgHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, msg types.ChainMsg) error { + return me.Called(me.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, me.MatchMsg(msg.VMMessage())) +} diff --git a/chain/events/utils.go b/chain/events/utils.go index d525e5368..40556c9ff 100644 --- a/chain/events/utils.go +++ b/chain/events/utils.go @@ -8,11 +8,11 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func (e *calledEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd CalledHandler) CheckFunc { +func (me *messageEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd MsgHandler) CheckFunc { msg := smsg.VMMessage() return func(ts *types.TipSet) (done bool, more bool, err error) { - fa, err := e.cs.StateGetActor(ctx, msg.From, ts.Key()) + fa, err := me.cs.StateGetActor(ctx, msg.From, ts.Key()) if err != nil { return false, true, err } @@ -22,7 +22,7 @@ func (e *calledEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd Ca return false, true, nil } - rec, err := e.cs.StateGetReceipt(ctx, smsg.VMMessage().Cid(), ts.Key()) + rec, err := me.cs.StateGetReceipt(ctx, smsg.VMMessage().Cid(), ts.Key()) if err != nil { return false, true, xerrors.Errorf("getting receipt in CheckMsg: %w", err) } @@ -33,7 +33,7 @@ func (e *calledEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd Ca } } -func (e *calledEvents) MatchMsg(inmsg *types.Message) MatchFunc { +func (me *messageEvents) MatchMsg(inmsg *types.Message) MsgMatchFunc { return func(msg *types.Message) (bool, error) { if msg.From == inmsg.From && msg.Nonce == inmsg.Nonce && !inmsg.Equals(msg) { return false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce) From b62fef7541e5c022532fa2671a9ef3e37b7afe6d Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Thu, 25 Jun 2020 12:12:03 -0400 Subject: [PATCH 264/379] feat: include previous TS in StateChangedHandler --- chain/events/events_hc.go | 80 +++++++----- chain/events/events_test.go | 243 +++++++++++++++++++++++++++++++++++- 2 files changed, 293 insertions(+), 30 deletions(-) diff --git a/chain/events/events_hc.go b/chain/events/events_hc.go index ae42fd85f..1f508b57f 100644 --- a/chain/events/events_hc.go +++ b/chain/events/events_hc.go @@ -13,6 +13,7 @@ import ( ) const NoTimeout = math.MaxInt64 +const NoHeight = abi.ChainEpoch(-1) type triggerID = uint64 @@ -26,9 +27,10 @@ type triggerH = abi.ChainEpoch type eventData interface{} // EventHandler arguments: -// `ts` is the tipset, in which the `msg` is included. +// `prevTs` is the previous tipset, eg the "from" tipset for a state change. +// `ts` is the event tipset, eg the tipset in which the `msg` is included. // `curH`-`ts.Height` = `confidence` -type EventHandler func(data eventData, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) +type EventHandler func(data eventData, prevTs, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) // CheckFunc is used for atomicity guarantees. If the condition the callbacks // wait for has already happened in tipset `ts` @@ -54,8 +56,9 @@ type handlerInfo struct { type queuedEvent struct { trigger triggerID - h abi.ChainEpoch - data eventData + prevH abi.ChainEpoch + h abi.ChainEpoch + data eventData called bool } @@ -112,6 +115,9 @@ func newHCEvents(ctx context.Context, cs eventAPI, tsc *tipSetCache, gcConfidenc // Called when there is a change to the head with tipsets to be // reverted / applied func (e *hcEvents) processHeadChangeEvent(rev, app []*types.TipSet) error { + e.lk.Lock() + defer e.lk.Unlock() + for _, ts := range rev { e.handleReverts(ts) e.lastTs = ts @@ -125,7 +131,7 @@ func (e *hcEvents) processHeadChangeEvent(rev, app []*types.TipSet) error { // Queue up calls until there have been enough blocks to reach // confidence on the state changes for tid, data := range stateChanges { - e.queueForConfidence(tid, data, ts) + e.queueForConfidence(tid, data, e.lastTs, ts) } // Check if the head change included any new message calls @@ -137,11 +143,11 @@ func (e *hcEvents) processHeadChangeEvent(rev, app []*types.TipSet) error { // Queue up calls until there have been enough blocks to reach // confidence on the message calls for tid, data := range newCalls { - e.queueForConfidence(tid, data, ts) + e.queueForConfidence(tid, data, nil, ts) } for at := e.lastTs.Height(); at <= ts.Height(); at++ { - // Apply any events and timeouts that were queued up until the + // Apply any queued events and timeouts that were targeted at the // current chain height e.applyWithConfidence(ts, at) e.applyTimeouts(ts) @@ -170,8 +176,7 @@ func (e *hcEvents) handleReverts(ts *types.TipSet) { trigger := e.triggers[event.trigger] if err := trigger.revert(e.ctx, ts); err != nil { - log.Errorf("reverting chain trigger failed: %s", err) - // log.Errorf("reverting chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, ts.Height(), triggerH, err) + log.Errorf("reverting chain trigger (@H %d, triggered @ %d) failed: %s", ts.Height(), triggerH, err) } } delete(e.confQueue[triggerH], ts.Height()) @@ -181,9 +186,13 @@ func (e *hcEvents) handleReverts(ts *types.TipSet) { // Queue up events until the chain has reached a height that reflects the // desired confidence -func (e *hcEvents) queueForConfidence(trigID uint64, data eventData, ts *types.TipSet) { +func (e *hcEvents) queueForConfidence(trigID uint64, data eventData, prevTs, ts *types.TipSet) { trigger := e.triggers[trigID] + prevH := NoHeight + if prevTs != nil { + prevH = prevTs.Height() + } appliedH := ts.Height() triggerH := appliedH + abi.ChainEpoch(trigger.confidence) @@ -196,6 +205,7 @@ func (e *hcEvents) queueForConfidence(trigID uint64, data eventData, ts *types.T byOrigH[appliedH] = append(byOrigH[appliedH], &queuedEvent{ trigger: trigID, + prevH: prevH, h: appliedH, data: data, }) @@ -207,7 +217,7 @@ func (e *hcEvents) queueForConfidence(trigID uint64, data eventData, ts *types.T func (e *hcEvents) applyWithConfidence(ts *types.TipSet, height abi.ChainEpoch) { byOrigH, ok := e.confQueue[height] if !ok { - return // no triggers at thin height + return // no triggers at this height } for origH, events := range byOrigH { @@ -226,10 +236,20 @@ func (e *hcEvents) applyWithConfidence(ts *types.TipSet, height abi.ChainEpoch) continue } - more, err := trigger.handle(event.data, triggerTs, height) + // Previous tipset - this is relevant for example in a state change + // from one tipset to another + var prevTs *types.TipSet + if event.prevH != NoHeight { + prevTs, err = e.tsc.get(event.prevH) + if err != nil { + log.Errorf("events: applyWithConfidence didn't find tipset for previous event; wanted %d; current %d", event.prevH, height) + continue + } + } + + more, err := trigger.handle(event.data, prevTs, triggerTs, height) if err != nil { - log.Errorf("chain trigger (@H %d, called @ %d) failed: %s", origH, height, err) - // log.Errorf("chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, origH, height, err) + log.Errorf("chain trigger (@H %d, triggered @ %d) failed: %s", origH, height, err) continue // don't revert failed calls } @@ -266,8 +286,7 @@ func (e *hcEvents) applyTimeouts(ts *types.TipSet) { log.Errorf("events: applyTimeouts didn't find tipset for event; wanted %d; current %d", ts.Height()-abi.ChainEpoch(trigger.confidence), ts.Height()) } - // more, err := trigger.handle(nil, nil, timeoutTs, ts.Height()) - more, err := trigger.handle(nil, timeoutTs, ts.Height()) + more, err := trigger.handle(nil, nil, timeoutTs, ts.Height()) if err != nil { log.Errorf("chain trigger (call @H %d, called @ %d) failed: %s", timeoutTs.Height(), ts.Height(), err) continue // don't revert failed calls @@ -355,7 +374,7 @@ func (we *watcherEvents) checkStateChanges(oldState, newState *types.TipSet) map res := make(map[triggerID]eventData) for tid, matchFn := range we.matchers { - ok, data, err := matchFn(we.ctx, oldState, newState) + ok, data, err := matchFn(oldState, newState) if err != nil { log.Errorf("event diff fn failed: %s", err) continue @@ -369,14 +388,19 @@ func (we *watcherEvents) checkStateChanges(oldState, newState *types.TipSet) map } // Used to store the state change -type stateData interface{} +type stateChange interface{} + +// Will be checked to ensure it has length 2 +type stateData []stateChange // StateChangeHandler arguments: -// `ts` is the tipset, in which the change occured +// `oldTs` is the state "from" tipset +// `newTs` is the state "to" tipset +// `data` is the old / new state // `curH`-`ts.Height` = `confidence` -type StateChangeHandler func(ctx context.Context, oldState, newState stateData, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) +type StateChangeHandler func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (more bool, err error) -type StateMatchFunc func(ctx context.Context, oldState, newState *types.TipSet) (bool, eventData, error) +type StateMatchFunc func(oldTs, newTs *types.TipSet) (bool, stateData, error) // StateChanged registers a callback which is triggered when a specified state // change occurs or a timeout is reached. @@ -400,20 +424,20 @@ type StateMatchFunc func(ctx context.Context, oldState, newState *types.TipSet) // // * `RevertHandler` is called after apply handler, when we drop the tipset // containing the message. The tipset passed as the argument is the tipset -// that is being dropped. Note that the message dropped may be re-applied +// that is being dropped. Note that the event dropped may be re-applied // in a different tipset in small amount of time. // // * `StateMatchFunc` is called against each tipset state. If there is a match, // the state change is queued up until the confidence interval has elapsed (and // `StateChangeHandler` is called) func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf StateMatchFunc) error { - hnd := func(data eventData, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { - states, ok := data.([]interface{}) - if !ok || len(states) != 2 { - panic("expected 2 element array") + hnd := func(data eventData, prevTs, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { + states, ok := data.(stateData) + if data != nil && (!ok || len(states) != 2) { + panic("StateChangeHandler: stateData passed to watcher must be a 2 element array: [old state, new state]") } - return scHnd(we.ctx, states[0], states[1], ts, height) + return scHnd(prevTs, ts, states, height) } id, err := we.hcApi.onHeadChanged(check, hnd, rev, confidence, timeout) @@ -557,7 +581,7 @@ type MsgMatchFunc func(msg *types.Message) (bool, error) // message is queued up until the confidence interval has elapsed (and // `MsgHandler` is called) func (me *messageEvents) Called(check CheckFunc, msgHnd MsgHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf MsgMatchFunc) error { - hnd := func(data eventData, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { + hnd := func(data eventData, prevTs, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { msg, ok := data.(*types.Message) if data != nil && !ok { panic("expected msg") diff --git a/chain/events/events_test.go b/chain/events/events_test.go index a048789ec..5185d977b 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -1004,8 +1004,6 @@ func TestRemoveTriggersOnMessage(t *testing.T) { return false, true, nil }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (bool, error) { require.Equal(t, false, applied) - fmt.Println(msg == nil) - fmt.Println(curH) applied = true return more, nil }, func(_ context.Context, ts *types.TipSet) error { @@ -1067,3 +1065,244 @@ func TestRemoveTriggersOnMessage(t *testing.T) { require.Equal(t, true, applied) require.Equal(t, false, reverted) } + +func TestStateChanged(t *testing.T) { + fcs := &fakeCS{ + t: t, + h: 1, + + msgs: map[cid.Cid]fakeMsg{}, + blkMsgs: map[cid.Cid]cid.Cid{}, + tsc: newTSCache(2*build.ForkLengthThreshold, nil), + } + require.NoError(t, fcs.tsc.add(fcs.makeTs(t, nil, 1, dummyCid))) + + events := NewEvents(context.Background(), fcs) + + more := true + var applied, reverted bool + var appliedData stateData + var appliedOldTs *types.TipSet + var appliedNewTs *types.TipSet + var appliedH abi.ChainEpoch + var matchData stateData + + confidence := 3 + timeout := abi.ChainEpoch(20) + + err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { + return false, true, nil + }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + require.Equal(t, false, applied) + applied = true + appliedData = data + appliedOldTs = oldTs + appliedNewTs = newTs + appliedH = curH + return more, nil + }, func(_ context.Context, ts *types.TipSet) error { + reverted = true + return nil + }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { + if matchData == nil { + return false, matchData, nil + } + + d := matchData + matchData = nil + return true, d, nil + }) + require.NoError(t, err) + + // create few blocks to make sure nothing get's randomly called + + fcs.advance(0, 4, nil) // H=5 + require.Equal(t, false, applied) + require.Equal(t, false, reverted) + + // create state change (but below confidence threshold) + matchData = []stateChange{"a", "b"} + fcs.advance(0, 3, nil) + + require.Equal(t, false, applied) + require.Equal(t, false, reverted) + + // create additional block so we are above confidence threshold + + fcs.advance(0, 2, nil) // H=10 (confidence=3, apply) + + require.Equal(t, true, applied) + require.Equal(t, false, reverted) + applied = false + + // dip below confidence (should not apply again) + fcs.advance(2, 2, nil) // H=10 (confidence=3, apply) + + require.Equal(t, false, applied) + require.Equal(t, false, reverted) + + // Change happens from 5 -> 6 + require.Equal(t, abi.ChainEpoch(5), appliedOldTs.Height()) + require.Equal(t, abi.ChainEpoch(6), appliedNewTs.Height()) + + // Actually applied (with confidence) at 9 + require.Equal(t, abi.ChainEpoch(9), appliedH) + + // Make sure the state change was correctly passed through + require.Equal(t, "a", appliedData[0]) + require.Equal(t, "b", appliedData[1]) +} + +func TestStateChangedRevert(t *testing.T) { + fcs := &fakeCS{ + t: t, + h: 1, + + msgs: map[cid.Cid]fakeMsg{}, + blkMsgs: map[cid.Cid]cid.Cid{}, + tsc: newTSCache(2*build.ForkLengthThreshold, nil), + } + require.NoError(t, fcs.tsc.add(fcs.makeTs(t, nil, 1, dummyCid))) + + events := NewEvents(context.Background(), fcs) + + more := true + var applied, reverted bool + var matchData stateData + + confidence := 1 + timeout := abi.ChainEpoch(20) + + err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { + return false, true, nil + }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + require.Equal(t, false, applied) + applied = true + return more, nil + }, func(_ context.Context, ts *types.TipSet) error { + reverted = true + return nil + }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { + if matchData == nil { + return false, matchData, nil + } + + d := matchData + matchData = nil + return true, d, nil + }) + require.NoError(t, err) + + fcs.advance(0, 2, nil) // H=3 + + // Make a state change from TS at height 3 to TS at height 4 + matchData = []stateChange{"a", "b"} + fcs.advance(0, 1, nil) // H=4 + + // Haven't yet reached confidence + require.Equal(t, false, applied) + require.Equal(t, false, reverted) + + // Advance to reach confidence level + fcs.advance(0, 1, nil) // H=5 + + // Should now have called the handler + require.Equal(t, true, applied) + require.Equal(t, false, reverted) + applied = false + + // Advance 3 more TS + fcs.advance(0, 3, nil) // H=8 + + require.Equal(t, false, applied) + require.Equal(t, false, reverted) + + // Regress but not so far as to cause a revert + fcs.advance(3, 1, nil) // H=6 + + require.Equal(t, false, applied) + require.Equal(t, false, reverted) + + // Regress back to state where change happened + fcs.advance(3, 1, nil) // H=4 + + // Expect revert to have happened + require.Equal(t, false, applied) + require.Equal(t, true, reverted) +} + +func TestStateChangedTimeout(t *testing.T) { + fcs := &fakeCS{ + t: t, + h: 1, + + msgs: map[cid.Cid]fakeMsg{}, + blkMsgs: map[cid.Cid]cid.Cid{}, + tsc: newTSCache(2*build.ForkLengthThreshold, nil), + } + require.NoError(t, fcs.tsc.add(fcs.makeTs(t, nil, 1, dummyCid))) + + events := NewEvents(context.Background(), fcs) + + called := false + + err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { + return false, true, nil + }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + called = true + require.Nil(t, data) + require.Equal(t, abi.ChainEpoch(20), newTs.Height()) + require.Equal(t, abi.ChainEpoch(23), curH) + return false, nil + }, func(_ context.Context, ts *types.TipSet) error { + t.Fatal("revert on timeout") + return nil + }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { + return false, stateData{}, nil + }) + + require.NoError(t, err) + + fcs.advance(0, 21, nil) + require.False(t, called) + + fcs.advance(0, 5, nil) + require.True(t, called) + called = false + + // with check func reporting done + + fcs = &fakeCS{ + t: t, + h: 1, + + msgs: map[cid.Cid]fakeMsg{}, + blkMsgs: map[cid.Cid]cid.Cid{}, + tsc: newTSCache(2*build.ForkLengthThreshold, nil), + } + require.NoError(t, fcs.tsc.add(fcs.makeTs(t, nil, 1, dummyCid))) + + events = NewEvents(context.Background(), fcs) + + err = events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { + return true, true, nil + }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + called = true + require.Nil(t, data) + require.Equal(t, abi.ChainEpoch(20), newTs.Height()) + require.Equal(t, abi.ChainEpoch(23), curH) + return false, nil + }, func(_ context.Context, ts *types.TipSet) error { + t.Fatal("revert on timeout") + return nil + }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { + return false, stateData{}, nil + }) + require.NoError(t, err) + + fcs.advance(0, 21, nil) + require.False(t, called) + + fcs.advance(0, 5, nil) + require.False(t, called) +} From 95a9dc9db00b41da5a8f03d3472ee77778446883 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Thu, 25 Jun 2020 12:35:14 -0400 Subject: [PATCH 265/379] refactor: use struct instead of array for state change --- chain/events/events_hc.go | 23 +++++++++++++---------- chain/events/events_test.go | 34 +++++++++++++++++----------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/chain/events/events_hc.go b/chain/events/events_hc.go index 1f508b57f..50826db36 100644 --- a/chain/events/events_hc.go +++ b/chain/events/events_hc.go @@ -387,20 +387,23 @@ func (we *watcherEvents) checkStateChanges(oldState, newState *types.TipSet) map return res } -// Used to store the state change -type stateChange interface{} +// Used to store the state for a stateChange +type stateData interface{} -// Will be checked to ensure it has length 2 -type stateData []stateChange +// A change in state from -> to +type stateChange struct { + from stateData + to stateData +} // StateChangeHandler arguments: // `oldTs` is the state "from" tipset // `newTs` is the state "to" tipset -// `data` is the old / new state +// `states` is the old / new state // `curH`-`ts.Height` = `confidence` -type StateChangeHandler func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (more bool, err error) +type StateChangeHandler func(oldTs, newTs *types.TipSet, states *stateChange, curH abi.ChainEpoch) (more bool, err error) -type StateMatchFunc func(oldTs, newTs *types.TipSet) (bool, stateData, error) +type StateMatchFunc func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) // StateChanged registers a callback which is triggered when a specified state // change occurs or a timeout is reached. @@ -432,9 +435,9 @@ type StateMatchFunc func(oldTs, newTs *types.TipSet) (bool, stateData, error) // `StateChangeHandler` is called) func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf StateMatchFunc) error { hnd := func(data eventData, prevTs, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { - states, ok := data.(stateData) - if data != nil && (!ok || len(states) != 2) { - panic("StateChangeHandler: stateData passed to watcher must be a 2 element array: [old state, new state]") + states, ok := data.(*stateChange) + if data != nil && !ok { + panic("expected *stateChange") } return scHnd(prevTs, ts, states, height) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 5185d977b..36da2bc1e 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -1081,18 +1081,18 @@ func TestStateChanged(t *testing.T) { more := true var applied, reverted bool - var appliedData stateData + var appliedData *stateChange var appliedOldTs *types.TipSet var appliedNewTs *types.TipSet var appliedH abi.ChainEpoch - var matchData stateData + var matchData *stateChange confidence := 3 timeout := abi.ChainEpoch(20) err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { require.Equal(t, false, applied) applied = true appliedData = data @@ -1103,7 +1103,7 @@ func TestStateChanged(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil - }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { + }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { if matchData == nil { return false, matchData, nil } @@ -1121,7 +1121,7 @@ func TestStateChanged(t *testing.T) { require.Equal(t, false, reverted) // create state change (but below confidence threshold) - matchData = []stateChange{"a", "b"} + matchData = &stateChange{from: "a", to: "b"} fcs.advance(0, 3, nil) require.Equal(t, false, applied) @@ -1149,8 +1149,8 @@ func TestStateChanged(t *testing.T) { require.Equal(t, abi.ChainEpoch(9), appliedH) // Make sure the state change was correctly passed through - require.Equal(t, "a", appliedData[0]) - require.Equal(t, "b", appliedData[1]) + require.Equal(t, "a", appliedData.from) + require.Equal(t, "b", appliedData.to) } func TestStateChangedRevert(t *testing.T) { @@ -1168,21 +1168,21 @@ func TestStateChangedRevert(t *testing.T) { more := true var applied, reverted bool - var matchData stateData + var matchData *stateChange confidence := 1 timeout := abi.ChainEpoch(20) err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { require.Equal(t, false, applied) applied = true return more, nil }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil - }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { + }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { if matchData == nil { return false, matchData, nil } @@ -1196,7 +1196,7 @@ func TestStateChangedRevert(t *testing.T) { fcs.advance(0, 2, nil) // H=3 // Make a state change from TS at height 3 to TS at height 4 - matchData = []stateChange{"a", "b"} + matchData = &stateChange{from: "a", to: "b"} fcs.advance(0, 1, nil) // H=4 // Haven't yet reached confidence @@ -1248,7 +1248,7 @@ func TestStateChangedTimeout(t *testing.T) { err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { called = true require.Nil(t, data) require.Equal(t, abi.ChainEpoch(20), newTs.Height()) @@ -1257,8 +1257,8 @@ func TestStateChangedTimeout(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") return nil - }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { - return false, stateData{}, nil + }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { + return false, nil, nil }) require.NoError(t, err) @@ -1286,7 +1286,7 @@ func TestStateChangedTimeout(t *testing.T) { err = events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return true, true, nil - }, func(oldTs, newTs *types.TipSet, data stateData, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { called = true require.Nil(t, data) require.Equal(t, abi.ChainEpoch(20), newTs.Height()) @@ -1295,8 +1295,8 @@ func TestStateChangedTimeout(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") return nil - }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, stateData, error) { - return false, stateData{}, nil + }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { + return false, nil, nil }) require.NoError(t, err) From 728afc0587d2893a1d4674e98e4d44c21fc74842 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Thu, 25 Jun 2020 12:46:43 -0400 Subject: [PATCH 266/379] refactor: remove state API example --- chain/events/state/state.go | 57 ------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 chain/events/state/state.go diff --git a/chain/events/state/state.go b/chain/events/state/state.go deleted file mode 100644 index 75041ad79..000000000 --- a/chain/events/state/state.go +++ /dev/null @@ -1,57 +0,0 @@ -package state - -import ( - "context" - - "github.com/filecoin-project/lotus/chain/store" - "github.com/filecoin-project/specs-actors/actors/abi" - - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/types" -) - -type StateWatcher struct { -} - -type WatcherAPI interface { - ChainNotify(context.Context) (<-chan []*api.HeadChange, error) -} - -type UserData interface{} - -type DiffFunc func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) - -type Callback func(ctx context.Context, oldState, newState *types.TipSet, events interface{}) - -type RevertHandler func(ctx context.Context, ts *types.TipSet) error - -/* -w := NewWatcher(api, OnActorChange(t04, OnDealStateChange(123)), cb) -*/ -func NewWatcher(ctx context.Context, api WatcherAPI, d DiffFunc, apply Callback, revert RevertHandler, confidence, timeout abi.ChainEpoch) { - go func() { - notifs, err := api.ChainNotify(ctx) - if err != nil { - // bad - return - } - - curTs := (<-notifs)[0].Val - d(ctx, curTs, curTs) - - for { - select { - case update := <-notifs: - for i, change := range update { - switch change.Type { - case store.HCApply: - d(ctx, curTs, change.Val) - case store.HCRevert: - - } - } - } - } - - }() -} From e3c897fb68ff787095b1db4a0939e94f5af7491b Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 17 Jun 2020 01:10:29 -0400 Subject: [PATCH 267/379] Change StateReadState to take an address, not an actor --- api/api_full.go | 2 +- api/apistruct/struct.go | 6 +++--- cli/state.go | 7 +------ cmd/lotus-chainwatch/sync.go | 6 ++++-- node/impl/full/state.go | 7 ++++++- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 17b0fdce6..d5a256bd6 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -206,7 +206,7 @@ type FullNode interface { StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error) StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) - StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*ActorState, error) + StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) StateNetworkName(context.Context) (dtypes.NetworkName, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 0c0acd05e..591bcb4a3 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -139,7 +139,7 @@ type FullNodeStruct struct { StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) `perm:"read"` StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"` StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"` - StateReadState func(context.Context, *types.Actor, types.TipSetKey) (*api.ActorState, error) `perm:"read"` + StateReadState func(context.Context, address.Address, types.TipSetKey) (*api.ActorState, error) `perm:"read"` StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"` StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"` StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"` @@ -618,8 +618,8 @@ func (c *FullNodeStruct) StateGetActor(ctx context.Context, actor address.Addres return c.Internal.StateGetActor(ctx, actor, tsk) } -func (c *FullNodeStruct) StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*api.ActorState, error) { - return c.Internal.StateReadState(ctx, act, tsk) +func (c *FullNodeStruct) StateReadState(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.ActorState, error) { + return c.Internal.StateReadState(ctx, addr, tsk) } func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) { diff --git a/cli/state.go b/cli/state.go index 1aad85299..a159f2272 100644 --- a/cli/state.go +++ b/cli/state.go @@ -742,12 +742,7 @@ var stateReadStateCmd = &cli.Command{ return err } - act, err := api.StateGetActor(ctx, addr, ts.Key()) - if err != nil { - return err - } - - as, err := api.StateReadState(ctx, act, ts.Key()) + as, err := api.StateReadState(ctx, addr, ts.Key()) if err != nil { return err } diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 88afb647e..059dcf9d6 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -161,7 +161,8 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. log.Error(err) return } - ast, err := api.StateReadState(ctx, act, genesisTs.Key()) + + ast, err := api.StateReadState(ctx, addr, genesisTs.Key()) if err != nil { log.Error(err) return @@ -210,7 +211,8 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. return } - ast, err := api.StateReadState(ctx, &act, pts.Key()) + ast, err := api.StateReadState(ctx, addr, pts.Key()) + if err != nil { log.Error(err) return diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 048ae7858..43e16d34f 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -300,7 +300,7 @@ func (a *StateAPI) StateAccountKey(ctx context.Context, addr address.Address, ts return a.StateManager.ResolveToKeyAddress(ctx, addr, ts) } -func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*api.ActorState, error) { +func (a *StateAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -310,6 +310,11 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk typ return nil, err } + act, err := state.GetActor(actor) + if err != nil { + return nil, err + } + blk, err := state.Store.(*cbor.BasicIpldStore).Blocks.Get(act.Head) if err != nil { return nil, err From 50aa1e6baa5d6fce83b573bfec82e4cc87b4f5e5 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 25 Jun 2020 00:20:15 -0400 Subject: [PATCH 268/379] Update bitfield --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 404c2d46c..1f60da467 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 - github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e + github.com/filecoin-project/go-bitfield v0.0.2-0.20200624234227-4563d4a0bc01 github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 diff --git a/go.sum b/go.sum index 2b8a31ba6..33dc25268 100644 --- a/go.sum +++ b/go.sum @@ -225,6 +225,8 @@ github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mo github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e h1:gkG/7G+iKy4He+IiQNeQn+nndFznb/vCoOR8iRQsm60= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= +github.com/filecoin-project/go-bitfield v0.0.2-0.20200624234227-4563d4a0bc01 h1:k/FyoahW7Pvqi8p8YF7Np8YcK1XWGJ8TlR1mEICly3E= +github.com/filecoin-project/go-bitfield v0.0.2-0.20200624234227-4563d4a0bc01/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= From e54b49b442c2bbd0f44b6aca14102a4a5c78f93b Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 25 Jun 2020 13:48:50 -0400 Subject: [PATCH 269/379] Bump API version --- build/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/version.go b/build/version.go index 03d5c0792..fc64eae71 100644 --- a/build/version.go +++ b/build/version.go @@ -53,7 +53,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool { } // APIVersion is a semver version of the rpc api exposed -var APIVersion Version = newVer(0, 4, 0) +var APIVersion Version = newVer(0, 5, 0) //nolint:varcheck,deadcode const ( From 2c0a4914cff1c60d5cfad8c81f815fef558ce1db Mon Sep 17 00:00:00 2001 From: frrist Date: Wed, 24 Jun 2020 17:57:51 -0700 Subject: [PATCH 270/379] feat: define miner sector schema - define a miner sector schema to store miner sector details at each tipset the miner experiences a state change. This solution stores redundant data since a miner state change (head cid changes) does not necessarily indicate its sectors changes. - makes progress towards sentinel/issues/10 --- cmd/lotus-chainwatch/mpool.go | 2 +- cmd/lotus-chainwatch/storage.go | 75 +++++++++++ cmd/lotus-chainwatch/sync.go | 229 ++++++++++++++++++++++++++------ 3 files changed, 264 insertions(+), 42 deletions(-) diff --git a/cmd/lotus-chainwatch/mpool.go b/cmd/lotus-chainwatch/mpool.go index ea45380b7..74ffa8771 100644 --- a/cmd/lotus-chainwatch/mpool.go +++ b/cmd/lotus-chainwatch/mpool.go @@ -46,7 +46,7 @@ func subMpool(ctx context.Context, api aapi.FullNode, st *storage) { msgs[v.Message.Message.Cid()] = &v.Message.Message } - log.Infof("Processing %d mpool updates", len(msgs)) + log.Debugf("Processing %d mpool updates", len(msgs)) err := st.storeMessages(msgs) if err != nil { diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index f7f80a9c6..dfdde08e3 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -1,7 +1,9 @@ package main import ( + "context" "database/sql" + "github.com/filecoin-project/specs-actors/actors/abi" "sync" "time" @@ -252,6 +254,24 @@ create table if not exists receipts create index if not exists receipts_msg_state_index on receipts (msg, state); + +create table if not exists miner_sectors +( + stateroot text not null, + miner text not null, + sectorid bigint not null, + activation bigint not null, + dealweight bigint not null, + verifieddealweight bigint not null, + expiration bigint not null, + sealcid text not null, + sealrandepoch bigint not null, + constraint miner_sectors_pk + primary key (stateroot, miner, sectorid) +); + +create index if not exists miner_sectors_state_index + on miner_sectors (stateroot, miner, sectorid); /* create table if not exists miner_heads ( @@ -456,6 +476,61 @@ func (st *storage) storeActors(actors map[address.Address]map[types.Actor]actorI return nil } +type storeSectorsAPI interface { + StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) +} + +func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, sectorApi storeSectorsAPI) error { + tx, err := st.db.Begin() + if err != nil { + return err + } + + if _, err := tx.Exec(`create temp table ms (like miner_sectors excluding constraints) on commit drop;`); err != nil { + return xerrors.Errorf("prep temp: %w", err) + } + + stmt, err := tx.Prepare(`copy ms (stateroot, miner, sectorid, activation, dealweight, verifieddealweight, expiration, sealcid, sealrandepoch) from STDIN `) + if err != nil { + return err + } + + for tipset, miners := range minerTips { + for _, miner := range miners { + sectors, err := sectorApi.StateMinerSectors(context.TODO(), miner.addr, nil, true, tipset) + if err != nil { + log.Debugw("Failed to load sectors", "tipset", tipset.String(), "miner", miner.addr.String(), "error", err) + } + + for _, sector := range sectors { + if _, err := stmt.Exec( + miner.stateroot.String(), + miner.addr.String(), + uint64(sector.ID), + int64(sector.Info.ActivationEpoch), + sector.Info.DealWeight.Uint64(), + sector.Info.VerifiedDealWeight.Uint64(), + int64(sector.Info.Info.Expiration), + sector.Info.Info.SealedCID.String(), + int64(sector.Info.Info.SealRandEpoch), + ); err != nil { + return err + } + } + } + } + + if err := stmt.Close(); err != nil { + return err + } + + if _, err := tx.Exec(`insert into miner_sectors select * from ms on conflict do nothing `); err != nil { + return xerrors.Errorf("actor put: %w", err) + } + + return tx.Commit() +} + func (st *storage) storeMiners(miners map[minerKey]*minerInfo) error { /*tx, err := st.db.Begin() if err != nil { diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 88afb647e..0a0b812d5 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -5,11 +5,15 @@ import ( "container/list" "context" "encoding/json" - "math" - "sync" - + "fmt" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/specs-actors/actors/util/adt" + cbg "github.com/whyrusleeping/cbor-gen" + "math" + "sync" + "time" "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" @@ -60,9 +64,27 @@ type minerInfo struct { state miner.State info miner.MinerInfo - power big.Int - ssize uint64 - psize uint64 + rawPower big.Int + qalPower big.Int + ssize uint64 + psize uint64 +} + +type newMinerInfo struct { + // common + addr address.Address + act types.Actor + stateroot cid.Cid + + // miner specific + state miner.State + info miner.MinerInfo + + // tracked by power actor + rawPower big.Int + qalPower big.Int + ssize uint64 + psize uint64 } type actorInfo struct { @@ -80,25 +102,28 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. log.Infof("Getting headers / actors") + // global list of all blocks that need to be synced allToSync := map[cid.Cid]*types.BlockHeader{} + // a stack toVisit := list.New() for _, header := range headTs.Blocks() { toVisit.PushBack(header) } + // TODO consider making a db query to check where syncing left off at in the case of a restart and avoid reprocessing + // those entries, or write value to file on shutdown + // walk the entire chain starting from headTS for toVisit.Len() > 0 { bh := toVisit.Remove(toVisit.Back()).(*types.BlockHeader) - _, has := hazlist[bh.Cid()] if _, seen := allToSync[bh.Cid()]; seen || has { continue } allToSync[bh.Cid()] = bh - if len(allToSync)%500 == 10 { - log.Infof("todo: (%d) %s @%d", len(allToSync), bh.Cid(), bh.Height) + log.Infof("to visit: (%d) %s @%d", len(allToSync), bh.Cid(), bh.Height) } if len(bh.Parents) == 0 { @@ -116,17 +141,25 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. } } + // Main worker loop, this loop runs until all tipse from headTS to genesis have been processed. for len(allToSync) > 0 { + // first map is addresses -> common actors states (head, code, balance, nonce) + // second map common actor states -> chain state (tipset, stateroot) & unique actor state (deserialization of their head CID) represented as json. actors := map[address.Address]map[types.Actor]actorInfo{} + + // map of actor public key address to ID address addressToID := map[address.Address]address.Address{} minH := abi.ChainEpoch(math.MaxInt64) + // find the blockheader with the lowest height for _, header := range allToSync { if header.Height < minH { minH = header.Height } } + // toSync maps block cids to their headers and contains all block headers that will be synced in this batch + // `maxBatch` is a tunable parameter to control how many blocks we sync per iteration. toSync := map[cid.Cid]*types.BlockHeader{} for c, header := range allToSync { if header.Height < minH+abi.ChainEpoch(maxBatch) { @@ -134,12 +167,14 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. addressToID[header.Miner] = address.Undef } } + // remove everything we are syncing this round from the global list of blocks to sync for c := range toSync { delete(allToSync, c) } - log.Infof("Syncing %d blocks", len(toSync)) + log.Infow("Starting Sync", "height", minH, "numBlocks", len(toSync), "maxBatch", maxBatch) + // collect all actor state that has changes between block headers paDone := 0 parmap.Par(50, parmap.MapArr(toSync), func(bh *types.BlockHeader) { paDone++ @@ -155,6 +190,8 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. return } + // TODO suspicious there is not a lot to be gained by doing this in parallel since the genesis state + // is unlikely to contain a lot of actors, why not for loop here? parmap.Par(50, aadrs, func(addr address.Address) { act, err := api.StateGetActor(ctx, addr, genesisTs.Key()) if err != nil { @@ -195,12 +232,15 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. return } + // TODO Does this return actors that have been deleted between states? + // collect all actors that had state changes between the blockheader parent-state and its grandparent-state. changes, err := api.StateChangedActors(ctx, pts.ParentState(), bh.ParentStateRoot) if err != nil { log.Error(err) return } + // record the state of all actors that have changed for a, act := range changes { act := act @@ -227,12 +267,14 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. if !ok { actors[addr] = map[types.Actor]actorInfo{} } + // a change occurred for the actor with address `addr` and state `act` at tipset `pts`. actors[addr][act] = actorInfo{ stateroot: bh.ParentStateRoot, state: string(state), tsKey: pts.Key(), } addressToID[addr] = address.Undef + // alk.Unlock() } }) @@ -263,57 +305,97 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. log.Infof("Getting miner info") - miners := map[minerKey]*minerInfo{} + // map of tipset to all miners that had a head-change at that tipset. + minerTips := map[types.TipSetKey][]*newMinerInfo{} + // heads we've seen, im being paranoid + headsSeen := map[cid.Cid]bool{} + minerChanges := 0 for addr, m := range actors { for actor, c := range m { if actor.Code != builtin.StorageMinerActorCodeID { continue } - miners[minerKey{ + // only want miner actors with head change events + if headsSeen[actor.Head] { + continue + } + minerChanges++ + + minerTips[c.tsKey] = append(minerTips[c.tsKey], &newMinerInfo{ addr: addr, act: actor, stateroot: c.stateroot, - tsKey: c.tsKey, - }] = &minerInfo{} + + state: miner.State{}, + info: miner.MinerInfo{}, + + rawPower: big.Zero(), + qalPower: big.Zero(), + ssize: 0, + psize: 0, + }) + + headsSeen[actor.Head] = true } } - parmap.Par(50, parmap.KVMapArr(miners), func(it func() (minerKey, *minerInfo)) { - k, info := it() + minerProcessingState := time.Now() + log.Infow("Processing miners", "numTips", len(minerTips), "numMinerChanges", minerChanges) + // extract the power actor state at each tipset, loop over all miners that changed at said tipset and extract their + // claims from the power actor state. This ensures we only fetch the power actors state once for each tipset. + parmap.Par(50, parmap.KVMapArr(minerTips), func(it func() (types.TipSetKey, []*newMinerInfo)) { + tsKey, minerInfo := it() - // TODO: get the storage power actors state and and pull the miner power from there, currently this hits the - // storage power actor once for each miner for each tipset, we can do better by just getting it for each tipset - // and reading each miner power from the result. - pow, err := api.StateMinerPower(ctx, k.addr, k.tsKey) - if err != nil { - log.Error(err) - // Not sure why this would fail, but its probably worth continuing - } - info.power = pow.MinerPower.QualityAdjPower - - sszs, err := api.StateMinerSectorCount(ctx, k.addr, k.tsKey) + // get the power actors claims map + mp, err := getPowerActorClaimsMap(ctx, api, tsKey) if err != nil { log.Error(err) return } - info.psize = sszs.Pset - info.ssize = sszs.Sset + // Get miner raw and quality power + for _, mi := range minerInfo { + var claim power.Claim + // get miner claim from power actors claim map and store if found, else the miner had no claim at + // this tipset + found, err := mp.Get(adt.AddrKey(mi.addr), &claim) + if err != nil { + log.Error(err) + } + if found { + mi.qalPower = claim.QualityAdjPower + mi.rawPower = claim.RawBytePower + } - astb, err := api.ChainReadObj(ctx, k.act.Head) - if err != nil { - log.Error(err) - return + // Get the miner state info + astb, err := api.ChainReadObj(ctx, mi.act.Head) + if err != nil { + log.Error(err) + return + } + if err := mi.state.UnmarshalCBOR(bytes.NewReader(astb)); err != nil { + log.Error(err) + return + } + mi.info = mi.state.Info } - if err := info.state.UnmarshalCBOR(bytes.NewReader(astb)); err != nil { - log.Error(err) - return - } - - info.info = info.state.Info + // TODO Get the Sector Count + // FIXME this is returning a lot of "address not found" errors, which is strange given that StateChangedActors + // retruns all actors that had a state change at tipset `k.tsKey`, maybe its returning deleted miners too?? + /* + sszs, err := api.StateMinerSectorCount(ctx, k.addr, k.tsKey) + if err != nil { + info.psize = 0 + info.ssize = 0 + } else { + info.psize = sszs.Pset + info.ssize = sszs.Sset + } + */ }) + log.Infow("Completed Miner Processing", "duration", time.Since(minerProcessingState).String(), "processed", minerChanges) log.Info("Getting receipts") @@ -340,12 +422,24 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. return } - log.Info("Storing miners") + // TODO re-enable when ready to fill miner metadata, the contents of storeMiners is commented out too. + /* + log.Info("Storing miners") - if err := st.storeMiners(miners); err != nil { + if err := st.storeMiners(miners); err != nil { + log.Error(err) + return + } + */ + + log.Info("Storing miner sectors") + + sectorStart := time.Now() + if err := st.storeSectors(minerTips, api); err != nil { log.Error(err) return } + log.Infow("Finished storing miner sectors", "duration", time.Since(sectorStart).String()) log.Infof("Storing messages") @@ -463,3 +557,56 @@ func fetchParentReceipts(ctx context.Context, api api.FullNode, toSync map[cid.C return out } + +// load the power actor state clam as an adt.Map at the tipset `ts`. +func getPowerActorClaimsMap(ctx context.Context, api api.FullNode, ts types.TipSetKey) (*adt.Map, error) { + powerActor, err := api.StateGetActor(ctx, builtin.StoragePowerActorAddr, ts) + if err != nil { + return nil, err + } + + powerRaw, err := api.ChainReadObj(ctx, powerActor.Head) + if err != nil { + return nil, err + } + + var powerActorState power.State + if err := powerActorState.UnmarshalCBOR(bytes.NewReader(powerRaw)); err != nil { + return nil, fmt.Errorf("failed to unmarshal power actor state: %w", err) + } + + s := &apiIpldStore{ctx, api} + return adt.AsMap(s, powerActorState.Claims) +} + +// require for AMT and HAMT access +// TODO extract this to a common locaiton in lotus and reuse the code +type apiIpldStore struct { + ctx context.Context + api api.FullNode +} + +func (ht *apiIpldStore) Context() context.Context { + return ht.ctx +} + +func (ht *apiIpldStore) Get(ctx context.Context, c cid.Cid, out interface{}) error { + raw, err := ht.api.ChainReadObj(ctx, c) + if err != nil { + return err + } + + cu, ok := out.(cbg.CBORUnmarshaler) + if ok { + if err := cu.UnmarshalCBOR(bytes.NewReader(raw)); err != nil { + return err + } + return nil + } + + return fmt.Errorf("Object does not implement CBORUnmarshaler") +} + +func (ht *apiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error) { + return cid.Undef, fmt.Errorf("Put is not implemented on apiIpldStore") +} From abad4a39415175f67f3d6a85d929d01297efc915 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Thu, 25 Jun 2020 17:43:37 -0400 Subject: [PATCH 271/379] refactor: modify predicates API --- chain/events/events_called.go | 359 ------------------------------- chain/events/events_hc.go | 20 +- chain/events/events_test.go | 36 ++-- chain/events/state/predicates.go | 77 ++++--- 4 files changed, 73 insertions(+), 419 deletions(-) delete mode 100644 chain/events/events_called.go diff --git a/chain/events/events_called.go b/chain/events/events_called.go deleted file mode 100644 index 0bae99404..000000000 --- a/chain/events/events_called.go +++ /dev/null @@ -1,359 +0,0 @@ -package events - -import ( - "context" - "math" - "sync" - - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/ipfs/go-cid" - "golang.org/x/xerrors" - - "github.com/filecoin-project/lotus/chain/types" -) - -const NoTimeout = math.MaxInt64 - -type triggerID = uint64 - -// msgH is the block height at which a message was present / event has happened -type msgH = abi.ChainEpoch - -// triggerH is the block height at which the listener will be notified about the -// message (msgH+confidence) -type triggerH = abi.ChainEpoch - -// CalledHandler arguments: -// `ts` is the tipset, in which the `msg` is included. -// `curH`-`ts.Height` = `confidence` -type CalledHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) - -// CheckFunc is used for atomicity guarantees. If the condition the callbacks -// wait for has already happened in tipset `ts` -// -// If `done` is true, timeout won't be triggered -// If `more` is false, no messages will be sent to CalledHandler (RevertHandler -// may still be called) -type CheckFunc func(ts *types.TipSet) (done bool, more bool, err error) - -type MatchFunc func(msg *types.Message) (bool, error) - -type callHandler struct { - confidence int - timeout abi.ChainEpoch - - disabled bool // TODO: GC after gcConfidence reached - - handle CalledHandler - revert RevertHandler -} - -type queuedEvent struct { - trigger triggerID - - h abi.ChainEpoch - msg *types.Message - - called bool -} - -type calledEvents struct { - cs eventAPI - tsc *tipSetCache - ctx context.Context - gcConfidence uint64 - - at abi.ChainEpoch - - lk sync.Mutex - - ctr triggerID - - triggers map[triggerID]*callHandler - matchers map[triggerID][]MatchFunc - - // maps block heights to events - // [triggerH][msgH][event] - confQueue map[triggerH]map[msgH][]*queuedEvent - - // [msgH][triggerH] - revertQueue map[msgH][]triggerH - - // [timeoutH+confidence][triggerID]{calls} - timeouts map[abi.ChainEpoch]map[triggerID]int -} - -func (e *calledEvents) headChangeCalled(rev, app []*types.TipSet) error { - e.lk.Lock() - defer e.lk.Unlock() - - for _, ts := range rev { - e.handleReverts(ts) - e.at = ts.Height() - } - - for _, ts := range app { - // called triggers - e.checkNewCalls(ts) - for ; e.at <= ts.Height(); e.at++ { - e.applyWithConfidence(ts, e.at) - e.applyTimeouts(ts) - } - } - - return nil -} - -func (e *calledEvents) handleReverts(ts *types.TipSet) { - reverts, ok := e.revertQueue[ts.Height()] - if !ok { - return // nothing to do - } - - for _, triggerH := range reverts { - toRevert := e.confQueue[triggerH][ts.Height()] - for _, event := range toRevert { - if !event.called { - continue // event wasn't apply()-ied yet - } - - trigger := e.triggers[event.trigger] - - if err := trigger.revert(e.ctx, ts); err != nil { - log.Errorf("reverting chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, ts.Height(), triggerH, err) - } - } - delete(e.confQueue[triggerH], ts.Height()) - } - delete(e.revertQueue, ts.Height()) -} - -func (e *calledEvents) checkNewCalls(ts *types.TipSet) { - pts, err := e.cs.ChainGetTipSet(e.ctx, ts.Parents()) // we actually care about messages in the parent tipset here - if err != nil { - log.Errorf("getting parent tipset in checkNewCalls: %s", err) - return - } - - e.messagesForTs(pts, func(msg *types.Message) { - // TODO: provide receipts - for tid, matchFns := range e.matchers { - var matched bool - for _, matchFn := range matchFns { - ok, err := matchFn(msg) - if err != nil { - log.Errorf("event matcher failed: %s", err) - continue - } - matched = ok - - if matched { - break - } - } - - if matched { - e.queueForConfidence(tid, msg, ts) - break - } - } - }) -} - -func (e *calledEvents) queueForConfidence(trigID uint64, msg *types.Message, ts *types.TipSet) { - trigger := e.triggers[trigID] - - appliedH := ts.Height() - - triggerH := appliedH + abi.ChainEpoch(trigger.confidence) - - byOrigH, ok := e.confQueue[triggerH] - if !ok { - byOrigH = map[abi.ChainEpoch][]*queuedEvent{} - e.confQueue[triggerH] = byOrigH - } - - byOrigH[appliedH] = append(byOrigH[appliedH], &queuedEvent{ - trigger: trigID, - h: appliedH, - msg: msg, - }) - - e.revertQueue[appliedH] = append(e.revertQueue[appliedH], triggerH) -} - -func (e *calledEvents) applyWithConfidence(ts *types.TipSet, height abi.ChainEpoch) { - byOrigH, ok := e.confQueue[height] - if !ok { - return // no triggers at thin height - } - - for origH, events := range byOrigH { - triggerTs, err := e.tsc.get(origH) - if err != nil { - log.Errorf("events: applyWithConfidence didn't find tipset for event; wanted %d; current %d", origH, height) - } - - for _, event := range events { - if event.called { - continue - } - - trigger := e.triggers[event.trigger] - if trigger.disabled { - continue - } - - rec, err := e.cs.StateGetReceipt(e.ctx, event.msg.Cid(), ts.Key()) - if err != nil { - log.Error(err) - return - } - - more, err := trigger.handle(event.msg, rec, triggerTs, height) - if err != nil { - log.Errorf("chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, origH, height, err) - continue // don't revert failed calls - } - - event.called = true - - touts, ok := e.timeouts[trigger.timeout] - if ok { - touts[event.trigger]++ - } - - trigger.disabled = !more - } - } -} - -func (e *calledEvents) applyTimeouts(ts *types.TipSet) { - triggers, ok := e.timeouts[ts.Height()] - if !ok { - return // nothing to do - } - - for triggerID, calls := range triggers { - if calls > 0 { - continue // don't timeout if the method was called - } - trigger := e.triggers[triggerID] - if trigger.disabled { - continue - } - - timeoutTs, err := e.tsc.get(ts.Height() - abi.ChainEpoch(trigger.confidence)) - if err != nil { - log.Errorf("events: applyTimeouts didn't find tipset for event; wanted %d; current %d", ts.Height()-abi.ChainEpoch(trigger.confidence), ts.Height()) - } - - more, err := trigger.handle(nil, nil, timeoutTs, ts.Height()) - if err != nil { - log.Errorf("chain trigger (call @H %d, called @ %d) failed: %s", timeoutTs.Height(), ts.Height(), err) - continue // don't revert failed calls - } - - trigger.disabled = !more // allows messages after timeout - } -} - -func (e *calledEvents) messagesForTs(ts *types.TipSet, consume func(*types.Message)) { - seen := map[cid.Cid]struct{}{} - - for _, tsb := range ts.Blocks() { - - msgs, err := e.cs.ChainGetBlockMessages(context.TODO(), tsb.Cid()) - if err != nil { - log.Errorf("messagesForTs MessagesForBlock failed (ts.H=%d, Bcid:%s, B.Mcid:%s): %s", ts.Height(), tsb.Cid(), tsb.Messages, err) - // this is quite bad, but probably better than missing all the other updates - continue - } - - for _, m := range msgs.BlsMessages { - _, ok := seen[m.Cid()] - if ok { - continue - } - seen[m.Cid()] = struct{}{} - - consume(m) - } - - for _, m := range msgs.SecpkMessages { - _, ok := seen[m.Message.Cid()] - if ok { - continue - } - seen[m.Message.Cid()] = struct{}{} - - consume(&m.Message) - } - } -} - -// Called registers a callbacks which are triggered when a specified method is -// called on an actor, or a timeout is reached. -// -// * `CheckFunc` callback is invoked immediately with a recent tipset, it -// returns two booleans - `done`, and `more`. -// -// * `done` should be true when some on-chain action we are waiting for has -// happened. When `done` is set to true, timeout trigger is disabled. -// -// * `more` should be false when we don't want to receive new notifications -// through CalledHandler. Note that notifications may still be delivered to -// RevertHandler -// -// * `CalledHandler` is called when the specified event was observed on-chain, -// and a confidence threshold was reached, or the specified `timeout` height -// was reached with no events observed. When this callback is invoked on a -// timeout, `msg` is set to nil. This callback returns a boolean specifying -// whether further notifications should be sent, like `more` return param -// from `CheckFunc` above. -// -// * `RevertHandler` is called after apply handler, when we drop the tipset -// containing the message. The tipset passed as the argument is the tipset -// that is being dropped. Note that the message dropped may be re-applied -// in a different tipset in small amount of time. -func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf MatchFunc) error { - e.lk.Lock() - defer e.lk.Unlock() - - ts := e.tsc.best() - done, more, err := check(ts) - if err != nil { - return xerrors.Errorf("called check error (h: %d): %w", ts.Height(), err) - } - if done { - timeout = NoTimeout - } - - id := e.ctr - e.ctr++ - - e.triggers[id] = &callHandler{ - confidence: confidence, - timeout: timeout + abi.ChainEpoch(confidence), - - disabled: !more, - - handle: hnd, - revert: rev, - } - - e.matchers[id] = append(e.matchers[id], mf) - - if timeout != NoTimeout { - if e.timeouts[timeout+abi.ChainEpoch(confidence)] == nil { - e.timeouts[timeout+abi.ChainEpoch(confidence)] = map[uint64]int{} - } - e.timeouts[timeout+abi.ChainEpoch(confidence)][id] = 0 - } - - return nil -} - -func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, msg types.ChainMsg) error { - return e.Called(e.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, e.MatchMsg(msg.VMMessage())) -} diff --git a/chain/events/events_hc.go b/chain/events/events_hc.go index 50826db36..01f5fdfcc 100644 --- a/chain/events/events_hc.go +++ b/chain/events/events_hc.go @@ -387,23 +387,17 @@ func (we *watcherEvents) checkStateChanges(oldState, newState *types.TipSet) map return res } -// Used to store the state for a stateChange -type stateData interface{} - -// A change in state from -> to -type stateChange struct { - from stateData - to stateData -} +// A change in state +type StateChange interface{} // StateChangeHandler arguments: // `oldTs` is the state "from" tipset // `newTs` is the state "to" tipset -// `states` is the old / new state +// `states` is the change in state // `curH`-`ts.Height` = `confidence` -type StateChangeHandler func(oldTs, newTs *types.TipSet, states *stateChange, curH abi.ChainEpoch) (more bool, err error) +type StateChangeHandler func(oldTs, newTs *types.TipSet, states StateChange, curH abi.ChainEpoch) (more bool, err error) -type StateMatchFunc func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) +type StateMatchFunc func(oldTs, newTs *types.TipSet) (bool, StateChange, error) // StateChanged registers a callback which is triggered when a specified state // change occurs or a timeout is reached. @@ -435,9 +429,9 @@ type StateMatchFunc func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) // `StateChangeHandler` is called) func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, mf StateMatchFunc) error { hnd := func(data eventData, prevTs, ts *types.TipSet, height abi.ChainEpoch) (bool, error) { - states, ok := data.(*stateChange) + states, ok := data.(StateChange) if data != nil && !ok { - panic("expected *stateChange") + panic("expected StateChange") } return scHnd(prevTs, ts, states, height) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 36da2bc1e..2bb5b0916 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -1066,6 +1066,11 @@ func TestRemoveTriggersOnMessage(t *testing.T) { require.Equal(t, false, reverted) } +type testStateChange struct { + from string + to string +} + func TestStateChanged(t *testing.T) { fcs := &fakeCS{ t: t, @@ -1081,18 +1086,18 @@ func TestStateChanged(t *testing.T) { more := true var applied, reverted bool - var appliedData *stateChange + var appliedData StateChange var appliedOldTs *types.TipSet var appliedNewTs *types.TipSet var appliedH abi.ChainEpoch - var matchData *stateChange + var matchData StateChange confidence := 3 timeout := abi.ChainEpoch(20) err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data StateChange, curH abi.ChainEpoch) (bool, error) { require.Equal(t, false, applied) applied = true appliedData = data @@ -1103,7 +1108,7 @@ func TestStateChanged(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil - }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { + }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, StateChange, error) { if matchData == nil { return false, matchData, nil } @@ -1121,7 +1126,7 @@ func TestStateChanged(t *testing.T) { require.Equal(t, false, reverted) // create state change (but below confidence threshold) - matchData = &stateChange{from: "a", to: "b"} + matchData = testStateChange{from: "a", to: "b"} fcs.advance(0, 3, nil) require.Equal(t, false, applied) @@ -1149,8 +1154,9 @@ func TestStateChanged(t *testing.T) { require.Equal(t, abi.ChainEpoch(9), appliedH) // Make sure the state change was correctly passed through - require.Equal(t, "a", appliedData.from) - require.Equal(t, "b", appliedData.to) + rcvd := appliedData.(testStateChange) + require.Equal(t, "a", rcvd.from) + require.Equal(t, "b", rcvd.to) } func TestStateChangedRevert(t *testing.T) { @@ -1168,21 +1174,21 @@ func TestStateChangedRevert(t *testing.T) { more := true var applied, reverted bool - var matchData *stateChange + var matchData StateChange confidence := 1 timeout := abi.ChainEpoch(20) err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data StateChange, curH abi.ChainEpoch) (bool, error) { require.Equal(t, false, applied) applied = true return more, nil }, func(_ context.Context, ts *types.TipSet) error { reverted = true return nil - }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { + }, confidence, timeout, func(oldTs, newTs *types.TipSet) (bool, StateChange, error) { if matchData == nil { return false, matchData, nil } @@ -1196,7 +1202,7 @@ func TestStateChangedRevert(t *testing.T) { fcs.advance(0, 2, nil) // H=3 // Make a state change from TS at height 3 to TS at height 4 - matchData = &stateChange{from: "a", to: "b"} + matchData = testStateChange{from: "a", to: "b"} fcs.advance(0, 1, nil) // H=4 // Haven't yet reached confidence @@ -1248,7 +1254,7 @@ func TestStateChangedTimeout(t *testing.T) { err := events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return false, true, nil - }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data StateChange, curH abi.ChainEpoch) (bool, error) { called = true require.Nil(t, data) require.Equal(t, abi.ChainEpoch(20), newTs.Height()) @@ -1257,7 +1263,7 @@ func TestStateChangedTimeout(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") return nil - }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { + }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, StateChange, error) { return false, nil, nil }) @@ -1286,7 +1292,7 @@ func TestStateChangedTimeout(t *testing.T) { err = events.StateChanged(func(ts *types.TipSet) (d bool, m bool, e error) { return true, true, nil - }, func(oldTs, newTs *types.TipSet, data *stateChange, curH abi.ChainEpoch) (bool, error) { + }, func(oldTs, newTs *types.TipSet, data StateChange, curH abi.ChainEpoch) (bool, error) { called = true require.Nil(t, data) require.Equal(t, abi.ChainEpoch(20), newTs.Height()) @@ -1295,7 +1301,7 @@ func TestStateChangedTimeout(t *testing.T) { }, func(_ context.Context, ts *types.TipSet) error { t.Fatal("revert on timeout") return nil - }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, *stateChange, error) { + }, 3, 20, func(oldTs, newTs *types.TipSet) (bool, StateChange, error) { return false, nil, nil }) require.NoError(t, err) diff --git a/chain/events/state/predicates.go b/chain/events/state/predicates.go index e9d9a7393..df1bcde30 100644 --- a/chain/events/state/predicates.go +++ b/chain/events/state/predicates.go @@ -2,38 +2,49 @@ package state import ( "context" - - "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-amt-ipld/v2" - "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" ) -type StatePredicates struct { - sm *stmgr.StateManager +type UserData interface{} + +type ChainApi interface { + ChainHasObj(context.Context, cid.Cid) (bool, error) + ChainReadObj(context.Context, cid.Cid) ([]byte, error) + StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) } -func NewStatePredicates(sm *stmgr.StateManager) *StatePredicates { +type StatePredicates struct { + api ChainApi + cst *cbor.BasicIpldStore +} + +func NewStatePredicates(api ChainApi) *StatePredicates { return &StatePredicates{ - sm: sm, + api: api, + cst: cbor.NewCborStore(apibstore.NewAPIBlockstore(api)), } } +type DiffFunc func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) + type DiffStateFunc func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFunc DiffStateFunc) DiffFunc { return func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) { - oldActor, err := sp.sm.GetActor(addr, oldState) + oldActor, err := sp.api.StateGetActor(ctx, addr, oldState.Key()) if err != nil { return false, nil, err } - newActor, err := sp.sm.GetActor(addr, newState) + newActor, err := sp.api.StateGetActor(ctx, addr, newState.Key()) if oldActor.Head.Equals(newActor.Head) { return false, nil, nil } @@ -46,12 +57,11 @@ type DiffStorageMarketStateFunc func(ctx context.Context, oldState *market.State func (sp *StatePredicates) OnStorageMarketActorChanged(addr address.Address, diffStorageMarketState DiffStorageMarketStateFunc) DiffFunc { return sp.OnActorStateChanged(builtin.StorageMarketActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) { var oldState market.State - cst := cbor.NewCborStore(sp.sm.ChainStore().Blockstore()) - if err := cst.Get(ctx, oldActorStateHead, &oldState); err != nil { + if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil { return false, nil, err } var newState market.State - if err := cst.Get(ctx, newActorStateHead, &newActorStateHead); err != nil { + if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil { return false, nil, err } return diffStorageMarketState(ctx, &oldState, &newState) @@ -65,37 +75,40 @@ func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) if oldState.States.Equals(newState.States) { return false, nil, nil } - blks := cbor.NewCborStore(sp.sm.ChainStore().Blockstore()) - oldRoot, err := amt.LoadAMT(ctx, blks, oldState.States) + + oldRoot, err := amt.LoadAMT(ctx, sp.cst, oldState.States) if err != nil { return false, nil, err } - newRoot, err := amt.LoadAMT(ctx, blks, newState.States) + newRoot, err := amt.LoadAMT(ctx, sp.cst, newState.States) if err != nil { return false, nil, err } + return diffDealStates(ctx, oldRoot, newRoot) } } -func (sp *StatePredicates) DealStateChangedForIDs(ctx context.Context, dealIds []abi.DealID, oldRoot, newRoot *amt.Root) (changed bool, user UserData, err error) { - var changedDeals []abi.DealID - for _, dealId := range dealIds { - var oldDeal, newDeal market.DealState - err := oldRoot.Get(ctx, uint64(dealId), &oldDeal) - if err != nil { - return false, nil, err +func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDealStatesFunc { + return func(ctx context.Context, oldDealStateRoot *amt.Root, newDealStateRoot *amt.Root) (changed bool, user UserData, err error) { + var changedDeals []abi.DealID + for _, dealId := range dealIds { + var oldDeal, newDeal market.DealState + err := oldDealStateRoot.Get(ctx, uint64(dealId), &oldDeal) + if err != nil { + return false, nil, err + } + err = newDealStateRoot.Get(ctx, uint64(dealId), &newDeal) + if err != nil { + return false, nil, err + } + if oldDeal != newDeal { + changedDeals = append(changedDeals, dealId) + } } - err = newRoot.Get(ctx, uint64(dealId), &newDeal) - if err != nil { - return false, nil, err - } - if oldDeal != newDeal { - changedDeals = append(changedDeals, dealId) + if len(changedDeals) > 0 { + return true, changed, nil } + return false, nil, nil } - if len(changedDeals) > 0 { - return true, changed, nil - } - return false, nil, nil } From d8b647cc3ae443cc2b75321d478b3629eea0a9d2 Mon Sep 17 00:00:00 2001 From: frrist Date: Thu, 25 Jun 2020 16:07:43 -0700 Subject: [PATCH 272/379] fixup! feat: define miner sector schema --- cmd/lotus-chainwatch/storage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index dfdde08e3..e9361e5a4 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -270,7 +270,7 @@ create table if not exists miner_sectors primary key (stateroot, miner, sectorid) ); -create index if not exists miner_sectors_state_index +create index if not exists miner_sectors_stateroot_miner_sectorid_index on miner_sectors (stateroot, miner, sectorid); /* create table if not exists miner_heads From 47c3e14d4b83474b60c299f6611d2541749f4f59 Mon Sep 17 00:00:00 2001 From: frrist Date: Thu, 25 Jun 2020 17:00:22 -0700 Subject: [PATCH 273/379] fixup! feat: define miner sector schema --- cmd/lotus-chainwatch/sync.go | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 0a0b812d5..0f633954b 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -174,6 +174,8 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. log.Infow("Starting Sync", "height", minH, "numBlocks", len(toSync), "maxBatch", maxBatch) + // map of addresses to changed actors + var changes map[string]types.Actor // collect all actor state that has changes between block headers paDone := 0 parmap.Par(50, parmap.MapArr(toSync), func(bh *types.BlockHeader) { @@ -234,7 +236,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. // TODO Does this return actors that have been deleted between states? // collect all actors that had state changes between the blockheader parent-state and its grandparent-state. - changes, err := api.StateChangedActors(ctx, pts.ParentState(), bh.ParentStateRoot) + changes, err = api.StateChangedActors(ctx, pts.ParentState(), bh.ParentStateRoot) if err != nil { log.Error(err) return @@ -279,6 +281,11 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. } }) + // map of tipset to all miners that had a head-change at that tipset. + minerTips := make(map[types.TipSetKey][]*newMinerInfo, len(changes)) + // heads we've seen, im being paranoid + headsSeen := make(map[cid.Cid]struct{}, len(actors)) + log.Infof("Getting messages") msgs, incls := fetchMessages(ctx, api, toSync) @@ -305,11 +312,6 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. log.Infof("Getting miner info") - // map of tipset to all miners that had a head-change at that tipset. - minerTips := map[types.TipSetKey][]*newMinerInfo{} - // heads we've seen, im being paranoid - headsSeen := map[cid.Cid]bool{} - minerChanges := 0 for addr, m := range actors { for actor, c := range m { @@ -318,7 +320,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. } // only want miner actors with head change events - if headsSeen[actor.Head] { + if _, found := headsSeen[actor.Head]; found { continue } minerChanges++ @@ -333,15 +335,13 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. rawPower: big.Zero(), qalPower: big.Zero(), - ssize: 0, - psize: 0, }) - headsSeen[actor.Head] = true + headsSeen[actor.Head] = struct{}{} } } - minerProcessingState := time.Now() + minerProcessingStartedAt := time.Now() log.Infow("Processing miners", "numTips", len(minerTips), "numMinerChanges", minerChanges) // extract the power actor state at each tipset, loop over all miners that changed at said tipset and extract their // claims from the power actor state. This ensures we only fetch the power actors state once for each tipset. @@ -395,7 +395,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. } */ }) - log.Infow("Completed Miner Processing", "duration", time.Since(minerProcessingState).String(), "processed", minerChanges) + log.Infow("Completed Miner Processing", "duration", time.Since(minerProcessingStartedAt).String(), "processed", minerChanges) log.Info("Getting receipts") @@ -580,7 +580,7 @@ func getPowerActorClaimsMap(ctx context.Context, api api.FullNode, ts types.TipS } // require for AMT and HAMT access -// TODO extract this to a common locaiton in lotus and reuse the code +// TODO extract this to a common location in lotus and reuse the code type apiIpldStore struct { ctx context.Context api api.FullNode @@ -603,8 +603,7 @@ func (ht *apiIpldStore) Get(ctx context.Context, c cid.Cid, out interface{}) err } return nil } - - return fmt.Errorf("Object does not implement CBORUnmarshaler") + return fmt.Errorf("Object does not implement CBORUnmarshaler: %T", out) } func (ht *apiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error) { From 6fe39ef0653af4a0a72671555e00bff2e1b9f0ea Mon Sep 17 00:00:00 2001 From: frrist Date: Thu, 25 Jun 2020 17:03:28 -0700 Subject: [PATCH 274/379] fixup! feat: define miner sector schema --- cmd/lotus-chainwatch/sync.go | 14 +++++++------- node/impl/full/state.go | 17 +++++++++-------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 0f633954b..db9786d4c 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -6,20 +6,20 @@ import ( "context" "encoding/json" "fmt" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/builtin/power" - "github.com/filecoin-project/specs-actors/actors/util/adt" - cbg "github.com/whyrusleeping/cbor-gen" "math" "sync" "time" "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/abi/big" - - "github.com/ipfs/go-cid" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/store" diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 048ae7858..6140cf5df 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -15,6 +15,15 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/sector-storage/ffiwrapper" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/beacon" @@ -27,14 +36,6 @@ import ( "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/lib/bufbstore" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/sector-storage/ffiwrapper" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/market" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" - samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - "github.com/filecoin-project/specs-actors/actors/builtin/power" ) type StateAPI struct { From 38533631bf8c136d3cb164a236f6d3f4dea50546 Mon Sep 17 00:00:00 2001 From: Rob Quist Date: Fri, 26 Jun 2020 02:09:39 +0200 Subject: [PATCH 275/379] Bump to Go v. 1.14 as requirement --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3038e929c..b143793aa 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ all: build unexport GOFLAGS GOVERSION:=$(shell go version | cut -d' ' -f 3 | cut -d. -f 2) -ifeq ($(shell expr $(GOVERSION) \< 13), 1) +ifeq ($(shell expr $(GOVERSION) \< 14), 1) $(warning Your Golang version is go 1.$(GOVERSION)) $(error Update Golang to version $(shell grep '^go' go.mod)) endif From eafb04004ef67da5879e84eb3c07e2a9f7fdad11 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 26 Jun 2020 09:06:01 +0300 Subject: [PATCH 276/379] Fix to addresses in paychmgr channel creation --- paychmgr/paych.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paychmgr/paych.go b/paychmgr/paych.go index 597663a94..763c448f9 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -76,7 +76,7 @@ func (pm *Manager) TrackInboundChannel(ctx context.Context, ch address.Address) return err } from := account.Address - _, err = pm.sm.LoadActorState(ctx, st.From, &account, nil) + _, err = pm.sm.LoadActorState(ctx, st.To, &account, nil) if err != nil { return err } @@ -114,7 +114,7 @@ func (pm *Manager) loadOutboundChannelInfo(ctx context.Context, ch address.Addre return nil, err } from := account.Address - _, err = pm.sm.LoadActorState(ctx, st.From, &account, nil) + _, err = pm.sm.LoadActorState(ctx, st.To, &account, nil) if err != nil { return nil, err } From 5d9a775699982cc8bbaacbabec078a8123adb0f8 Mon Sep 17 00:00:00 2001 From: laser Date: Fri, 26 Jun 2020 10:33:06 -0700 Subject: [PATCH 277/379] replace enable/disable commands with selection commands --- api/api_storage.go | 2 + api/apistruct/struct.go | 10 +++ cmd/lotus-storage-miner/market.go | 79 ++++++++++++++++------ cmd/lotus-storage-miner/retrieval-deals.go | 69 +++++++++++++++---- node/impl/storminer.go | 10 +++ 5 files changed, 136 insertions(+), 34 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 6d8fe384e..ab2293142 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -56,7 +56,9 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) + DealsAcceptingStorageDeals(context.Context) (bool, error) DealsSetAcceptingStorageDeals(context.Context, bool) error + DealsAcceptingRetrievalDeals(context.Context) (bool, error) DealsSetAcceptingRetrievalDeals(context.Context, bool) error DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error) DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 0c0acd05e..4a8a7eb28 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -226,7 +226,9 @@ type StorageMinerStruct struct { DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsAcceptingStorageDeals func(context.Context) (bool, error) `perm:"admin"` DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsAcceptingRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` DealsSetAcceptingRetrievalDeals func(context.Context, bool) error `perm:"admin"` DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` @@ -878,10 +880,18 @@ func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.Sto return c.Internal.DealsList(ctx) } +func (c *StorageMinerStruct) DealsAcceptingStorageDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsAcceptingStorageDeals(ctx) +} + func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, b bool) error { return c.Internal.DealsSetAcceptingStorageDeals(ctx, b) } +func (c *StorageMinerStruct) DealsAcceptingRetrievalDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsAcceptingRetrievalDeals(ctx) +} + func (c *StorageMinerStruct) DealsSetAcceptingRetrievalDeals(ctx context.Context, b bool) error { return c.Internal.DealsSetAcceptingRetrievalDeals(ctx, b) } diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index e658be1cf..c512aad02 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -50,33 +50,73 @@ func GetCidEncoder(cctx *cli.Context) (cidenc.Encoder, error) { return e, nil } -var enableCmd = &cli.Command{ - Name: "enable", - Usage: "Configure the miner to consider storage deal proposals", - Flags: []cli.Flag{}, - Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - - return api.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), true) +var storageDealSelectionCmd = &cli.Command{ + Name: "selection", + Usage: "Configure acceptance criteria for storage deal proposals", + Subcommands: []*cli.Command{ + storageDealSelectionShowCmd, + storageDealSelectionResetCmd, + storageDealSelectionRejectCmd, }, } -var disableCmd = &cli.Command{ - Name: "disable", - Usage: "Configure the miner to reject all storage deal proposals", - Flags: []cli.Flag{}, +var storageDealSelectionShowCmd = &cli.Command{ + Name: "list", + Usage: "List storage deal proposal selection criteria", Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { return err } defer closer() - return api.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), false) + isAcceptingStorageDeals, err := smapi.DealsAcceptingStorageDeals(lcli.DaemonContext(cctx)) + if err != nil { + return err + } + + fmt.Printf("offline storage deals: %t\n", isAcceptingStorageDeals) + fmt.Printf("online storage deals: %t\n", isAcceptingStorageDeals) + + return nil + }, +} + +var storageDealSelectionResetCmd = &cli.Command{ + Name: "reset", + Usage: "Reset storage deal proposal selection criteria to default values", + Action: func(cctx *cli.Context) error { + smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + err = smapi.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), true) + if err != nil { + return err + } + + return nil + }, +} + +var storageDealSelectionRejectCmd = &cli.Command{ + Name: "reject", + Usage: "Configure criteria which necessitate automatic rejection", + Action: func(cctx *cli.Context) error { + smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + err = smapi.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } + + return nil }, } @@ -223,8 +263,7 @@ var storageDealsCmd = &cli.Command{ Subcommands: []*cli.Command{ dealsImportDataCmd, dealsListCmd, - enableCmd, - disableCmd, + storageDealSelectionCmd, setAskCmd, getAskCmd, setBlocklistCmd, diff --git a/cmd/lotus-storage-miner/retrieval-deals.go b/cmd/lotus-storage-miner/retrieval-deals.go index ee503fb2b..33045e00b 100644 --- a/cmd/lotus-storage-miner/retrieval-deals.go +++ b/cmd/lotus-storage-miner/retrieval-deals.go @@ -1,6 +1,8 @@ package main import ( + "fmt" + lcli "github.com/filecoin-project/lotus/cli" "github.com/urfave/cli/v2" ) @@ -9,37 +11,76 @@ var retrievalDealsCmd = &cli.Command{ Name: "retrieval-deals", Usage: "Manage retrieval deals and related configuration", Subcommands: []*cli.Command{ - enableRetrievalCmd, - disableRetrievalCmd, + retrievalDealSelectionCmd, }, } -var enableRetrievalCmd = &cli.Command{ - Name: "enable", - Usage: "Configure the miner to consider retrieval deal proposals", - Flags: []cli.Flag{}, +var retrievalDealSelectionCmd = &cli.Command{ + Name: "selection", + Usage: "Configure acceptance criteria for retrieval deal proposals", + Subcommands: []*cli.Command{ + retrievalDealSelectionShowCmd, + retrievalDealSelectionResetCmd, + retrievalDealSelectionRejectCmd, + }, +} + +var retrievalDealSelectionShowCmd = &cli.Command{ + Name: "list", + Usage: "List retrieval deal proposal selection criteria", Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { return err } defer closer() - return api.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), true) + isAcceptingRetrievalDeals, err := smapi.DealsAcceptingRetrievalDeals(lcli.DaemonContext(cctx)) + if err != nil { + return err + } + + fmt.Printf("offline retrieval deals: %t\n", isAcceptingRetrievalDeals) + fmt.Printf("online retrieval deals: %t\n", isAcceptingRetrievalDeals) + + return nil }, } -var disableRetrievalCmd = &cli.Command{ - Name: "disable", - Usage: "Configure the miner to reject all retrieval deal proposals", - Flags: []cli.Flag{}, +var retrievalDealSelectionResetCmd = &cli.Command{ + Name: "reset", + Usage: "Reset retrieval deal proposal selection criteria to default values", Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { return err } defer closer() - return api.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), false) + err = smapi.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), true) + if err != nil { + return err + } + + return nil + }, +} + +var retrievalDealSelectionRejectCmd = &cli.Command{ + Name: "reject", + Usage: "Configure criteria which necessitate automatic rejection", + Action: func(cctx *cli.Context) error { + smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + err = smapi.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } + + return nil }, } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index b993d1b46..70a35a31a 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -43,7 +43,9 @@ type StorageMinerAPI struct { StorageMgr *sectorstorage.Manager `optional:"true"` *stores.Index + AcceptingStorageDealsConfigFunc dtypes.AcceptingStorageDealsConfigFunc SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc + AcceptingRetrievalDealsConfigFunc dtypes.AcceptingRetrievalDealsConfigFunc SetAcceptingRetrievalDealsConfigFunc dtypes.SetAcceptingRetrievalDealsConfigFunc StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc @@ -225,10 +227,18 @@ func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.Stora return sm.StorageProvider.ListDeals(ctx) } +func (sm *StorageMinerAPI) DealsAcceptingStorageDeals(ctx context.Context) (bool, error) { + return sm.AcceptingStorageDealsConfigFunc() +} + func (sm *StorageMinerAPI) DealsSetAcceptingStorageDeals(ctx context.Context, b bool) error { return sm.SetAcceptingStorageDealsConfigFunc(b) } +func (sm *StorageMinerAPI) DealsAcceptingRetrievalDeals(ctx context.Context) (bool, error) { + return sm.AcceptingRetrievalDealsConfigFunc() +} + func (sm *StorageMinerAPI) DealsSetAcceptingRetrievalDeals(ctx context.Context, b bool) error { return sm.SetAcceptingRetrievalDealsConfigFunc(b) } From e910a045d01f470b434cb7c1484cb97ce1171efe Mon Sep 17 00:00:00 2001 From: laser Date: Fri, 26 Jun 2020 10:50:54 -0700 Subject: [PATCH 278/379] big rename to allow for later introducing the "consider offline" config --- api/api_storage.go | 8 +++--- api/apistruct/struct.go | 32 +++++++++++----------- cmd/lotus-storage-miner/market.go | 6 ++-- cmd/lotus-storage-miner/retrieval-deals.go | 6 ++-- node/builder.go | 8 +++--- node/config/def.go | 12 ++++---- node/impl/storminer.go | 24 ++++++++-------- node/modules/dtypes/miner.go | 30 ++++++++++---------- node/modules/storageminer.go | 20 +++++++------- 9 files changed, 73 insertions(+), 73 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index ab2293142..0202eed6b 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -56,10 +56,10 @@ type StorageMiner interface { DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) - DealsAcceptingStorageDeals(context.Context) (bool, error) - DealsSetAcceptingStorageDeals(context.Context, bool) error - DealsAcceptingRetrievalDeals(context.Context) (bool, error) - DealsSetAcceptingRetrievalDeals(context.Context, bool) error + DealsConsiderOnlineStorageDeals(context.Context) (bool, error) + DealsSetConsiderOnlineStorageDeals(context.Context, bool) error + DealsConsiderOnlineRetrievalDeals(context.Context) (bool, error) + DealsSetConsiderOnlineRetrievalDeals(context.Context, bool) error DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error) DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 4a8a7eb28..b299476ec 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -224,14 +224,14 @@ type StorageMinerStruct struct { StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` - DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` - DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` - DealsAcceptingStorageDeals func(context.Context) (bool, error) `perm:"admin"` - DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsAcceptingRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` - DealsSetAcceptingRetrievalDeals func(context.Context, bool) error `perm:"admin"` - DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` - DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` + DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` + DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"admin"` + DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` + DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"` + DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` + DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -880,20 +880,20 @@ func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.Sto return c.Internal.DealsList(ctx) } -func (c *StorageMinerStruct) DealsAcceptingStorageDeals(ctx context.Context) (bool, error) { - return c.Internal.DealsAcceptingStorageDeals(ctx) +func (c *StorageMinerStruct) DealsConsiderOnlineStorageDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsConsiderOnlineStorageDeals(ctx) } -func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, b bool) error { - return c.Internal.DealsSetAcceptingStorageDeals(ctx, b) +func (c *StorageMinerStruct) DealsSetConsiderOnlineStorageDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetConsiderOnlineStorageDeals(ctx, b) } -func (c *StorageMinerStruct) DealsAcceptingRetrievalDeals(ctx context.Context) (bool, error) { - return c.Internal.DealsAcceptingRetrievalDeals(ctx) +func (c *StorageMinerStruct) DealsConsiderOnlineRetrievalDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsConsiderOnlineRetrievalDeals(ctx) } -func (c *StorageMinerStruct) DealsSetAcceptingRetrievalDeals(ctx context.Context, b bool) error { - return c.Internal.DealsSetAcceptingRetrievalDeals(ctx, b) +func (c *StorageMinerStruct) DealsSetConsiderOnlineRetrievalDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetConsiderOnlineRetrievalDeals(ctx, b) } func (c *StorageMinerStruct) DealsPieceCidBlocklist(ctx context.Context) ([]cid.Cid, error) { diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index c512aad02..d79c3cd91 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -70,7 +70,7 @@ var storageDealSelectionShowCmd = &cli.Command{ } defer closer() - isAcceptingStorageDeals, err := smapi.DealsAcceptingStorageDeals(lcli.DaemonContext(cctx)) + isAcceptingStorageDeals, err := smapi.DealsConsiderOnlineStorageDeals(lcli.DaemonContext(cctx)) if err != nil { return err } @@ -92,7 +92,7 @@ var storageDealSelectionResetCmd = &cli.Command{ } defer closer() - err = smapi.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), true) + err = smapi.DealsSetConsiderOnlineStorageDeals(lcli.DaemonContext(cctx), true) if err != nil { return err } @@ -111,7 +111,7 @@ var storageDealSelectionRejectCmd = &cli.Command{ } defer closer() - err = smapi.DealsSetAcceptingStorageDeals(lcli.DaemonContext(cctx), false) + err = smapi.DealsSetConsiderOnlineStorageDeals(lcli.DaemonContext(cctx), false) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/retrieval-deals.go b/cmd/lotus-storage-miner/retrieval-deals.go index 33045e00b..a572a04e5 100644 --- a/cmd/lotus-storage-miner/retrieval-deals.go +++ b/cmd/lotus-storage-miner/retrieval-deals.go @@ -35,7 +35,7 @@ var retrievalDealSelectionShowCmd = &cli.Command{ } defer closer() - isAcceptingRetrievalDeals, err := smapi.DealsAcceptingRetrievalDeals(lcli.DaemonContext(cctx)) + isAcceptingRetrievalDeals, err := smapi.DealsConsiderOnlineRetrievalDeals(lcli.DaemonContext(cctx)) if err != nil { return err } @@ -57,7 +57,7 @@ var retrievalDealSelectionResetCmd = &cli.Command{ } defer closer() - err = smapi.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), true) + err = smapi.DealsSetConsiderOnlineRetrievalDeals(lcli.DaemonContext(cctx), true) if err != nil { return err } @@ -76,7 +76,7 @@ var retrievalDealSelectionRejectCmd = &cli.Command{ } defer closer() - err = smapi.DealsSetAcceptingRetrievalDeals(lcli.DaemonContext(cctx), false) + err = smapi.DealsSetConsiderOnlineRetrievalDeals(lcli.DaemonContext(cctx), false) if err != nil { return err } diff --git a/node/builder.go b/node/builder.go index 6b987dc28..39af3207e 100644 --- a/node/builder.go +++ b/node/builder.go @@ -313,10 +313,10 @@ func Online() Option { Override(new(gen.WinningPoStProver), storage.NewWinningPoStProver), Override(new(*miner.Miner), modules.SetupBlockProducer), - Override(new(dtypes.AcceptingRetrievalDealsConfigFunc), modules.NewAcceptingRetrievalDealsConfigFunc), - Override(new(dtypes.SetAcceptingRetrievalDealsConfigFunc), modules.NewSetAcceptingRetrievalDealsConfigFunc), - Override(new(dtypes.AcceptingStorageDealsConfigFunc), modules.NewAcceptingStorageDealsConfigFunc), - Override(new(dtypes.SetAcceptingStorageDealsConfigFunc), modules.NewSetAcceptingStorageDealsConfigFunc), + Override(new(dtypes.ConsiderOnlineRetrievalDealsConfigFunc), modules.NewConsiderOnlineRetrievalDealsConfigFunc), + Override(new(dtypes.SetConsiderOnlineRetrievalDealsConfigFunc), modules.NewSetConsiderOnlineRetrievalDealsConfigFunc), + Override(new(dtypes.ConsiderOnlineStorageDealsConfigFunc), modules.NewConsiderOnlineStorageDealsConfigFunc), + Override(new(dtypes.SetConsiderOnlineStorageDealsConfigFunc), modules.NewSetConsideringOnlineStorageDealsFunc), Override(new(dtypes.StorageDealPieceCidBlocklistConfigFunc), modules.NewStorageDealPieceCidBlocklistConfigFunc), Override(new(dtypes.SetStorageDealPieceCidBlocklistConfigFunc), modules.NewSetStorageDealPieceCidBlocklistConfigFunc), ), diff --git a/node/config/def.go b/node/config/def.go index a86f87d24..342e6bca8 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -34,9 +34,9 @@ type StorageMiner struct { } type DealmakingConfig struct { - AcceptingStorageDeals bool - AcceptingRetrievalDeals bool - PieceCidBlocklist []cid.Cid + ConsiderOnlineStorageDeals bool + ConsiderOnlineRetrievalDeals bool + PieceCidBlocklist []cid.Cid } // API contains configs for API endpoint @@ -124,9 +124,9 @@ func DefaultStorageMiner() *StorageMiner { }, Dealmaking: DealmakingConfig{ - AcceptingStorageDeals: true, - AcceptingRetrievalDeals: true, - PieceCidBlocklist: []cid.Cid{}, + ConsiderOnlineStorageDeals: true, + ConsiderOnlineRetrievalDeals: true, + PieceCidBlocklist: []cid.Cid{}, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 70a35a31a..7e4d71330 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -43,10 +43,10 @@ type StorageMinerAPI struct { StorageMgr *sectorstorage.Manager `optional:"true"` *stores.Index - AcceptingStorageDealsConfigFunc dtypes.AcceptingStorageDealsConfigFunc - SetAcceptingStorageDealsConfigFunc dtypes.SetAcceptingStorageDealsConfigFunc - AcceptingRetrievalDealsConfigFunc dtypes.AcceptingRetrievalDealsConfigFunc - SetAcceptingRetrievalDealsConfigFunc dtypes.SetAcceptingRetrievalDealsConfigFunc + ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc + SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc + ConsiderOnlineRetrievalDealsConfigFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc + SetConsiderOnlineRetrievalDealsConfigFunc dtypes.SetConsiderOnlineRetrievalDealsConfigFunc StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc } @@ -227,20 +227,20 @@ func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.Stora return sm.StorageProvider.ListDeals(ctx) } -func (sm *StorageMinerAPI) DealsAcceptingStorageDeals(ctx context.Context) (bool, error) { - return sm.AcceptingStorageDealsConfigFunc() +func (sm *StorageMinerAPI) DealsConsiderOnlineStorageDeals(ctx context.Context) (bool, error) { + return sm.ConsiderOnlineStorageDealsConfigFunc() } -func (sm *StorageMinerAPI) DealsSetAcceptingStorageDeals(ctx context.Context, b bool) error { - return sm.SetAcceptingStorageDealsConfigFunc(b) +func (sm *StorageMinerAPI) DealsSetConsiderOnlineStorageDeals(ctx context.Context, b bool) error { + return sm.SetConsiderOnlineStorageDealsConfigFunc(b) } -func (sm *StorageMinerAPI) DealsAcceptingRetrievalDeals(ctx context.Context) (bool, error) { - return sm.AcceptingRetrievalDealsConfigFunc() +func (sm *StorageMinerAPI) DealsConsiderOnlineRetrievalDeals(ctx context.Context) (bool, error) { + return sm.ConsiderOnlineRetrievalDealsConfigFunc() } -func (sm *StorageMinerAPI) DealsSetAcceptingRetrievalDeals(ctx context.Context, b bool) error { - return sm.SetAcceptingRetrievalDealsConfigFunc(b) +func (sm *StorageMinerAPI) DealsSetConsiderOnlineRetrievalDeals(ctx context.Context, b bool) error { + return sm.SetConsiderOnlineRetrievalDealsConfigFunc(b) } func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fname string) error { diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 9ea8c3440..c6e89a19c 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -10,25 +10,25 @@ import ( type MinerAddress address.Address type MinerID abi.ActorID -// AcceptingStorageDealsConfigFunc is a function which reads from miner config -// to determine if the user has disabled storage deals (or not). -type AcceptingStorageDealsConfigFunc func() (bool, error) +// ConsiderOnlineStorageDealsConfigFunc is a function which reads from miner +// config to determine if the user has disabled storage deals (or not). +type ConsiderOnlineStorageDealsConfigFunc func() (bool, error) -// SetAcceptingStorageDealsConfigFunc is a function which is used to disable or -// enable storage deal acceptance. -type SetAcceptingStorageDealsConfigFunc func(bool) error +// SetConsiderOnlineStorageDealsConfigFunc is a function which is used to +// disable or enable storage deal acceptance. +type SetConsiderOnlineStorageDealsConfigFunc func(bool) error -// AcceptingRetrievalDealsConfigFunc is a function which reads from miner config -// to determine if the user has disabled retrieval acceptance (or not). -type AcceptingRetrievalDealsConfigFunc func() (bool, error) +// ConsiderOnlineRetrievalDealsConfigFunc is a function which reads from miner +// config to determine if the user has disabled retrieval acceptance (or not). +type ConsiderOnlineRetrievalDealsConfigFunc func() (bool, error) -// SetAcceptingRetrievalDealsConfigFunc is a function which is used to disable -// or enable retrieval deal acceptance. -type SetAcceptingRetrievalDealsConfigFunc func(bool) error +// SetConsiderOnlineRetrievalDealsConfigFunc is a function which is used to +// disable or enable retrieval deal acceptance. +type SetConsiderOnlineRetrievalDealsConfigFunc func(bool) error -// StorageDealPieceCidBlocklistConfigFunc is a function which reads from miner config -// to obtain a list of CIDs for which the storage miner will not accept storage -// proposals. +// StorageDealPieceCidBlocklistConfigFunc is a function which reads from miner +// config to obtain a list of CIDs for which the storage miner will not accept +// storage proposals. type StorageDealPieceCidBlocklistConfigFunc func() ([]cid.Cid, error) // SetStorageDealPieceCidBlocklistConfigFunc is a function which is used to set a diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 3ccc5daa7..e1a5472be 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -315,7 +315,7 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return storedAsk, nil } -func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.AcceptingStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc) (storagemarket.StorageProvider, error) { +func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.ConsiderOnlineStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc) (storagemarket.StorageProvider, error) { net := smnet.NewFromLibp2pHost(h) store, err := piecefilestore.NewLocalFileStore(piecefilestore.OsPath(r.Path())) if err != nil { @@ -357,7 +357,7 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con } // RetrievalProvider creates a new retrieval provider attached to the provider blockstore -func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, full lapi.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, ibs dtypes.StagingBlockstore, isAcceptingFunc dtypes.AcceptingRetrievalDealsConfigFunc) (retrievalmarket.RetrievalProvider, error) { +func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, full lapi.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, ibs dtypes.StagingBlockstore, isAcceptingFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc) (retrievalmarket.RetrievalProvider, error) { adapter := retrievaladapter.NewRetrievalProviderNode(miner, sealer, full) maddr, err := minerAddrFromDS(ds) @@ -416,37 +416,37 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA return sectorstorage.StorageAuth(headers), nil } -func NewAcceptingRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.AcceptingRetrievalDealsConfigFunc, error) { +func NewConsiderOnlineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderOnlineRetrievalDealsConfigFunc, error) { return func() (out bool, err error) { err = readCfg(r, func(cfg *config.StorageMiner) { - out = cfg.Dealmaking.AcceptingRetrievalDeals + out = cfg.Dealmaking.ConsiderOnlineRetrievalDeals }) return }, nil } -func NewSetAcceptingRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.SetAcceptingRetrievalDealsConfigFunc, error) { +func NewSetConsiderOnlineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.SetConsiderOnlineRetrievalDealsConfigFunc, error) { return func(b bool) (err error) { err = mutateCfg(r, func(cfg *config.StorageMiner) { - cfg.Dealmaking.AcceptingRetrievalDeals = b + cfg.Dealmaking.ConsiderOnlineRetrievalDeals = b }) return }, nil } -func NewAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.AcceptingStorageDealsConfigFunc, error) { +func NewConsiderOnlineStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderOnlineStorageDealsConfigFunc, error) { return func() (out bool, err error) { err = readCfg(r, func(cfg *config.StorageMiner) { - out = cfg.Dealmaking.AcceptingStorageDeals + out = cfg.Dealmaking.ConsiderOnlineStorageDeals }) return }, nil } -func NewSetAcceptingStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.SetAcceptingStorageDealsConfigFunc, error) { +func NewSetConsideringOnlineStorageDealsFunc(r repo.LockedRepo) (dtypes.SetConsiderOnlineStorageDealsConfigFunc, error) { return func(b bool) (err error) { err = mutateCfg(r, func(cfg *config.StorageMiner) { - cfg.Dealmaking.AcceptingStorageDeals = b + cfg.Dealmaking.ConsiderOnlineStorageDeals = b }) return }, nil From 393a9ca4f2457758cbaef59ceec44f5539786640 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 26 Jun 2020 11:51:45 -0400 Subject: [PATCH 279/379] test: predicates test --- chain/events/state/predicates.go | 18 ++- chain/events/state/predicates_test.go | 176 ++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 chain/events/state/predicates_test.go diff --git a/chain/events/state/predicates.go b/chain/events/state/predicates.go index df1bcde30..014a7ecc3 100644 --- a/chain/events/state/predicates.go +++ b/chain/events/state/predicates.go @@ -17,8 +17,7 @@ import ( type UserData interface{} type ChainApi interface { - ChainHasObj(context.Context, cid.Cid) (bool, error) - ChainReadObj(context.Context, cid.Cid) ([]byte, error) + apibstore.ChainIO StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) } @@ -54,7 +53,7 @@ func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFu type DiffStorageMarketStateFunc func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) -func (sp *StatePredicates) OnStorageMarketActorChanged(addr address.Address, diffStorageMarketState DiffStorageMarketStateFunc) DiffFunc { +func (sp *StatePredicates) OnStorageMarketActorChanged(diffStorageMarketState DiffStorageMarketStateFunc) DiffFunc { return sp.OnActorStateChanged(builtin.StorageMarketActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) { var oldState market.State if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil { @@ -89,9 +88,16 @@ func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) } } +type ChangedDeals map[abi.DealID]DealStateChange + +type DealStateChange struct { + From market.DealState + To market.DealState +} + func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDealStatesFunc { return func(ctx context.Context, oldDealStateRoot *amt.Root, newDealStateRoot *amt.Root) (changed bool, user UserData, err error) { - var changedDeals []abi.DealID + changedDeals := make(ChangedDeals) for _, dealId := range dealIds { var oldDeal, newDeal market.DealState err := oldDealStateRoot.Get(ctx, uint64(dealId), &oldDeal) @@ -103,11 +109,11 @@ func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDeal return false, nil, err } if oldDeal != newDeal { - changedDeals = append(changedDeals, dealId) + changedDeals[dealId] = DealStateChange{oldDeal, newDeal} } } if len(changedDeals) > 0 { - return true, changed, nil + return true, changedDeals, nil } return false, nil, nil } diff --git a/chain/events/state/predicates_test.go b/chain/events/state/predicates_test.go new file mode 100644 index 000000000..190f5bd2a --- /dev/null +++ b/chain/events/state/predicates_test.go @@ -0,0 +1,176 @@ +package state + +import ( + "context" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/ipfs/go-hamt-ipld" + "testing" + + "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + ds "github.com/ipfs/go-datastore" + ds_sync "github.com/ipfs/go-datastore/sync" + bstore "github.com/ipfs/go-ipfs-blockstore" + cbornode "github.com/ipfs/go-ipld-cbor" + "golang.org/x/xerrors" + + "github.com/ipfs/go-cid" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" +) + +var dummyCid cid.Cid + +func init() { + dummyCid, _ = cid.Parse("bafkqaaa") +} + +type mockApi struct { + ts map[types.TipSetKey]*types.Actor + bs bstore.Blockstore +} + +func newMockApi(bs bstore.Blockstore) *mockApi { + return &mockApi{ + bs: bs, + ts: make(map[types.TipSetKey]*types.Actor), + } +} + +func (m mockApi) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { + return m.bs.Has(c) +} + +func (m mockApi) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { + blk, err := m.bs.Get(c) + if err != nil { + return nil, xerrors.Errorf("blockstore get: %w", err) + } + + return blk.RawData(), nil +} + +func (m mockApi) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { + return m.ts[tsk], nil +} + +func (m mockApi) setActor(tsk types.TipSetKey, act *types.Actor) { + m.ts[tsk] = act +} + +func TestPredicates(t *testing.T) { + ctx := context.Background() + + bs := bstore.NewBlockstore(ds_sync.MutexWrap(ds.NewMapDatastore())) + store := cbornode.NewCborStore(bs) + + oldDeals := map[abi.DealID]*market.DealState{ + abi.DealID(1): { + SectorStartEpoch: 1, + LastUpdatedEpoch: 2, + SlashEpoch: 0, + }, + abi.DealID(2): { + SectorStartEpoch: 4, + LastUpdatedEpoch: 5, + SlashEpoch: 0, + }, + } + oldStateC := createMarketState(t, store, oldDeals, ctx) + + newDeals := map[abi.DealID]*market.DealState{ + abi.DealID(1): { + SectorStartEpoch: 1, + LastUpdatedEpoch: 3, + SlashEpoch: 0, + }, + abi.DealID(2): { + SectorStartEpoch: 4, + LastUpdatedEpoch: 6, + SlashEpoch: 6, + }, + } + newStateC := createMarketState(t, store, newDeals, ctx) + + miner, err := address.NewFromString("t00") + require.NoError(t, err) + oldState, err := mockTipset(miner, 1) + require.NoError(t, err) + newState, err := mockTipset(miner, 2) + require.NoError(t, err) + + api := newMockApi(bs) + api.setActor(oldState.Key(), &types.Actor{Head: oldStateC}) + api.setActor(newState.Key(), &types.Actor{Head: newStateC}) + + preds := NewStatePredicates(api) + + dealIds := []abi.DealID{abi.DealID(1), abi.DealID(2)} + diffFn := preds.OnStorageMarketActorChanged(preds.OnDealStateChanged(preds.DealStateChangedForIDs(dealIds))) + + // Diff a state against itself: expect no change + changed, _, err := diffFn(ctx, oldState, oldState) + require.NoError(t, err) + require.False(t, changed) + + // Diff old state against new state + changed, val, err := diffFn(ctx, oldState, newState) + require.NoError(t, err) + require.True(t, changed) + + changedDeals, ok := val.(ChangedDeals) + require.True(t, ok) + require.Len(t, changedDeals, 2) + require.Contains(t, changedDeals, abi.DealID(1)) + require.Contains(t, changedDeals, abi.DealID(2)) + deal1 := changedDeals[abi.DealID(1)] + if deal1.From.LastUpdatedEpoch != 2 || deal1.To.LastUpdatedEpoch != 3 { + t.Fatal("Unexpected change to LastUpdatedEpoch") + } + deal2 := changedDeals[abi.DealID(2)] + if deal2.From.SlashEpoch != 0 || deal2.To.SlashEpoch != 6 { + t.Fatal("Unexpected change to LastUpdatedEpoch") + } +} + +func mockTipset(miner address.Address, timestamp uint64) (*types.TipSet, error) { + return types.NewTipSet([]*types.BlockHeader{{ + Miner: miner, + Height: 5, + ParentStateRoot: dummyCid, + Messages: dummyCid, + ParentMessageReceipts: dummyCid, + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS}, + BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS}, + Timestamp: timestamp, + }}) +} + +func createMarketState(t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState, ctx context.Context) cid.Cid { + rootCid := createAMT(t, store, deals, ctx) + + emptyArrayCid, err := amt.NewAMT(store).Flush(context.TODO()) + require.NoError(t, err) + emptyMap, err := store.Put(context.TODO(), hamt.NewNode(store, hamt.UseTreeBitWidth(5))) + require.NoError(t, err) + state := market.ConstructState(emptyArrayCid, emptyMap, emptyMap) + state.States = rootCid + + stateC, err := store.Put(ctx, state) + require.NoError(t, err) + return stateC +} + +func createAMT(t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState, ctx context.Context) cid.Cid { + root := amt.NewAMT(store) + for dealId, dealState := range deals { + err := root.Set(ctx, uint64(dealId), dealState) + require.NoError(t, err) + } + rootCid, err := root.Flush(ctx) + require.NoError(t, err) + return rootCid +} From a1b009328dea6ed79797d3b88adce292a2943c1b Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 26 Jun 2020 14:43:46 -0400 Subject: [PATCH 280/379] refactor: simplify diff --- chain/events/{events_hc.go => events_called.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename chain/events/{events_hc.go => events_called.go} (100%) diff --git a/chain/events/events_hc.go b/chain/events/events_called.go similarity index 100% rename from chain/events/events_hc.go rename to chain/events/events_called.go From db1773d70804bc4ec5c14fe36a4ac359bfba12f7 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 26 Jun 2020 14:59:23 -0400 Subject: [PATCH 281/379] docs: add predicate docs --- chain/events/events_called.go | 2 +- chain/events/state/predicates.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 01f5fdfcc..1306b26ec 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -306,7 +306,7 @@ func (e *hcEvents) onHeadChanged(check CheckFunc, hnd EventHandler, rev RevertHa e.lk.Lock() defer e.lk.Unlock() - // Check if the even has already occurred + // Check if the event has already occurred ts := e.tsc.best() done, more, err := check(ts) if err != nil { diff --git a/chain/events/state/predicates.go b/chain/events/state/predicates.go index 014a7ecc3..21d43adab 100644 --- a/chain/events/state/predicates.go +++ b/chain/events/state/predicates.go @@ -14,13 +14,16 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/market" ) +// Data returned from the DiffFunc type UserData interface{} +// The calls made by this class external APIs type ChainApi interface { apibstore.ChainIO StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) } +// Use StatePredicates to respond to state changes type StatePredicates struct { api ChainApi cst *cbor.BasicIpldStore @@ -33,10 +36,15 @@ func NewStatePredicates(api ChainApi) *StatePredicates { } } +// Check if there's a change form oldState to newState, and return +// - changed: was there a change +// - user: user-defined data representing the state change +// - err type DiffFunc func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) type DiffStateFunc func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) +// Calls diffStateFunc when the state changes for the given actor func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFunc DiffStateFunc) DiffFunc { return func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) { oldActor, err := sp.api.StateGetActor(ctx, addr, oldState.Key()) @@ -53,6 +61,7 @@ func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFu type DiffStorageMarketStateFunc func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) +// Calls diffStorageMarketState when the state changes for the market actor func (sp *StatePredicates) OnStorageMarketActorChanged(diffStorageMarketState DiffStorageMarketStateFunc) DiffFunc { return sp.OnActorStateChanged(builtin.StorageMarketActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) { var oldState market.State @@ -69,6 +78,7 @@ func (sp *StatePredicates) OnStorageMarketActorChanged(diffStorageMarketState Di type DiffDealStatesFunc func(ctx context.Context, oldDealStateRoot *amt.Root, newDealStateRoot *amt.Root) (changed bool, user UserData, err error) +// Calls diffDealStates when the market state changes func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) DiffStorageMarketStateFunc { return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) { if oldState.States.Equals(newState.States) { @@ -88,13 +98,16 @@ func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) } } +// A set of changes to deal state type ChangedDeals map[abi.DealID]DealStateChange +// Change in deal state from -> to type DealStateChange struct { From market.DealState To market.DealState } +// Detect changes in the deal state AMT for the given deal IDs func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDealStatesFunc { return func(ctx context.Context, oldDealStateRoot *amt.Root, newDealStateRoot *amt.Root) (changed bool, user UserData, err error) { changedDeals := make(ChangedDeals) From b9180a99d4805239aa281329e31414f39435d8e8 Mon Sep 17 00:00:00 2001 From: laser Date: Fri, 26 Jun 2020 12:27:41 -0700 Subject: [PATCH 282/379] toggle consideration of offline storage/retrieval deal proposals --- api/api_storage.go | 4 + api/apistruct/struct.go | 36 +++++-- cmd/lotus-storage-miner/market.go | 39 ++++++-- cmd/lotus-storage-miner/retrieval-deals.go | 39 ++++++-- node/builder.go | 8 +- node/config/def.go | 16 +-- node/impl/storminer.go | 32 ++++-- node/modules/dtypes/miner.go | 16 +++ node/modules/storageminer.go | 109 ++++++++++++++++----- 9 files changed, 238 insertions(+), 61 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 0202eed6b..dfb536580 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -62,6 +62,10 @@ type StorageMiner interface { DealsSetConsiderOnlineRetrievalDeals(context.Context, bool) error DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error) DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error + DealsConsiderOfflineStorageDeals(context.Context) (bool, error) + DealsSetConsiderOfflineStorageDeals(context.Context, bool) error + DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error) + DealsSetConsiderOfflineRetrievalDeals(context.Context, bool) error StorageAddLocal(ctx context.Context, path string) error } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index b299476ec..3555e9cca 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -224,14 +224,18 @@ type StorageMinerStruct struct { StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"` StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"` - DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` - DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` - DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"admin"` - DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` - DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"` - DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` - DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` + DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` + DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` + DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"admin"` + DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` + DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderOfflineStorageDeals func(context.Context) (bool, error) `perm:"admin"` + DealsSetConsiderOfflineStorageDeals func(context.Context, bool) error `perm:"admin"` + DealsConsiderOfflineRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` + DealsSetConsiderOfflineRetrievalDeals func(context.Context, bool) error `perm:"admin"` + DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` + DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } @@ -904,6 +908,22 @@ func (c *StorageMinerStruct) DealsSetPieceCidBlocklist(ctx context.Context, cids return c.Internal.DealsSetPieceCidBlocklist(ctx, cids) } +func (c *StorageMinerStruct) DealsConsiderOfflineStorageDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsConsiderOfflineStorageDeals(ctx) +} + +func (c *StorageMinerStruct) DealsSetConsiderOfflineStorageDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetConsiderOfflineStorageDeals(ctx, b) +} + +func (c *StorageMinerStruct) DealsConsiderOfflineRetrievalDeals(ctx context.Context) (bool, error) { + return c.Internal.DealsConsiderOfflineRetrievalDeals(ctx) +} + +func (c *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(ctx context.Context, b bool) error { + return c.Internal.DealsSetConsiderOfflineRetrievalDeals(ctx, b) +} + func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error { return c.Internal.StorageAddLocal(ctx, path) } diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index d79c3cd91..6809cc733 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -70,13 +70,18 @@ var storageDealSelectionShowCmd = &cli.Command{ } defer closer() - isAcceptingStorageDeals, err := smapi.DealsConsiderOnlineStorageDeals(lcli.DaemonContext(cctx)) + onlineOk, err := smapi.DealsConsiderOnlineStorageDeals(lcli.DaemonContext(cctx)) if err != nil { return err } - fmt.Printf("offline storage deals: %t\n", isAcceptingStorageDeals) - fmt.Printf("online storage deals: %t\n", isAcceptingStorageDeals) + offlineOk, err := smapi.DealsConsiderOfflineStorageDeals(lcli.DaemonContext(cctx)) + if err != nil { + return err + } + + fmt.Printf("considering online storage deals: %t\n", onlineOk) + fmt.Printf("considering offline storage deals: %t\n", offlineOk) return nil }, @@ -97,6 +102,11 @@ var storageDealSelectionResetCmd = &cli.Command{ return err } + err = smapi.DealsSetConsiderOfflineStorageDeals(lcli.DaemonContext(cctx), true) + if err != nil { + return err + } + return nil }, } @@ -104,6 +114,14 @@ var storageDealSelectionResetCmd = &cli.Command{ var storageDealSelectionRejectCmd = &cli.Command{ Name: "reject", Usage: "Configure criteria which necessitate automatic rejection", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "online", + }, + &cli.BoolFlag{ + Name: "offline", + }, + }, Action: func(cctx *cli.Context) error { smapi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { @@ -111,9 +129,18 @@ var storageDealSelectionRejectCmd = &cli.Command{ } defer closer() - err = smapi.DealsSetConsiderOnlineStorageDeals(lcli.DaemonContext(cctx), false) - if err != nil { - return err + if cctx.Bool("online") { + err = smapi.DealsSetConsiderOnlineStorageDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } + } + + if cctx.Bool("offline") { + err = smapi.DealsSetConsiderOfflineStorageDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } } return nil diff --git a/cmd/lotus-storage-miner/retrieval-deals.go b/cmd/lotus-storage-miner/retrieval-deals.go index a572a04e5..942e30dff 100644 --- a/cmd/lotus-storage-miner/retrieval-deals.go +++ b/cmd/lotus-storage-miner/retrieval-deals.go @@ -35,13 +35,18 @@ var retrievalDealSelectionShowCmd = &cli.Command{ } defer closer() - isAcceptingRetrievalDeals, err := smapi.DealsConsiderOnlineRetrievalDeals(lcli.DaemonContext(cctx)) + onlineOk, err := smapi.DealsConsiderOnlineRetrievalDeals(lcli.DaemonContext(cctx)) if err != nil { return err } - fmt.Printf("offline retrieval deals: %t\n", isAcceptingRetrievalDeals) - fmt.Printf("online retrieval deals: %t\n", isAcceptingRetrievalDeals) + offlineOk, err := smapi.DealsConsiderOfflineRetrievalDeals(lcli.DaemonContext(cctx)) + if err != nil { + return err + } + + fmt.Printf("considering online retrieval deals: %t\n", onlineOk) + fmt.Printf("considering offline retrieval deals: %t\n", offlineOk) return nil }, @@ -62,6 +67,11 @@ var retrievalDealSelectionResetCmd = &cli.Command{ return err } + err = smapi.DealsSetConsiderOfflineRetrievalDeals(lcli.DaemonContext(cctx), true) + if err != nil { + return err + } + return nil }, } @@ -69,6 +79,14 @@ var retrievalDealSelectionResetCmd = &cli.Command{ var retrievalDealSelectionRejectCmd = &cli.Command{ Name: "reject", Usage: "Configure criteria which necessitate automatic rejection", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "online", + }, + &cli.BoolFlag{ + Name: "offline", + }, + }, Action: func(cctx *cli.Context) error { smapi, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { @@ -76,9 +94,18 @@ var retrievalDealSelectionRejectCmd = &cli.Command{ } defer closer() - err = smapi.DealsSetConsiderOnlineRetrievalDeals(lcli.DaemonContext(cctx), false) - if err != nil { - return err + if cctx.Bool("online") { + err = smapi.DealsSetConsiderOnlineRetrievalDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } + } + + if cctx.Bool("offline") { + err = smapi.DealsSetConsiderOfflineRetrievalDeals(lcli.DaemonContext(cctx), false) + if err != nil { + return err + } } return nil diff --git a/node/builder.go b/node/builder.go index 39af3207e..2ffe88921 100644 --- a/node/builder.go +++ b/node/builder.go @@ -313,12 +313,16 @@ func Online() Option { Override(new(gen.WinningPoStProver), storage.NewWinningPoStProver), Override(new(*miner.Miner), modules.SetupBlockProducer), - Override(new(dtypes.ConsiderOnlineRetrievalDealsConfigFunc), modules.NewConsiderOnlineRetrievalDealsConfigFunc), - Override(new(dtypes.SetConsiderOnlineRetrievalDealsConfigFunc), modules.NewSetConsiderOnlineRetrievalDealsConfigFunc), Override(new(dtypes.ConsiderOnlineStorageDealsConfigFunc), modules.NewConsiderOnlineStorageDealsConfigFunc), Override(new(dtypes.SetConsiderOnlineStorageDealsConfigFunc), modules.NewSetConsideringOnlineStorageDealsFunc), + Override(new(dtypes.ConsiderOnlineRetrievalDealsConfigFunc), modules.NewConsiderOnlineRetrievalDealsConfigFunc), + Override(new(dtypes.SetConsiderOnlineRetrievalDealsConfigFunc), modules.NewSetConsiderOnlineRetrievalDealsConfigFunc), Override(new(dtypes.StorageDealPieceCidBlocklistConfigFunc), modules.NewStorageDealPieceCidBlocklistConfigFunc), Override(new(dtypes.SetStorageDealPieceCidBlocklistConfigFunc), modules.NewSetStorageDealPieceCidBlocklistConfigFunc), + Override(new(dtypes.ConsiderOfflineStorageDealsConfigFunc), modules.NewConsiderOfflineStorageDealsConfigFunc), + Override(new(dtypes.SetConsiderOfflineStorageDealsConfigFunc), modules.NewSetConsideringOfflineStorageDealsFunc), + Override(new(dtypes.ConsiderOfflineRetrievalDealsConfigFunc), modules.NewConsiderOfflineRetrievalDealsConfigFunc), + Override(new(dtypes.SetConsiderOfflineRetrievalDealsConfigFunc), modules.NewSetConsiderOfflineRetrievalDealsConfigFunc), ), ) } diff --git a/node/config/def.go b/node/config/def.go index 342e6bca8..dd80d4f75 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -34,9 +34,11 @@ type StorageMiner struct { } type DealmakingConfig struct { - ConsiderOnlineStorageDeals bool - ConsiderOnlineRetrievalDeals bool - PieceCidBlocklist []cid.Cid + ConsiderOnlineStorageDeals bool + ConsiderOfflineStorageDeals bool + ConsiderOnlineRetrievalDeals bool + ConsiderOfflineRetrievalDeals bool + PieceCidBlocklist []cid.Cid } // API contains configs for API endpoint @@ -124,9 +126,11 @@ func DefaultStorageMiner() *StorageMiner { }, Dealmaking: DealmakingConfig{ - ConsiderOnlineStorageDeals: true, - ConsiderOnlineRetrievalDeals: true, - PieceCidBlocklist: []cid.Cid{}, + ConsiderOnlineStorageDeals: true, + ConsiderOfflineStorageDeals: true, + ConsiderOnlineRetrievalDeals: true, + ConsiderOfflineRetrievalDeals: true, + PieceCidBlocklist: []cid.Cid{}, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 7e4d71330..cf9b84388 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -43,12 +43,16 @@ type StorageMinerAPI struct { StorageMgr *sectorstorage.Manager `optional:"true"` *stores.Index - ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc - SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc - ConsiderOnlineRetrievalDealsConfigFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc - SetConsiderOnlineRetrievalDealsConfigFunc dtypes.SetConsiderOnlineRetrievalDealsConfigFunc - StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc - SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc + ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc + SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc + ConsiderOnlineRetrievalDealsConfigFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc + SetConsiderOnlineRetrievalDealsConfigFunc dtypes.SetConsiderOnlineRetrievalDealsConfigFunc + StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc + SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc + ConsiderOfflineStorageDealsConfigFunc dtypes.ConsiderOfflineStorageDealsConfigFunc + SetConsiderOfflineStorageDealsConfigFunc dtypes.SetConsiderOfflineStorageDealsConfigFunc + ConsiderOfflineRetrievalDealsConfigFunc dtypes.ConsiderOfflineRetrievalDealsConfigFunc + SetConsiderOfflineRetrievalDealsConfigFunc dtypes.SetConsiderOfflineRetrievalDealsConfigFunc } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { @@ -243,6 +247,22 @@ func (sm *StorageMinerAPI) DealsSetConsiderOnlineRetrievalDeals(ctx context.Cont return sm.SetConsiderOnlineRetrievalDealsConfigFunc(b) } +func (sm *StorageMinerAPI) DealsConsiderOfflineStorageDeals(ctx context.Context) (bool, error) { + return sm.ConsiderOfflineStorageDealsConfigFunc() +} + +func (sm *StorageMinerAPI) DealsSetConsiderOfflineStorageDeals(ctx context.Context, b bool) error { + return sm.SetConsiderOfflineStorageDealsConfigFunc(b) +} + +func (sm *StorageMinerAPI) DealsConsiderOfflineRetrievalDeals(ctx context.Context) (bool, error) { + return sm.ConsiderOfflineRetrievalDealsConfigFunc() +} + +func (sm *StorageMinerAPI) DealsSetConsiderOfflineRetrievalDeals(ctx context.Context, b bool) error { + return sm.SetConsiderOfflineRetrievalDealsConfigFunc(b) +} + func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fname string) error { fi, err := os.Open(fname) if err != nil { diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index c6e89a19c..33c6e4b04 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -34,3 +34,19 @@ type StorageDealPieceCidBlocklistConfigFunc func() ([]cid.Cid, error) // SetStorageDealPieceCidBlocklistConfigFunc is a function which is used to set a // list of CIDs for which the storage miner will reject deal proposals. type SetStorageDealPieceCidBlocklistConfigFunc func([]cid.Cid) error + +// ConsiderOfflineStorageDealsConfigFunc is a function which reads from miner +// config to determine if the user has disabled storage deals (or not). +type ConsiderOfflineStorageDealsConfigFunc func() (bool, error) + +// SetConsiderOfflineStorageDealsConfigFunc is a function which is used to +// disable or enable storage deal acceptance. +type SetConsiderOfflineStorageDealsConfigFunc func(bool) error + +// ConsiderOfflineRetrievalDealsConfigFunc is a function which reads from miner +// config to determine if the user has disabled retrieval acceptance (or not). +type ConsiderOfflineRetrievalDealsConfigFunc func() (bool, error) + +// SetConsiderOfflineRetrievalDealsConfigFunc is a function which is used to +// disable or enable retrieval deal acceptance. +type SetConsiderOfflineRetrievalDealsConfigFunc func(bool) error diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index e1a5472be..99d95f77a 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -315,7 +315,7 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat return storedAsk, nil } -func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, isAcceptingFunc dtypes.ConsiderOnlineStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc) (storagemarket.StorageProvider, error) { +func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Config, storedAsk *storedask.StoredAsk, h host.Host, ds dtypes.MetadataDS, ibs dtypes.StagingBlockstore, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, dataTransfer dtypes.ProviderDataTransfer, spn storagemarket.StorageProviderNode, onlineOk dtypes.ConsiderOnlineStorageDealsConfigFunc, offlineOk dtypes.ConsiderOfflineStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc) (storagemarket.StorageProvider, error) { net := smnet.NewFromLibp2pHost(h) store, err := piecefilestore.NewLocalFileStore(piecefilestore.OsPath(r.Path())) if err != nil { @@ -323,14 +323,24 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con } opt := storageimpl.CustomDealDecisionLogic(func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) { - b, err := isAcceptingFunc() + b, err := onlineOk() if err != nil { return false, "miner error", err } - if !b { - log.Warnf("storage deal acceptance disabled; rejecting storage deal proposal from client: %s", deal.Client.String()) - return false, "miner is not accepting storage deals", nil + if deal.Ref != nil && deal.Ref.TransferType != storagemarket.TTManual && !b { + log.Warnf("online storage deal consideration disabled; rejecting storage deal proposal from client: %s", deal.Client.String()) + return false, "miner is not considering online storage deals", nil + } + + b, err = offlineOk() + if err != nil { + return false, "miner error", err + } + + if deal.Ref != nil && deal.Ref.TransferType == storagemarket.TTManual && !b { + log.Warnf("offline storage deal consideration disabled; rejecting storage deal proposal from client: %s", deal.Client.String()) + return false, "miner is not accepting offline storage deals", nil } blocklist, err := blocklistFunc() @@ -357,7 +367,7 @@ func StorageProvider(minerAddress dtypes.MinerAddress, ffiConfig *ffiwrapper.Con } // RetrievalProvider creates a new retrieval provider attached to the provider blockstore -func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, full lapi.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, ibs dtypes.StagingBlockstore, isAcceptingFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc) (retrievalmarket.RetrievalProvider, error) { +func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, full lapi.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, ibs dtypes.StagingBlockstore, onlineOk dtypes.ConsiderOnlineRetrievalDealsConfigFunc, offlineOk dtypes.ConsiderOfflineRetrievalDealsConfigFunc) (retrievalmarket.RetrievalProvider, error) { adapter := retrievaladapter.NewRetrievalProviderNode(miner, sealer, full) maddr, err := minerAddrFromDS(ds) @@ -368,14 +378,23 @@ func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.S netwk := rmnet.NewFromLibp2pHost(h) opt := retrievalimpl.DealDeciderOpt(func(ctx context.Context, state retrievalmarket.ProviderDealState) (bool, string, error) { - b, err := isAcceptingFunc() + b, err := onlineOk() if err != nil { return false, "miner error", err } if !b { - log.Warn("retrieval deal acceptance disabled; rejecting retrieval deal proposal from client") - return false, "miner is not accepting retrieval deals", nil + log.Warn("online retrieval deal consideration disabled; rejecting retrieval deal proposal from client") + return false, "miner is not accepting online retrieval deals", nil + } + + b, err = offlineOk() + if err != nil { + return false, "miner error", err + } + + if !b { + log.Info("offline retrieval has not been implemented yet") } return true, "", nil @@ -416,24 +435,6 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA return sectorstorage.StorageAuth(headers), nil } -func NewConsiderOnlineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderOnlineRetrievalDealsConfigFunc, error) { - return func() (out bool, err error) { - err = readCfg(r, func(cfg *config.StorageMiner) { - out = cfg.Dealmaking.ConsiderOnlineRetrievalDeals - }) - return - }, nil -} - -func NewSetConsiderOnlineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.SetConsiderOnlineRetrievalDealsConfigFunc, error) { - return func(b bool) (err error) { - err = mutateCfg(r, func(cfg *config.StorageMiner) { - cfg.Dealmaking.ConsiderOnlineRetrievalDeals = b - }) - return - }, nil -} - func NewConsiderOnlineStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderOnlineStorageDealsConfigFunc, error) { return func() (out bool, err error) { err = readCfg(r, func(cfg *config.StorageMiner) { @@ -452,6 +453,24 @@ func NewSetConsideringOnlineStorageDealsFunc(r repo.LockedRepo) (dtypes.SetConsi }, nil } +func NewConsiderOnlineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderOnlineRetrievalDealsConfigFunc, error) { + return func() (out bool, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.ConsiderOnlineRetrievalDeals + }) + return + }, nil +} + +func NewSetConsiderOnlineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.SetConsiderOnlineRetrievalDealsConfigFunc, error) { + return func(b bool) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.ConsiderOnlineRetrievalDeals = b + }) + return + }, nil +} + func NewStorageDealPieceCidBlocklistConfigFunc(r repo.LockedRepo) (dtypes.StorageDealPieceCidBlocklistConfigFunc, error) { return func() (out []cid.Cid, err error) { err = readCfg(r, func(cfg *config.StorageMiner) { @@ -470,6 +489,42 @@ func NewSetStorageDealPieceCidBlocklistConfigFunc(r repo.LockedRepo) (dtypes.Set }, nil } +func NewConsiderOfflineStorageDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderOfflineStorageDealsConfigFunc, error) { + return func() (out bool, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.ConsiderOfflineStorageDeals + }) + return + }, nil +} + +func NewSetConsideringOfflineStorageDealsFunc(r repo.LockedRepo) (dtypes.SetConsiderOfflineStorageDealsConfigFunc, error) { + return func(b bool) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.ConsiderOfflineStorageDeals = b + }) + return + }, nil +} + +func NewConsiderOfflineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.ConsiderOfflineRetrievalDealsConfigFunc, error) { + return func() (out bool, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = cfg.Dealmaking.ConsiderOfflineRetrievalDeals + }) + return + }, nil +} + +func NewSetConsiderOfflineRetrievalDealsConfigFunc(r repo.LockedRepo) (dtypes.SetConsiderOfflineRetrievalDealsConfigFunc, error) { + return func(b bool) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.ConsiderOfflineRetrievalDeals = b + }) + return + }, nil +} + func readCfg(r repo.LockedRepo, accessor func(*config.StorageMiner)) error { raw, err := r.Config() if err != nil { From 5052a87a8299ba0c33c1ec7d891c48ed7240f82d Mon Sep 17 00:00:00 2001 From: laser Date: Fri, 26 Jun 2020 12:33:39 -0700 Subject: [PATCH 283/379] bugfix: accessors should be `read` and writers should be `admin` --- api/apistruct/struct.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 3555e9cca..a031dc38b 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -226,16 +226,16 @@ type StorageMinerStruct struct { DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"` - DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"admin"` + DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"` DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` + DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"` DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"` - DealsConsiderOfflineStorageDeals func(context.Context) (bool, error) `perm:"admin"` + DealsConsiderOfflineStorageDeals func(context.Context) (bool, error) `perm:"read"` DealsSetConsiderOfflineStorageDeals func(context.Context, bool) error `perm:"admin"` - DealsConsiderOfflineRetrievalDeals func(context.Context) (bool, error) `perm:"admin"` + DealsConsiderOfflineRetrievalDeals func(context.Context) (bool, error) `perm:"read"` DealsSetConsiderOfflineRetrievalDeals func(context.Context, bool) error `perm:"admin"` - DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"admin"` - DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"read"` + DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"read"` + DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"admin"` StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"` } From bbb9a9cd1aa9e83a5a5ead62f9004ff79dd8b89c Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 26 Jun 2020 15:36:48 -0400 Subject: [PATCH 284/379] refactor: lint fixes --- chain/events/events.go | 2 +- chain/events/events_called.go | 24 +++++++------- chain/events/events_test.go | 2 +- chain/events/state/predicates.go | 46 +++++++++++++++------------ chain/events/state/predicates_test.go | 33 +++++++++---------- 5 files changed, 56 insertions(+), 51 deletions(-) diff --git a/chain/events/events.go b/chain/events/events.go index 408c8845e..c1ef07a4e 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -74,7 +74,7 @@ func NewEvents(ctx context.Context, api eventAPI) *Events { htHeights: map[abi.ChainEpoch][]uint64{}, }, - hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)), + hcEvents: *newHCEvents(ctx, api, tsc, uint64(gcConfidence)), } e.ready.Add(1) diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 1306b26ec..3d8e05c02 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -93,7 +93,7 @@ type hcEvents struct { watcherEvents } -func newHCEvents(ctx context.Context, cs eventAPI, tsc *tipSetCache, gcConfidence uint64) hcEvents { +func newHCEvents(ctx context.Context, cs eventAPI, tsc *tipSetCache, gcConfidence uint64) *hcEvents { e := hcEvents{ ctx: ctx, cs: cs, @@ -109,7 +109,7 @@ func newHCEvents(ctx context.Context, cs eventAPI, tsc *tipSetCache, gcConfidenc e.messageEvents = newMessageEvents(ctx, &e, cs) e.watcherEvents = newWatcherEvents(ctx, &e, cs) - return e + return &e } // Called when there is a change to the head with tipsets to be @@ -297,7 +297,7 @@ func (e *hcEvents) applyTimeouts(ts *types.TipSet) { } // Listen for an event -// - CheckFunc: immediately checks if the event already occured +// - CheckFunc: immediately checks if the event already occurred // - EventHandler: called when the event has occurred, after confidence tipsets // - RevertHandler: called if the chain head changes causing the event to revert // - confidence: wait this many tipsets before calling EventHandler @@ -351,17 +351,17 @@ type headChangeAPI interface { type watcherEvents struct { ctx context.Context cs eventAPI - hcApi headChangeAPI + hcAPI headChangeAPI lk sync.RWMutex matchers map[triggerID]StateMatchFunc } -func newWatcherEvents(ctx context.Context, hcApi headChangeAPI, cs eventAPI) watcherEvents { +func newWatcherEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) watcherEvents { return watcherEvents{ ctx: ctx, cs: cs, - hcApi: hcApi, + hcAPI: hcAPI, matchers: make(map[triggerID]StateMatchFunc), } } @@ -387,7 +387,7 @@ func (we *watcherEvents) checkStateChanges(oldState, newState *types.TipSet) map return res } -// A change in state +// StateChange represents a change in state type StateChange interface{} // StateChangeHandler arguments: @@ -437,7 +437,7 @@ func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, return scHnd(prevTs, ts, states, height) } - id, err := we.hcApi.onHeadChanged(check, hnd, rev, confidence, timeout) + id, err := we.hcAPI.onHeadChanged(check, hnd, rev, confidence, timeout) if err != nil { return err } @@ -453,17 +453,17 @@ func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, type messageEvents struct { ctx context.Context cs eventAPI - hcApi headChangeAPI + hcAPI headChangeAPI lk sync.RWMutex matchers map[triggerID][]MsgMatchFunc } -func newMessageEvents(ctx context.Context, hcApi headChangeAPI, cs eventAPI) messageEvents { +func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) messageEvents { return messageEvents{ ctx: ctx, cs: cs, - hcApi: hcApi, + hcAPI: hcAPI, matchers: map[triggerID][]MsgMatchFunc{}, } } @@ -592,7 +592,7 @@ func (me *messageEvents) Called(check CheckFunc, msgHnd MsgHandler, rev RevertHa return msgHnd(msg, rec, ts, height) } - id, err := me.hcApi.onHeadChanged(check, hnd, rev, confidence, timeout) + id, err := me.hcAPI.onHeadChanged(check, hnd, rev, confidence, timeout) if err != nil { return err } diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 2bb5b0916..5798fb75c 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -1068,7 +1068,7 @@ func TestRemoveTriggersOnMessage(t *testing.T) { type testStateChange struct { from string - to string + to string } func TestStateChanged(t *testing.T) { diff --git a/chain/events/state/predicates.go b/chain/events/state/predicates.go index 21d43adab..3245d5c03 100644 --- a/chain/events/state/predicates.go +++ b/chain/events/state/predicates.go @@ -2,41 +2,41 @@ package state import ( "context" - cbor "github.com/ipfs/go-ipld-cbor" - "github.com/ipfs/go-cid" - "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" ) -// Data returned from the DiffFunc +// UserData is the data returned from the DiffFunc type UserData interface{} -// The calls made by this class external APIs -type ChainApi interface { +// ChainAPI abstracts out calls made by this class to external APIs +type ChainAPI interface { apibstore.ChainIO StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) } -// Use StatePredicates to respond to state changes +// StatePredicates has common predicates for responding to state changes type StatePredicates struct { - api ChainApi + api ChainAPI cst *cbor.BasicIpldStore } -func NewStatePredicates(api ChainApi) *StatePredicates { +func NewStatePredicates(api ChainAPI) *StatePredicates { return &StatePredicates{ api: api, cst: cbor.NewCborStore(apibstore.NewAPIBlockstore(api)), } } -// Check if there's a change form oldState to newState, and return +// DiffFunc check if there's a change form oldState to newState, and returns // - changed: was there a change // - user: user-defined data representing the state change // - err @@ -44,7 +44,7 @@ type DiffFunc func(ctx context.Context, oldState, newState *types.TipSet) (chang type DiffStateFunc func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) -// Calls diffStateFunc when the state changes for the given actor +// OnActorStateChanged calls diffStateFunc when the state changes for the given actor func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFunc DiffStateFunc) DiffFunc { return func(ctx context.Context, oldState, newState *types.TipSet) (changed bool, user UserData, err error) { oldActor, err := sp.api.StateGetActor(ctx, addr, oldState.Key()) @@ -52,6 +52,10 @@ func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFu return false, nil, err } newActor, err := sp.api.StateGetActor(ctx, addr, newState.Key()) + if err != nil { + return false, nil, err + } + if oldActor.Head.Equals(newActor.Head) { return false, nil, nil } @@ -61,7 +65,7 @@ func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFu type DiffStorageMarketStateFunc func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) -// Calls diffStorageMarketState when the state changes for the market actor +// OnStorageMarketActorChanged calls diffStorageMarketState when the state changes for the market actor func (sp *StatePredicates) OnStorageMarketActorChanged(diffStorageMarketState DiffStorageMarketStateFunc) DiffFunc { return sp.OnActorStateChanged(builtin.StorageMarketActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) { var oldState market.State @@ -78,7 +82,7 @@ func (sp *StatePredicates) OnStorageMarketActorChanged(diffStorageMarketState Di type DiffDealStatesFunc func(ctx context.Context, oldDealStateRoot *amt.Root, newDealStateRoot *amt.Root) (changed bool, user UserData, err error) -// Calls diffDealStates when the market state changes +// OnDealStateChanged calls diffDealStates when the market state changes func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) DiffStorageMarketStateFunc { return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) { if oldState.States.Equals(newState.States) { @@ -98,31 +102,31 @@ func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) } } -// A set of changes to deal state +// ChangedDeals is a set of changes to deal state type ChangedDeals map[abi.DealID]DealStateChange -// Change in deal state from -> to +// DealStateChange is a change in deal state from -> to type DealStateChange struct { From market.DealState - To market.DealState + To market.DealState } -// Detect changes in the deal state AMT for the given deal IDs +// DealStateChangedForIDs detects changes in the deal state AMT for the given deal IDs func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDealStatesFunc { return func(ctx context.Context, oldDealStateRoot *amt.Root, newDealStateRoot *amt.Root) (changed bool, user UserData, err error) { changedDeals := make(ChangedDeals) - for _, dealId := range dealIds { + for _, dealID := range dealIds { var oldDeal, newDeal market.DealState - err := oldDealStateRoot.Get(ctx, uint64(dealId), &oldDeal) + err := oldDealStateRoot.Get(ctx, uint64(dealID), &oldDeal) if err != nil { return false, nil, err } - err = newDealStateRoot.Get(ctx, uint64(dealId), &newDeal) + err = newDealStateRoot.Get(ctx, uint64(dealID), &newDeal) if err != nil { return false, nil, err } if oldDeal != newDeal { - changedDeals[dealId] = DealStateChange{oldDeal, newDeal} + changedDeals[dealID] = DealStateChange{oldDeal, newDeal} } } if len(changedDeals) > 0 { diff --git a/chain/events/state/predicates_test.go b/chain/events/state/predicates_test.go index 190f5bd2a..1c10209a8 100644 --- a/chain/events/state/predicates_test.go +++ b/chain/events/state/predicates_test.go @@ -2,9 +2,10 @@ package state import ( "context" + "testing" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/ipfs/go-hamt-ipld" - "testing" "github.com/filecoin-project/go-amt-ipld/v2" "github.com/filecoin-project/specs-actors/actors/builtin/market" @@ -28,23 +29,23 @@ func init() { dummyCid, _ = cid.Parse("bafkqaaa") } -type mockApi struct { +type mockAPI struct { ts map[types.TipSetKey]*types.Actor bs bstore.Blockstore } -func newMockApi(bs bstore.Blockstore) *mockApi { - return &mockApi{ +func newMockAPI(bs bstore.Blockstore) *mockAPI { + return &mockAPI{ bs: bs, ts: make(map[types.TipSetKey]*types.Actor), } } -func (m mockApi) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { +func (m mockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { return m.bs.Has(c) } -func (m mockApi) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { +func (m mockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { blk, err := m.bs.Get(c) if err != nil { return nil, xerrors.Errorf("blockstore get: %w", err) @@ -53,11 +54,11 @@ func (m mockApi) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { return blk.RawData(), nil } -func (m mockApi) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { +func (m mockAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { return m.ts[tsk], nil } -func (m mockApi) setActor(tsk types.TipSetKey, act *types.Actor) { +func (m mockAPI) setActor(tsk types.TipSetKey, act *types.Actor) { m.ts[tsk] = act } @@ -79,7 +80,7 @@ func TestPredicates(t *testing.T) { SlashEpoch: 0, }, } - oldStateC := createMarketState(t, store, oldDeals, ctx) + oldStateC := createMarketState(ctx, t, store, oldDeals) newDeals := map[abi.DealID]*market.DealState{ abi.DealID(1): { @@ -93,7 +94,7 @@ func TestPredicates(t *testing.T) { SlashEpoch: 6, }, } - newStateC := createMarketState(t, store, newDeals, ctx) + newStateC := createMarketState(ctx, t, store, newDeals) miner, err := address.NewFromString("t00") require.NoError(t, err) @@ -102,7 +103,7 @@ func TestPredicates(t *testing.T) { newState, err := mockTipset(miner, 2) require.NoError(t, err) - api := newMockApi(bs) + api := newMockAPI(bs) api.setActor(oldState.Key(), &types.Actor{Head: oldStateC}) api.setActor(newState.Key(), &types.Actor{Head: newStateC}) @@ -149,8 +150,8 @@ func mockTipset(miner address.Address, timestamp uint64) (*types.TipSet, error) }}) } -func createMarketState(t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState, ctx context.Context) cid.Cid { - rootCid := createAMT(t, store, deals, ctx) +func createMarketState(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState) cid.Cid { + rootCid := createAMT(ctx, t, store, deals) emptyArrayCid, err := amt.NewAMT(store).Flush(context.TODO()) require.NoError(t, err) @@ -164,10 +165,10 @@ func createMarketState(t *testing.T, store *cbornode.BasicIpldStore, deals map[a return stateC } -func createAMT(t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState, ctx context.Context) cid.Cid { +func createAMT(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState) cid.Cid { root := amt.NewAMT(store) - for dealId, dealState := range deals { - err := root.Set(ctx, uint64(dealId), dealState) + for dealID, dealState := range deals { + err := root.Set(ctx, uint64(dealID), dealState) require.NoError(t, err) } rootCid, err := root.Flush(ctx) From 659c723ea31d72aad34ae8723cc39afec170e21d Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 26 Jun 2020 15:42:44 -0400 Subject: [PATCH 285/379] fix: embed hcEvents into events as pointer so as not to copy lock --- chain/events/events.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/events/events.go b/chain/events/events.go index c1ef07a4e..e11507795 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -51,7 +51,7 @@ type Events struct { readyOnce sync.Once heightEvents - hcEvents + *hcEvents } func NewEvents(ctx context.Context, api eventAPI) *Events { @@ -74,7 +74,7 @@ func NewEvents(ctx context.Context, api eventAPI) *Events { htHeights: map[abi.ChainEpoch][]uint64{}, }, - hcEvents: *newHCEvents(ctx, api, tsc, uint64(gcConfidence)), + hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)), } e.ready.Add(1) From fbfe57cd633e47127fb7a05512547f25649bd9cd Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Fri, 26 Jun 2020 20:13:14 -0300 Subject: [PATCH 286/379] doc: block validations (#1919) Co-authored-by: Jakub Sztandera --- chain/types/message.go | 1 + documentation/en/block-validation.md | 137 +++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 documentation/en/block-validation.md diff --git a/chain/types/message.go b/chain/types/message.go index 68844d63c..b0d7f885f 100644 --- a/chain/types/message.go +++ b/chain/types/message.go @@ -21,6 +21,7 @@ type ChainMsg interface { Cid() cid.Cid VMMessage() *Message ToStorageBlock() (block.Block, error) + // FIXME: This is the *message* length, this name is misleading. ChainLength() int } diff --git a/documentation/en/block-validation.md b/documentation/en/block-validation.md new file mode 100644 index 000000000..a5ee49c30 --- /dev/null +++ b/documentation/en/block-validation.md @@ -0,0 +1,137 @@ +# Incoming block validations + +This document reviews the code flow that takes place inside the full node after receiving a new block from the GossipSub `/fil/blocks` topic and traces all of its protocol-related validation logic. We do not include validation logic *inside* the VM, the analysis stops at `(*VM).Invoke()`. The `V:` tag explicitly signals validations throughout the text. + +## `modules.HandleIncomingBlocks()` + +We subscribe to the `/fil/blocks` PubSub topic to receive external blocks from peers in the network and register a block validator that operates at the PubSub (`libp2p` stack) level, validating each PubSub message containing a Filecoin block header. + +`V:` PubSub message is a valid CBOR `BlockMsg`. + +`V:` Total messages in block are under `BlockMessageLimit`. + +`V:` Aggregate message CIDs, encapsulated in the `MsgMeta` structure, serialize to the `Messages` CID in the block header (`ValidateMsgMeta()`). + +`V:` Miner `Address` in block header is present and corresponds to a public-key address in the current chain state. + +`V:` Block signature (`BlockSig`) is present and belongs to the public-key address retrieved for the miner (`CheckBlockSignature()`). + +## `sub.HandleIncomingBlocks()` + +Assemble a `FullBlock` from the received block header retrieving its Filecoin messages. + +`V:` Block messages CIDs can be retrieved from the network and decode into valid CBOR `Message`/`SignedMessage`. + +## `(*Syncer).InformNewHead()` + +Assemble a `FullTipSet` populated with the single block received earlier. + +`V:` `ValidateMsgMeta()` (already done in the topic validator). + +`V:` Block's `ParentWeight` is greater than the one from the (first block of the) heaviest tipset. + +## `(*Syncer).Sync()` + +`(*Syncer).collectHeaders()`: we retrieve all tipsets from the received block down to our chain. Validation now is expanded to *every* block inside these tipsets. + +`V`: Beacon entires are ordered by their round number. + +`V:` Tipset `Parents` CIDs match the fetched parent tipset through block sync. (This check is not enforced correctly at the moment, see [issue](https://github.com/filecoin-project/lotus/issues/1918).) + +## `(*Syncer).ValidateBlock()` + +This function contains most of the validation logic grouped in separate closures that run asynchronously, this list does not reflect validation order then. + +`V:` Block `Timestamp`: + * Is not bigger than current time plus `AllowableClockDrift`. + * Is not smaller than previous block's `Timestamp` plus `BlockDelay` (including null blocks). + +### Messages + +We check all the messages contained in one block at a time (`(*Syncer).checkBlockMessages()`). + +`V:` The block's `BLSAggregate` matches the aggregate of BLS messages digests and public keys (extracted from the messages `From`). + +`V:` Each `secp256k1` message `Signature` is signed with the public key extracted from the message `From`. + +`V:` Aggregate message CIDs, encapsulated in the `MsgMeta` structure, serialize to the `Messages` CID in block header (similar to `ValidateMsgMeta()` call). + +`V:` For each message, in `ValidForBlockInclusion()`: +* Message fields `Version`, `To`, `From`, `Value`, `GasPrice`, and `GasLimit` are correctly defined. +* Message `GasLimit` is under the message minimum gas cost (derived from chain height and message length). + +`V:` Actor associated with message `From` exists and is an account actor, its `Nonce` matches the message `Nonce`. + +### Miner + +`V:` Miner address is registered in the `Claims` HAMT of the Power actor. + +### Compute parent tipset state + +`V:` Block's `ParentStateRoot` CID matches the state CID computed from the parent tipset. + +`V:` Block's `ParentMessageReceipts` CID matches receipts CID computed from the parent tipset. + +### Winner + +Draw randomness for current epoch with minimum ticket from previous tipset, using `ElectionProofProduction` +domain separation tag. +`V`: `ElectionProof.VRFProof` is computed correctly by checking BLS signature using miner's key. +`V`: Miner is not slashed in `StoragePowerActor`. +`V`: Check if ticket is a winning ticket: +``` +h := blake2b(VRFProof) +lhs := AsInt(h) * totalNetworkPower +rhs := minerPower * 2^256 +if lhs < rhs { return "Winner" } else { return "Not a winner" } +``` + +### Block signature + +`V:` `CheckBlockSignature()` (same signature validation as the one applied to the incoming block). + +### Beacon values check + +`V`: Validate that all `BeaconEntries` are valid. Check that every one of them is a signature of a message: `previousSignature || round` signed using drand's public key. +`V`: All entries between `MaxBeaconRoundForEpoch` down to `prevEntry` (from previous tipset) are included. + +### Verify VRF Ticket chain + +Draw randomness for current epoch with minimum ticket from previous tipset, using `TicketProduction` +domain separation tag. +`V`: `VerifyVRF` using drawn randomness and miner public key. + +### Winning PoSt proof + +Draw randomness for current epoch with `WinningPoSt` domain separation tag. +Get list of sectors challanged in this epoch for this miner, based on the randomness drawn. + +`V`: Use filecoin proofs system to verify that miner prooved access to sealed versions of these sectors. + +## `(*StateManager).TipSetState()` + +Called throughout the validation process for the parent of each tipset being validated. The checks here then do not apply to the received new head itself that started the validation process. + +### `(*StateManager).computeTipSetState()` + +`V:` Every block in the tipset should belong to different a miner. + +### `(*StateManager).ApplyBlocks()` + +We create a new VM with the tipset's `ParentStateRoot` (this is then the parent state of the parent of the tipset currently being validated) on which to apply all messages from all blocks in the tipset. For each message independently we apply the validations listed next. + +### `(*VM).ApplyMessage()` + +`V:` Basic gas and value checks in `checkMessage()`: +* Message `GasLimit` is bigger than zero. +* Message `GasPrice` and `Value` are set. + +`V:` Message storage gas cost is under the message's `GasLimit`. + +`V:` Message's `Nonce` matches nonce in actor retrieved from message's `From`. + +`V:` Message's maximum gas cost (derived from its `GasLimit`, `GasPrice`, and `Value`) is under the balance of the actor retrieved from message's `From`. + +### `(*VM).send()` + +`V:` Message's transfer `Value` is under the balance in actor retrieved from message's `From`. From a4f6269724cee12da578a01f4fd0a659cd3e65f0 Mon Sep 17 00:00:00 2001 From: jackoelv Date: Sat, 27 Jun 2020 23:16:24 +0800 Subject: [PATCH 287/379] Update mining.md lotus-storage-miner state power should be changed to lotus state power --- documentation/en/mining.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/en/mining.md b/documentation/en/mining.md index 80c81aedd..3b1f5a8a3 100644 --- a/documentation/en/mining.md +++ b/documentation/en/mining.md @@ -82,12 +82,12 @@ lotus-storage-miner sectors pledge Get **miner power** and **sector usage**: ```sh -lotus-storage-miner state power +lotus state power # returns total power -lotus-storage-miner state power +lotus state power -lotus-storage-miner state sectors +lotus state sectors ``` ## Performance tuning From 8d51a201433b2d60d3d680e2b1cfc2ee777bf090 Mon Sep 17 00:00:00 2001 From: waynewyang Date: Sun, 28 Jun 2020 18:20:56 +0800 Subject: [PATCH 288/379] fix: mining logic --- miner/miner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/miner.go b/miner/miner.go index 1f5f8dad5..d42778e3b 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -140,7 +140,7 @@ func (m *Miner) mine(ctx context.Context) { onDone, err := m.waitFunc(ctx, prebase.TipSet.MinTimestamp()) if err != nil { log.Error(err) - return + continue } base, err := m.GetBestMiningCandidate(ctx) From 90a470ed78636e9dbf8362aa0e9da36c2f75634b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 29 Jun 2020 16:05:27 +0200 Subject: [PATCH 289/379] Update go-bitfield with fixed empty marshaling --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7a438c5b0..c05ace73c 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 - github.com/filecoin-project/go-bitfield v0.0.2-0.20200624234227-4563d4a0bc01 + github.com/filecoin-project/go-bitfield v0.0.2-0.20200629135455-587b27927d38 github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 diff --git a/go.sum b/go.sum index 33dc25268..abcd893f9 100644 --- a/go.sum +++ b/go.sum @@ -225,8 +225,8 @@ github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mo github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e h1:gkG/7G+iKy4He+IiQNeQn+nndFznb/vCoOR8iRQsm60= github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= -github.com/filecoin-project/go-bitfield v0.0.2-0.20200624234227-4563d4a0bc01 h1:k/FyoahW7Pvqi8p8YF7Np8YcK1XWGJ8TlR1mEICly3E= -github.com/filecoin-project/go-bitfield v0.0.2-0.20200624234227-4563d4a0bc01/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= +github.com/filecoin-project/go-bitfield v0.0.2-0.20200629135455-587b27927d38 h1:B2gUde2DlfCb5YMYNVems2orobxC3KhrX3migym1IOQ= +github.com/filecoin-project/go-bitfield v0.0.2-0.20200629135455-587b27927d38/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= From c72def55fe496eca03a4b5a7e98fa854ee4337ee Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Mon, 29 Jun 2020 11:21:29 -0400 Subject: [PATCH 290/379] test: add more predicate tests --- chain/events/state/predicates_test.go | 38 ++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/chain/events/state/predicates_test.go b/chain/events/state/predicates_test.go index 1c10209a8..56387f8b5 100644 --- a/chain/events/state/predicates_test.go +++ b/chain/events/state/predicates_test.go @@ -64,7 +64,6 @@ func (m mockAPI) setActor(tsk types.TipSetKey, act *types.Actor) { func TestPredicates(t *testing.T) { ctx := context.Background() - bs := bstore.NewBlockstore(ds_sync.MutexWrap(ds.NewMapDatastore())) store := cbornode.NewCborStore(bs) @@ -133,8 +132,29 @@ func TestPredicates(t *testing.T) { } deal2 := changedDeals[abi.DealID(2)] if deal2.From.SlashEpoch != 0 || deal2.To.SlashEpoch != 6 { - t.Fatal("Unexpected change to LastUpdatedEpoch") + t.Fatal("Unexpected change to SlashEpoch") } + + // Test that OnActorStateChanged does not call the callback if the state has not changed + mockAddr, err := address.NewFromString("t01") + require.NoError(t, err) + actorDiffFn := preds.OnActorStateChanged(mockAddr, func(context.Context, cid.Cid, cid.Cid) (bool, UserData, error) { + t.Fatal("No state change so this should not be called") + return false, nil, nil + }) + changed, _, err = actorDiffFn(ctx, oldState, oldState) + require.NoError(t, err) + require.False(t, changed) + + // Test that OnDealStateChanged does not call the callback if the state has not changed + diffDealStateFn := preds.OnDealStateChanged(func(context.Context, *amt.Root, *amt.Root) (bool, UserData, error) { + t.Fatal("No state change so this should not be called") + return false, nil, nil + }) + marketState := createEmptyMarketState(t, store) + changed, _, err = diffDealStateFn(ctx, marketState, marketState) + require.NoError(t, err) + require.False(t, changed) } func mockTipset(miner address.Address, timestamp uint64) (*types.TipSet, error) { @@ -153,11 +173,7 @@ func mockTipset(miner address.Address, timestamp uint64) (*types.TipSet, error) func createMarketState(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState) cid.Cid { rootCid := createAMT(ctx, t, store, deals) - emptyArrayCid, err := amt.NewAMT(store).Flush(context.TODO()) - require.NoError(t, err) - emptyMap, err := store.Put(context.TODO(), hamt.NewNode(store, hamt.UseTreeBitWidth(5))) - require.NoError(t, err) - state := market.ConstructState(emptyArrayCid, emptyMap, emptyMap) + state := createEmptyMarketState(t, store) state.States = rootCid stateC, err := store.Put(ctx, state) @@ -165,6 +181,14 @@ func createMarketState(ctx context.Context, t *testing.T, store *cbornode.BasicI return stateC } +func createEmptyMarketState(t *testing.T, store *cbornode.BasicIpldStore) *market.State { + emptyArrayCid, err := amt.NewAMT(store).Flush(context.TODO()) + require.NoError(t, err) + emptyMap, err := store.Put(context.TODO(), hamt.NewNode(store, hamt.UseTreeBitWidth(5))) + require.NoError(t, err) + return market.ConstructState(emptyArrayCid, emptyMap, emptyMap) +} + func createAMT(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState) cid.Cid { root := amt.NewAMT(store) for dealID, dealState := range deals { From 4e32c7edb37463dfddc049216f034ab06fa08c05 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Mon, 29 Jun 2020 10:20:06 -0700 Subject: [PATCH 291/379] feat(markets): update to markets 0.3.1 Update to markets 0.3.1 with multiaddr support for miners --- go.mod | 2 +- go.sum | 4 ++-- markets/storageadapter/client.go | 33 ++++++++++++++++++++++++++++++-- markets/utils/converters.go | 5 ++++- node/impl/client/client.go | 14 ++++++++++++-- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index c05ace73c..ce9e48a66 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 - github.com/filecoin-project/go-fil-markets v0.3.0 + github.com/filecoin-project/go-fil-markets v0.3.1 github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca diff --git a/go.sum b/go.sum index abcd893f9..3f07626e0 100644 --- a/go.sum +++ b/go.sum @@ -235,8 +235,8 @@ github.com/filecoin-project/go-data-transfer v0.3.0 h1:BwBrrXu9Unh9JjjX4GAc5FfzU github.com/filecoin-project/go-data-transfer v0.3.0/go.mod h1:cONglGP4s/d+IUQw5mWZrQK+FQATQxr3AXzi4dRh0l4= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= -github.com/filecoin-project/go-fil-markets v0.3.0 h1:7iCGiuTSia4f4DmOn3s96NWUwMNSOI0ZHel/XgeApAQ= -github.com/filecoin-project/go-fil-markets v0.3.0/go.mod h1:UXsXi43AyUQ5ieb4yIaLgk4PVt7TAbl1UCccuNw+7ds= +github.com/filecoin-project/go-fil-markets v0.3.1 h1:YLH4ck4hQrKBpQ3fo0VcA2SXqiAosizxBJ/QHYgR9aE= +github.com/filecoin-project/go-fil-markets v0.3.1/go.mod h1:UY+/zwNXHN73HcrN6HxNDpv6KKM6ehqfCuE9vK9khF8= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 5f962c171..6d478d629 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -19,7 +19,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/multiformats/go-multiaddr" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/events" @@ -80,7 +80,15 @@ func (n *ClientNodeAdapter) ListStorageProviders(ctx context.Context, encodedTs return nil, err } - storageProviderInfo := utils.NewStorageProviderInfo(addr, mi.Worker, mi.SectorSize, peer.ID(mi.PeerId)) + multiaddrs := make([]multiaddr.Multiaddr, 0, len(mi.Multiaddrs)) + for _, a := range mi.Multiaddrs { + maddr, err := multiaddr.NewMultiaddrBytes(a) + if err != nil { + return nil, err + } + multiaddrs = append(multiaddrs, maddr) + } + storageProviderInfo := utils.NewStorageProviderInfo(addr, mi.Worker, mi.SectorSize, mi.PeerId, multiaddrs) out = append(out, &storageProviderInfo) } @@ -405,4 +413,25 @@ func (n *ClientNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb return cb(receipt.Receipt.ExitCode, receipt.Receipt.Return, nil) } +func (n *ClientNodeAdapter) GetMinerInfo(ctx context.Context, addr address.Address, encodedTs shared.TipSetToken) (*storagemarket.StorageProviderInfo, error) { + tsk, err := types.TipSetKeyFromBytes(encodedTs) + if err != nil { + return nil, err + } + mi, err := n.StateMinerInfo(ctx, addr, tsk) + if err != nil { + return nil, err + } + multiaddrs := make([]multiaddr.Multiaddr, 0, len(mi.Multiaddrs)) + for _, a := range mi.Multiaddrs { + maddr, err := multiaddr.NewMultiaddrBytes(a) + if err != nil { + return nil, err + } + multiaddrs = append(multiaddrs, maddr) + } + out := utils.NewStorageProviderInfo(addr, mi.Worker, mi.SectorSize, mi.PeerId, multiaddrs) + return &out, nil +} + var _ storagemarket.StorageClientNode = &ClientNodeAdapter{} diff --git a/markets/utils/converters.go b/markets/utils/converters.go index d6316839b..4c7ab5c2d 100644 --- a/markets/utils/converters.go +++ b/markets/utils/converters.go @@ -6,17 +6,20 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin/market" peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/multiformats/go-multiaddr" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/storagemarket" ) -func NewStorageProviderInfo(address address.Address, miner address.Address, sectorSize abi.SectorSize, peer peer.ID) storagemarket.StorageProviderInfo { +func NewStorageProviderInfo(address address.Address, miner address.Address, sectorSize abi.SectorSize, peer peer.ID, addrs []multiaddr.Multiaddr) storagemarket.StorageProviderInfo { + return storagemarket.StorageProviderInfo{ Address: address, Worker: miner, SectorSize: uint64(sectorSize), PeerID: peer, + Addrs: addrs, } } diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 6e7f50f26..6664414a3 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -9,6 +9,7 @@ import ( basicnode "github.com/ipld/go-ipld-prime/node/basic" "github.com/ipld/go-ipld-prime/traversal/selector" "github.com/ipld/go-ipld-prime/traversal/selector/builder" + "github.com/multiformats/go-multiaddr" "io" "os" @@ -90,6 +91,15 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) return nil, xerrors.Errorf("failed getting peer ID: %w", err) } + multiaddrs := make([]multiaddr.Multiaddr, 0, len(mi.Multiaddrs)) + for _, a := range mi.Multiaddrs { + maddr, err := multiaddr.NewMultiaddrBytes(a) + if err != nil { + return nil, err + } + multiaddrs = append(multiaddrs, maddr) + } + md, err := a.StateMinerProvingDeadline(ctx, params.Miner, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("failed getting peer ID: %w", err) @@ -104,7 +114,7 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) return nil, xerrors.New("data doesn't fit in a sector") } - providerInfo := utils.NewStorageProviderInfo(params.Miner, mi.Worker, mi.SectorSize, peer.ID(mi.PeerId)) + providerInfo := utils.NewStorageProviderInfo(params.Miner, mi.Worker, mi.SectorSize, mi.PeerId, multiaddrs) dealStart := params.DealStartEpoch if dealStart <= 0 { // unset, or explicitly 'epoch undefined' @@ -431,7 +441,7 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref } func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) { - info := utils.NewStorageProviderInfo(miner, address.Undef, 0, p) + info := utils.NewStorageProviderInfo(miner, address.Undef, 0, p, nil) signedAsk, err := a.SMDealClient.GetAsk(ctx, info) if err != nil { return nil, err From 77b3bf8bc26edef62182461227720186b70095f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Jun 2020 20:32:47 +0200 Subject: [PATCH 292/379] Update FFI to 0.30.1 --- chain/gen/mining.go | 11 +++++++++++ extern/filecoin-ffi | 2 +- go.sum | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/chain/gen/mining.go b/chain/gen/mining.go index ad8dfdf5b..bc809a888 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -150,6 +150,17 @@ func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) { } aggSig := bls.Aggregate(blsSigs) + if aggSig == nil { + if len(sigs) > 0 { + return nil, xerrors.Errorf("bls.Aggregate returned nil with %d signatures", len(sigs)) + } + + return &crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: new(bls.Signature)[:], + }, nil + } + return &crypto.Signature{ Type: crypto.SigTypeBLS, Data: aggSig[:], diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index ca281af0b..5342c7c97 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit ca281af0b6c00314382a75ae869e5cb22c83655b +Subproject commit 5342c7c97d1a1df4650629d14f2823d52889edd9 diff --git a/go.sum b/go.sum index 2b8a31ba6..f984e5816 100644 --- a/go.sum +++ b/go.sum @@ -257,6 +257,7 @@ github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246/go github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= From 12f10ac414cb776c44b7e0d00557fd556731d1c9 Mon Sep 17 00:00:00 2001 From: Travis Person Date: Mon, 29 Jun 2020 19:41:43 +0000 Subject: [PATCH 293/379] lotus-shed: organize peer key generate and other key commands under keyinfo --- cmd/lotus-shed/keyinfo.go | 349 ++++++++++++++++++++++++++++++++---- cmd/lotus-shed/main.go | 1 - cmd/lotus-shed/peerkey.go | 101 ----------- node/modules/lp2p/libp2p.go | 11 +- 4 files changed, 322 insertions(+), 140 deletions(-) delete mode 100644 cmd/lotus-shed/peerkey.go diff --git a/cmd/lotus-shed/keyinfo.go b/cmd/lotus-shed/keyinfo.go index 42ab91601..2d8ca3dca 100644 --- a/cmd/lotus-shed/keyinfo.go +++ b/cmd/lotus-shed/keyinfo.go @@ -1,8 +1,10 @@ package main import ( + "encoding/base64" "encoding/hex" "encoding/json" + "fmt" "io" "io/ioutil" "os" @@ -11,77 +13,356 @@ import ( "github.com/urfave/cli/v2" - _ "github.com/filecoin-project/lotus/lib/sigs/bls" - _ "github.com/filecoin-project/lotus/lib/sigs/secp" + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" + "github.com/filecoin-project/lotus/node/modules/lp2p" + "github.com/filecoin-project/lotus/node/repo" + + _ "github.com/filecoin-project/lotus/lib/sigs/bls" + _ "github.com/filecoin-project/lotus/lib/sigs/secp" ) -type walletInfo struct { +var validTypes = []string{wallet.KTBLS, wallet.KTSecp256k1, lp2p.KTLibp2pHost} + +type keyInfoOutput struct { Type string Address string PublicKey string } -func (wi walletInfo) String() string { - bs, _ := json.Marshal(wi) - return string(bs) +var keyinfoCmd = &cli.Command{ + Name: "keyinfo", + Usage: "work with lotus keyinfo files (wallets and libp2p host keys)", + Description: `The subcommands of keyinfo provide helpful tools for working with keyinfo files without + having to run the lotus daemon.`, + Subcommands: []*cli.Command{ + keyinfoNewCmd, + keyinfoInfoCmd, + keyinfoImportCmd, + }, } -var keyinfoCmd = &cli.Command{ - Name: "keyinfo", - Description: "decode a keyinfo", +var keyinfoImportCmd = &cli.Command{ + Name: "import", + Usage: "import a keyinfo file into a lotus repository", + Description: `The import command provides a way to import keyfiles into a lotus repository + without running the daemon. + + Note: The LOTUS_PATH directory must be created. This command will not create this directory for you. + + Examples + + env LOTUS_PATH=/var/lib/lotus lotus-shed keyinfo import libp2p-host.keyinfo`, + Action: func(cctx *cli.Context) error { + flagRepo := cctx.String("repo") + + var input io.Reader + if cctx.Args().Len() == 0 { + input = os.Stdin + } else { + var err error + input, err = os.Open(cctx.Args().First()) + if err != nil { + return err + } + } + + encoded, err := ioutil.ReadAll(input) + if err != nil { + return err + } + + decoded, err := hex.DecodeString(strings.TrimSpace(string(encoded))) + if err != nil { + return err + } + + var keyInfo types.KeyInfo + if err := json.Unmarshal(decoded, &keyInfo); err != nil { + return err + } + + fsrepo, err := repo.NewFS(flagRepo) + if err != nil { + return err + } + + lkrepo, err := fsrepo.Lock(repo.FullNode) + if err != nil { + return err + } + + defer lkrepo.Close() + + keystore, err := lkrepo.KeyStore() + if err != nil { + return err + } + + switch keyInfo.Type { + case lp2p.KTLibp2pHost: + if err := keystore.Put(lp2p.KLibp2pHost, keyInfo); err != nil { + return err + } + + sk, err := crypto.UnmarshalPrivateKey(keyInfo.PrivateKey) + if err != nil { + return err + } + + peerid, err := peer.IDFromPrivateKey(sk) + if err != nil { + return err + } + + fmt.Printf("%s\n", peerid.String()) + + break + case wallet.KTSecp256k1: + case wallet.KTBLS: + w, err := wallet.NewWallet(keystore) + if err != nil { + return err + } + + addr, err := w.Import(&keyInfo) + if err != nil { + return err + } + + fmt.Printf("%s\n", addr.String()) + } + + return nil + }, +} + +var keyinfoInfoCmd = &cli.Command{ + Name: "info", + Usage: "print information about a keyinfo file", + Description: `The info command prints additional information about a key which can't easily + be retrieved by inspecting the file itself. + + The 'format' flag takes a golang text/template template as its value. + + The following fields can be retrived through this command + Type + Address + PublicKey + + The PublicKey value will be printed base64 encoded using golangs StdEncoding + + Examples + + Retreive the address of a lotus wallet + lotus-shed keyinfo info --format '{{ .Address }}' wallet.keyinfo + `, Flags: []cli.Flag{ &cli.StringFlag{ Name: "format", - Value: "{{.Address}}", - Usage: "Format to output", + Value: "{{ .Type }} {{ .Address }}", + Usage: "specify which output columns to print", }, }, Action: func(cctx *cli.Context) error { format := cctx.String("format") var input io.Reader - if cctx.Args().Len() == 0 { input = os.Stdin } else { - input = strings.NewReader(cctx.Args().First()) + var err error + input, err = os.Open(cctx.Args().First()) + if err != nil { + return err + } } - bytes, err := ioutil.ReadAll(input) - - data, err := hex.DecodeString(strings.TrimSpace(string(bytes))) + encoded, err := ioutil.ReadAll(input) if err != nil { return err } - var ki types.KeyInfo - if err := json.Unmarshal(data, &ki); err != nil { - return err - } - - key, err := wallet.NewKey(ki) + decoded, err := hex.DecodeString(strings.TrimSpace(string(encoded))) if err != nil { return err } - bs, err := json.Marshal(key) + var keyInfo types.KeyInfo + if err := json.Unmarshal(decoded, &keyInfo); err != nil { + return err + } + + var kio keyInfoOutput + + switch keyInfo.Type { + case lp2p.KTLibp2pHost: + kio.Type = keyInfo.Type + + sk, err := crypto.UnmarshalPrivateKey(keyInfo.PrivateKey) + if err != nil { + return err + } + + pk := sk.GetPublic() + + peerid, err := peer.IDFromPrivateKey(sk) + if err != nil { + return err + } + + pkBytes, err := pk.Raw() + if err != nil { + return err + } + + kio.Address = peerid.String() + kio.PublicKey = base64.StdEncoding.EncodeToString(pkBytes) + + break + case wallet.KTSecp256k1: + case wallet.KTBLS: + kio.Type = keyInfo.Type + + key, err := wallet.NewKey(keyInfo) + if err != nil { + return err + } + + kio.Address = key.Address.String() + kio.PublicKey = base64.StdEncoding.EncodeToString(key.PublicKey) + } + + tmpl, err := template.New("output").Parse(format) if err != nil { return err } - var wi walletInfo - if err := json.Unmarshal(bs, &wi); err != nil { - return err - } - - tmpl, err := template.New("").Parse(format) - if err != nil { - return err - } - - return tmpl.Execute(os.Stdout, wi) + return tmpl.Execute(os.Stdout, kio) }, } + +var keyinfoNewCmd = &cli.Command{ + Name: "new", + Usage: "create a new keyinfo file of the provided type", + ArgsUsage: "[bls|secp256k1|libp2p-host]", + Description: `Keyinfo files are base16 encoded json structures containing a type + string value, and a base64 encoded private key. + + Both the bls and secp256k1 keyfiles can be imported into a running lotus daemon using + the 'lotus wallet import' command. Or imported to a non-running / unitialized repo using + the 'lotus-shed keyinfo import' command. Libp2p host keys can only be imported using lotus-shed + as lotus itself does not provide this functionality at the moment.`, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "output", + Value: "-.keyinfo", + Usage: "output file formt", + }, + &cli.BoolFlag{ + Name: "silent", + Value: false, + Usage: "do not print the address to stdout", + }, + }, + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return fmt.Errorf("please specify a type to generate") + } + + keyType := cctx.Args().First() + flagOutput := cctx.String("output") + + if i := SliceIndex(len(validTypes), func(i int) bool { + if keyType == validTypes[i] { + return true + } + return false + }); i == -1 { + return fmt.Errorf("invalid key type argument provided '%s'", keyType) + } + + keystore := wallet.NewMemKeyStore() + + var keyAddr string + var keyInfo types.KeyInfo + + switch keyType { + case lp2p.KTLibp2pHost: + sk, err := lp2p.PrivKey(keystore) + if err != nil { + return err + } + + ki, err := keystore.Get(lp2p.KLibp2pHost) + if err != nil { + return err + } + + peerid, err := peer.IDFromPrivateKey(sk) + if err != nil { + return err + } + + keyAddr = peerid.String() + keyInfo = ki + + break + case wallet.KTSecp256k1: + case wallet.KTBLS: + key, err := wallet.GenerateKey(wallet.ActSigType(keyType)) + if err != nil { + return err + } + + keyAddr = key.Address.String() + keyInfo = key.KeyInfo + + break + } + + filename := flagOutput + filename = strings.ReplaceAll(filename, "", keyAddr) + filename = strings.ReplaceAll(filename, "", keyType) + + file, err := os.Create(filename) + if err != nil { + return err + } + + defer func() { + if err := file.Close(); err != nil { + log.Warnf("failed to close output file: %w", err) + } + }() + + bytes, err := json.Marshal(keyInfo) + if err != nil { + return err + } + + encoded := hex.EncodeToString(bytes) + if _, err := file.Write([]byte(encoded)); err != nil { + return err + } + + if !cctx.Bool("silent") { + fmt.Println(keyAddr) + } + + return nil + }, +} + +func SliceIndex(length int, fn func(i int) bool) int { + for i := 0; i < length; i++ { + if fn(i) { + return i + } + } + + return -1 +} diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 09cffac5d..c37b93a42 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -19,7 +19,6 @@ func main() { base16Cmd, bitFieldCmd, keyinfoCmd, - peerkeyCmd, noncefix, bigIntParseCmd, staterootStatsCmd, diff --git a/cmd/lotus-shed/peerkey.go b/cmd/lotus-shed/peerkey.go deleted file mode 100644 index 6d9ee99b6..000000000 --- a/cmd/lotus-shed/peerkey.go +++ /dev/null @@ -1,101 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "os" - "strings" - - "github.com/urfave/cli/v2" - - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/node/modules/lp2p" - "github.com/libp2p/go-libp2p-core/peer" -) - -type keystore struct { - set bool - info types.KeyInfo -} - -func (ks *keystore) Put(name string, info types.KeyInfo) error { - ks.info = info - ks.set = true - - return nil -} - -func (ks *keystore) Get(name string) (types.KeyInfo, error) { - if !ks.set { - return types.KeyInfo{}, types.ErrKeyInfoNotFound - } - - return ks.info, nil -} - -func (ks *keystore) Delete(name string) error { - panic("Implement me") -} - -func (ks *keystore) List() ([]string, error) { - panic("Implement me") -} - -var peerkeyCmd = &cli.Command{ - Name: "peerkey", - Description: "create libp2p host key", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "output", - Value: ".peerkey", - Usage: "Output file format", - }, - &cli.BoolFlag{ - Name: "silent", - Value: false, - Usage: "Do not print peerid at end", - }, - }, - Action: func(cctx *cli.Context) error { - output := cctx.String("output") - ks := keystore{} - - sk, err := lp2p.PrivKey(&ks) - if err != nil { - return err - } - - bs, err := json.Marshal(ks.info) - if err != nil { - return err - } - - peerid, err := peer.IDFromPrivateKey(sk) - if err != nil { - return err - } - - output = strings.ReplaceAll(output, "", peerid.String()) - - f, err := os.Create(output) - if err != nil { - return err - } - - defer func() { - if err := f.Close(); err != nil { - log.Warnf("failed to close output file: %w", err) - } - }() - - if _, err := f.Write(bs); err != nil { - return err - } - - if !cctx.Bool("silent") { - fmt.Println(peerid.String()) - } - - return nil - }, -} diff --git a/node/modules/lp2p/libp2p.go b/node/modules/lp2p/libp2p.go index c74d05e60..5a1666cb6 100644 --- a/node/modules/lp2p/libp2p.go +++ b/node/modules/lp2p/libp2p.go @@ -19,7 +19,10 @@ import ( var log = logging.Logger("p2pnode") -const kstorePrivkey = "libp2p-host" +const ( + KLibp2pHost = "libp2p-host" + KTLibp2pHost = KLibp2pHost +) type Libp2pOpts struct { fx.Out @@ -28,7 +31,7 @@ type Libp2pOpts struct { } func PrivKey(ks types.KeyStore) (crypto.PrivKey, error) { - k, err := ks.Get(kstorePrivkey) + k, err := ks.Get(KLibp2pHost) if err == nil { return crypto.UnmarshalPrivateKey(k.PrivateKey) } @@ -44,8 +47,8 @@ func PrivKey(ks types.KeyStore) (crypto.PrivKey, error) { return nil, err } - if err := ks.Put(kstorePrivkey, types.KeyInfo{ - Type: kstorePrivkey, + if err := ks.Put(KLibp2pHost, types.KeyInfo{ + Type: KTLibp2pHost, PrivateKey: kbytes, }); err != nil { return nil, err From 0fddf3e114ef94950c8183e2822bd9e731ddccb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 14:18:01 +0100 Subject: [PATCH 294/379] make system constants configurable as vars. This configurability is unlocked through the `testground` build tag, which Project Oni will uses. Changes in the usage places of these relaxed constants were required due to the fact that Golang constants are untyped, but vars aren't. Read https://blog.golang.org/constants for more info. --- build/params_shared_funcs.go | 38 ++++++++++ ...params_shared.go => params_shared_vals.go} | 32 +-------- build/params_testground.go | 70 +++++++++++++++++++ build/params_testnet.go | 1 + chain/gen/gen.go | 4 +- chain/messagepool/messagepool.go | 2 +- chain/types/fil.go | 4 +- cli/sync.go | 2 +- cmd/lotus-health/main.go | 9 +-- cmd/lotus-seed/genesis.go | 2 +- cmd/lotus-storage-miner/info.go | 2 +- cmd/lotus-storage-miner/market.go | 4 +- cmd/lotus-storage-miner/proving.go | 4 +- go.sum | 1 + markets/storageadapter/client.go | 2 +- markets/storageadapter/provider.go | 2 +- miner/miner.go | 16 +++-- node/impl/common/common.go | 2 +- node/modules/testing/beacon.go | 2 +- tools/stats/rpc.go | 2 +- 20 files changed, 144 insertions(+), 57 deletions(-) create mode 100644 build/params_shared_funcs.go rename build/{params_shared.go => params_shared_vals.go} (76%) create mode 100644 build/params_testground.go diff --git a/build/params_shared_funcs.go b/build/params_shared_funcs.go new file mode 100644 index 000000000..cdb8e70d3 --- /dev/null +++ b/build/params_shared_funcs.go @@ -0,0 +1,38 @@ +package build + +import ( + "sort" + + "github.com/libp2p/go-libp2p-core/protocol" + + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + + "github.com/filecoin-project/lotus/node/modules/dtypes" +) + +func DefaultSectorSize() abi.SectorSize { + szs := make([]abi.SectorSize, 0, len(miner.SupportedProofTypes)) + for spt := range miner.SupportedProofTypes { + ss, err := spt.SectorSize() + if err != nil { + panic(err) + } + + szs = append(szs, ss) + } + + sort.Slice(szs, func(i, j int) bool { + return szs[i] < szs[j] + }) + + return szs[0] +} + +// Core network constants + +func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) } +func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) } +func DhtProtocolName(netName dtypes.NetworkName) protocol.ID { + return protocol.ID("/fil/kad/" + string(netName)) +} diff --git a/build/params_shared.go b/build/params_shared_vals.go similarity index 76% rename from build/params_shared.go rename to build/params_shared_vals.go index 5ab07bd3f..be12ec2d9 100644 --- a/build/params_shared.go +++ b/build/params_shared_vals.go @@ -1,44 +1,16 @@ +// +build !testground + package build import ( "math/big" - "sort" - "github.com/libp2p/go-libp2p-core/protocol" - - "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/lotus/node/modules/dtypes" ) -func DefaultSectorSize() abi.SectorSize { - szs := make([]abi.SectorSize, 0, len(miner.SupportedProofTypes)) - for spt := range miner.SupportedProofTypes { - ss, err := spt.SectorSize() - if err != nil { - panic(err) - } - - szs = append(szs, ss) - } - - sort.Slice(szs, func(i, j int) bool { - return szs[i] < szs[j] - }) - - return szs[0] -} - -// Core network constants - -func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) } -func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) } -func DhtProtocolName(netName dtypes.NetworkName) protocol.ID { - return protocol.ID("/fil/kad/" + string(netName)) -} - // ///// // Storage diff --git a/build/params_testground.go b/build/params_testground.go new file mode 100644 index 000000000..b83d24a23 --- /dev/null +++ b/build/params_testground.go @@ -0,0 +1,70 @@ +// +build testground + +// This file makes hardcoded parameters (const) configurable as vars. +// +// Its purpose is to unlock various degrees of flexibility and parametrization +// when writing Testground plans for Lotus. +// +package build + +import ( + "math/big" + + "github.com/filecoin-project/lotus/node/modules/dtypes" + + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" +) + +var ( + UnixfsChunkSize = uint64(1 << 20) + UnixfsLinksPerLevel = 1024 + + BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) + BlockMessageLimit = 512 + BlockGasLimit = int64(100_000_000_000) + BlockDelay = uint64(builtin.EpochDurationSeconds) + PropagationDelay = uint64(6) + + AllowableClockDrift = uint64(1) + + Finality = miner.ChainFinalityish + ForkLengthThreshold = Finality + + MessageConfidence uint64 = 5 + + WRatioNum = int64(1) + WRatioDen = uint64(2) + + BadBlockCacheSize = 1 << 15 + BlsSignatureCacheSize = 40000 + VerifSigCacheSize = 32000 + + SealRandomnessLookback = Finality + SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 + MaxSealLookback = SealRandomnessLookbackLimit + 2000 + + TicketRandomnessLookback = abi.ChainEpoch(1) + WinningPoStSectorSetLookback = abi.ChainEpoch(10) + + TotalFilecoin uint64 = 2_000_000_000 + MiningRewardTotal uint64 = 1_400_000_000 + + FilecoinPrecision uint64 = 1_000_000_000_000_000_000 + + InitialRewardBalance = func() *big.Int { + v := big.NewInt(int64(MiningRewardTotal)) + v = v.Mul(v, big.NewInt(int64(FilecoinPrecision))) + return v + }() + + DrandConfig = dtypes.DrandConfig{ + Servers: []string{ + "https://pl-eu.testnet.drand.sh", + "https://pl-us.testnet.drand.sh", + "https://pl-sin.testnet.drand.sh", + }, + ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}`, + } +) diff --git a/build/params_testnet.go b/build/params_testnet.go index 69884f3f8..370c1cc13 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -1,5 +1,6 @@ // +build !debug // +build !2k +// +build !testground package build diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 89d4f32bf..6d161d31c 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -196,7 +196,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { *genm2, }, NetworkName: "", - Timestamp: uint64(time.Now().Add(-500 * build.BlockDelay * time.Second).Unix()), + Timestamp: uint64(time.Now().Add(-500 * time.Duration(build.BlockDelay) * time.Second).Unix()), } genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl) @@ -414,7 +414,7 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke if cg.Timestamper != nil { ts = cg.Timestamper(parents, height-parents.Height()) } else { - ts = parents.MinTimestamp() + uint64((height-parents.Height())*build.BlockDelay) + ts = parents.MinTimestamp() + uint64(height-parents.Height())*uint64(build.BlockDelay) } fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, &api.BlockTemplate{ diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 047f409c4..78a0e8114 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -187,7 +187,7 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa mp := &MessagePool{ closer: make(chan struct{}), - repubTk: time.NewTicker(build.BlockDelay * 10 * time.Second), + repubTk: time.NewTicker(time.Duration(build.BlockDelay) * 10 * time.Second), localAddrs: make(map[address.Address]struct{}), pending: make(map[address.Address]*msgSet), minGasPrice: types.NewInt(0), diff --git a/chain/types/fil.go b/chain/types/fil.go index 80de6ced3..527078e0f 100644 --- a/chain/types/fil.go +++ b/chain/types/fil.go @@ -11,7 +11,7 @@ import ( type FIL BigInt func (f FIL) String() string { - r := new(big.Rat).SetFrac(f.Int, big.NewInt(build.FilecoinPrecision)) + r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(build.FilecoinPrecision))) if r.Sign() == 0 { return "0" } @@ -33,7 +33,7 @@ func ParseFIL(s string) (FIL, error) { return FIL{}, fmt.Errorf("failed to parse %q as a decimal number", s) } - r = r.Mul(r, big.NewRat(build.FilecoinPrecision, 1)) + r = r.Mul(r, big.NewRat(int64(build.FilecoinPrecision), 1)) if !r.IsInt() { return FIL{}, fmt.Errorf("invalid FIL value: %q", s) } diff --git a/cli/sync.go b/cli/sync.go index 2a062cbcd..e9a6fb4a4 100644 --- a/cli/sync.go +++ b/cli/sync.go @@ -186,7 +186,7 @@ func SyncWait(ctx context.Context, napi api.FullNode) error { fmt.Printf("\r\x1b[2KWorker %d: Target: %s\tState: %s\tHeight: %d", working, target, chain.SyncStageString(ss.Stage), ss.Height) - if time.Now().Unix()-int64(head.MinTimestamp()) < build.BlockDelay { + if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelay) { fmt.Println("\nDone!") return nil } diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index 9860b5b7c..d3d280b9d 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -63,7 +63,7 @@ var watchHeadCmd = &cli.Command{ }, &cli.IntFlag{ Name: "interval", - Value: build.BlockDelay, + Value: int(build.BlockDelay), Usage: "interval in seconds between chain head checks", }, &cli.StringFlag{ @@ -72,8 +72,9 @@ var watchHeadCmd = &cli.Command{ Usage: "systemd unit name to restart on health check failure", }, &cli.IntFlag{ - Name: "api-timeout", - Value: build.BlockDelay, + Name: "api-timeout", + // TODO: this default value seems spurious. + Value: int(build.BlockDelay), Usage: "timeout between API retries", }, &cli.IntFlag{ @@ -236,7 +237,7 @@ func waitForSyncComplete(ctx context.Context, a api.FullNode, r int, t time.Dura return err } - if time.Now().Unix()-int64(head.MinTimestamp()) < build.BlockDelay { + if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelay) { return nil } } diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index 748b406ac..d439e2ed5 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -124,7 +124,7 @@ var genesisAddMinerCmd = &cli.Command{ log.Infof("Giving %s some initial balance", miner.Owner) template.Accounts = append(template.Accounts, genesis.Actor{ Type: genesis.TAccount, - Balance: big.Mul(big.NewInt(50_000_000), big.NewInt(build.FilecoinPrecision)), + Balance: big.Mul(big.NewInt(50_000_000), big.NewInt(int64(build.FilecoinPrecision))), Meta: (&genesis.AccountMeta{Owner: miner.Owner}).ActorMeta(), }) } diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 17e06e214..2863e97cb 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -128,7 +128,7 @@ var infoCmd = &cli.Command{ if expWinChance > 1 { expWinChance = 1 } - winRate := time.Duration(float64(time.Second*build.BlockDelay) / expWinChance) + winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelay)) / expWinChance) winPerDay := float64(time.Hour*24) / float64(winRate) fmt.Print("Expected block win rate: ") diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index e658be1cf..802e7ed66 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -123,7 +123,7 @@ var setAskCmd = &cli.Command{ return xerrors.Errorf("cannot parse duration: %w", err) } - qty := dur.Seconds() / build.BlockDelay + qty := dur.Seconds() / float64(build.BlockDelay) min, err := units.RAMInBytes(cctx.String("min-piece-size")) if err != nil { @@ -208,7 +208,7 @@ var getAskCmd = &cli.Command{ dlt := ask.Expiry - head.Height() rem := "" if dlt > 0 { - rem = (time.Second * time.Duration(dlt*build.BlockDelay)).String() + rem = (time.Second * time.Duration(int64(dlt)*int64(build.BlockDelay))).String() } fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, rem, ask.SeqNo) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 60cf2ab99..43170b01d 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -211,11 +211,11 @@ var provingInfoCmd = &cli.Command{ func epochTime(curr, e abi.ChainEpoch) string { switch { case curr > e: - return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(build.BlockDelay*(curr-e))) + return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(int64(build.BlockDelay)*int64(curr-e))) case curr == e: return fmt.Sprintf("%d (now)", e) case curr < e: - return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(build.BlockDelay*(e-curr))) + return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(int64(build.BlockDelay)*int64(e-curr))) } panic("math broke") diff --git a/go.sum b/go.sum index 3f07626e0..717aa3ae5 100644 --- a/go.sum +++ b/go.sum @@ -259,6 +259,7 @@ github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246/go github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 6d478d629..863e527cb 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -330,7 +330,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider } } - if err := c.ev.Called(checkFunc, called, revert, build.MessageConfidence+1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { + if err := c.ev.Called(checkFunc, called, revert, int(build.MessageConfidence+1), build.SealRandomnessLookbackLimit, matchEvent); err != nil { return xerrors.Errorf("failed to set up called handler: %w", err) } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index ddbc826eb..338396675 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -321,7 +321,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide } - if err := n.ev.Called(checkFunc, called, revert, build.MessageConfidence+1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { + if err := n.ev.Called(checkFunc, called, revert, int(build.MessageConfidence+1), build.SealRandomnessLookbackLimit, matchEvent); err != nil { return xerrors.Errorf("failed to set up called handler: %w", err) } diff --git a/miner/miner.go b/miner/miner.go index d42778e3b..2130ce181 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -150,7 +150,7 @@ func (m *Miner) mine(ctx context.Context) { } if base.TipSet.Equals(lastBase.TipSet) && lastBase.NullRounds == base.NullRounds { log.Warnf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.TipSet.Cids(), lastBase.NullRounds) - m.niceSleep(build.BlockDelay * time.Second) + m.niceSleep(time.Duration(build.BlockDelay) * time.Second) continue } @@ -194,7 +194,7 @@ func (m *Miner) mine(ctx context.Context) { // has enough time to form. // // See: https://github.com/filecoin-project/lotus/issues/1845 - nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+uint64(build.BlockDelay*base.NullRounds))+int64(build.PropagationDelay), 0) + nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+build.BlockDelay*uint64(base.NullRounds))+int64(build.PropagationDelay), 0) select { case <-time.After(time.Until(nextRound)): @@ -255,12 +255,16 @@ func (m *Miner) hasPower(ctx context.Context, addr address.Address, ts *types.Ti return mpower.MinerPower.QualityAdjPower.GreaterThanEqual(power.ConsensusMinerMinPower), nil } -// mineOne mines a single block, and does so synchronously, if and only if we -// have won the current round. +// mineOne attempts to mine a single block, and does so synchronously, if and +// only if we are eligible to mine. // // {hint/landmark}: This method coordinates all the steps involved in mining a // block, including the condition of whether mine or not at all depending on // whether we win the round or not. +// +// This method does the following: +// +// 1. func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, error) { log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.TipSet.Cids())) start := time.Now() @@ -352,7 +356,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, tCreateBlock := time.Now() dur := tCreateBlock.Sub(start) log.Infow("mined new block", "cid", b.Cid(), "height", b.Header.Height, "took", dur) - if dur > time.Second*build.BlockDelay { + if dur > time.Second*time.Duration(build.BlockDelay) { log.Warn("CAUTION: block production took longer than the block delay. Your computer may not be fast enough to keep up") log.Warnw("tMinerBaseInfo ", "duration", tMBI.Sub(start)) @@ -413,7 +417,7 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type msgs = msgs[:build.BlockMessageLimit] } - uts := base.TipSet.MinTimestamp() + uint64(build.BlockDelay*(base.NullRounds+1)) + uts := base.TipSet.MinTimestamp() + build.BlockDelay*(uint64(base.NullRounds)+1) nheight := base.TipSet.Height() + base.NullRounds + 1 diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 3a42872d9..c9f54470c 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -122,7 +122,7 @@ func (a *CommonAPI) Version(context.Context) (api.Version, error) { Version: build.UserVersion(), APIVersion: build.APIVersion, - BlockDelay: build.BlockDelay, + BlockDelay: uint64(build.BlockDelay), }, nil } diff --git a/node/modules/testing/beacon.go b/node/modules/testing/beacon.go index 37d229982..28bdf7946 100644 --- a/node/modules/testing/beacon.go +++ b/node/modules/testing/beacon.go @@ -8,5 +8,5 @@ import ( ) func RandomBeacon() (beacon.RandomBeacon, error) { - return beacon.NewMockBeacon(build.BlockDelay * time.Second), nil + return beacon.NewMockBeacon(time.Duration(build.BlockDelay) * time.Second), nil } diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index 6e00ff910..61f53a911 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -114,7 +114,7 @@ sync_complete: // If we get within 20 blocks of the current exected block height we // consider sync complete. Block propagation is not always great but we still // want to be recording stats as soon as we can - if timestampDelta < build.BlockDelay*20 { + if timestampDelta < int64(build.BlockDelay)*20 { return nil } } From 612b2fe9d7d6bb5c2243886abceec31750eb7ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 14:21:39 +0100 Subject: [PATCH 295/379] revert changes in go.sum. --- go.sum | 1 - 1 file changed, 1 deletion(-) diff --git a/go.sum b/go.sum index 717aa3ae5..3f07626e0 100644 --- a/go.sum +++ b/go.sum @@ -259,7 +259,6 @@ github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246/go github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= -github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= From 4f9c9072489ae83c78d5a9d6a61edb1d09d23434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 14:22:48 +0100 Subject: [PATCH 296/379] rename build.{BlockDelay=>BlockDelaySecs}. Since this global is not typed as a time.Duration, rather as an int, it makes sense to clarify the unit. --- build/params_2k.go | 2 +- build/params_testground.go | 2 +- build/params_testnet.go | 2 +- chain/gen/gen.go | 6 +++--- chain/messagepool/messagepool.go | 2 +- chain/sync.go | 6 +++--- chain/sync_test.go | 2 +- cli/sync.go | 2 +- cmd/lotus-health/main.go | 6 +++--- cmd/lotus-storage-miner/info.go | 2 +- cmd/lotus-storage-miner/market.go | 4 ++-- cmd/lotus-storage-miner/proving.go | 4 ++-- cmd/lotus/debug_advance.go | 2 +- miner/miner.go | 8 ++++---- node/impl/common/common.go | 2 +- node/modules/services.go | 4 ++-- node/modules/testing/beacon.go | 2 +- node/node_test.go | 2 +- tools/stats/rpc.go | 2 +- 19 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/params_2k.go b/build/params_2k.go index 046753678..36eef602f 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -21,7 +21,7 @@ func init() { } // Seconds -const BlockDelay = 2 +const BlockDelaySecs = 2 const PropagationDelay = 3 diff --git a/build/params_testground.go b/build/params_testground.go index b83d24a23..8cc36258e 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -24,7 +24,7 @@ var ( BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) BlockMessageLimit = 512 BlockGasLimit = int64(100_000_000_000) - BlockDelay = uint64(builtin.EpochDurationSeconds) + BlockDelaySecs = uint64(builtin.EpochDurationSeconds) PropagationDelay = uint64(6) AllowableClockDrift = uint64(1) diff --git a/build/params_testnet.go b/build/params_testnet.go index 370c1cc13..98a9d9071 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -21,6 +21,6 @@ func init() { } // Seconds -const BlockDelay = builtin.EpochDurationSeconds +const BlockDelaySecs = builtin.EpochDurationSeconds const PropagationDelay = 6 diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 6d161d31c..abbc87e93 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -196,7 +196,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { *genm2, }, NetworkName: "", - Timestamp: uint64(time.Now().Add(-500 * time.Duration(build.BlockDelay) * time.Second).Unix()), + Timestamp: uint64(time.Now().Add(-500 * time.Duration(build.BlockDelaySecs) * time.Second).Unix()), } genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl) @@ -223,7 +223,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { miners := []address.Address{maddr1, maddr2} beac := beacon.NewMockBeacon(time.Second) - //beac, err := drand.NewDrandBeacon(tpl.Timestamp, build.BlockDelay) + //beac, err := drand.NewDrandBeacon(tpl.Timestamp, build.BlockDelaySecs) //if err != nil { //return nil, xerrors.Errorf("creating drand beacon: %w", err) //} @@ -414,7 +414,7 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke if cg.Timestamper != nil { ts = cg.Timestamper(parents, height-parents.Height()) } else { - ts = parents.MinTimestamp() + uint64(height-parents.Height())*uint64(build.BlockDelay) + ts = parents.MinTimestamp() + uint64(height-parents.Height())*uint64(build.BlockDelaySecs) } fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, &api.BlockTemplate{ diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 78a0e8114..b8ac55c59 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -187,7 +187,7 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa mp := &MessagePool{ closer: make(chan struct{}), - repubTk: time.NewTicker(time.Duration(build.BlockDelay) * 10 * time.Second), + repubTk: time.NewTicker(time.Duration(build.BlockDelaySecs) * 10 * time.Second), localAddrs: make(map[address.Address]struct{}), pending: make(map[address.Address]*msgSet), minGasPrice: types.NewInt(0), diff --git a/chain/sync.go b/chain/sync.go index 0a08e8b15..6e2e68cee 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -664,11 +664,11 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er log.Warn("Got block from the future, but within threshold", h.Timestamp, time.Now().Unix()) } - if h.Timestamp < baseTs.MinTimestamp()+(build.BlockDelay*uint64(h.Height-baseTs.Height())) { + if h.Timestamp < baseTs.MinTimestamp()+(build.BlockDelaySecs*uint64(h.Height-baseTs.Height())) { log.Warn("timestamp funtimes: ", h.Timestamp, baseTs.MinTimestamp(), h.Height, baseTs.Height()) - diff := (baseTs.MinTimestamp() + (build.BlockDelay * uint64(h.Height-baseTs.Height()))) - h.Timestamp + diff := (baseTs.MinTimestamp() + (build.BlockDelaySecs * uint64(h.Height-baseTs.Height()))) - h.Timestamp - return xerrors.Errorf("block was generated too soon (h.ts:%d < base.mints:%d + BLOCK_DELAY:%d * deltaH:%d; diff %d)", h.Timestamp, baseTs.MinTimestamp(), build.BlockDelay, h.Height-baseTs.Height(), diff) + return xerrors.Errorf("block was generated too soon (h.ts:%d < base.mints:%d + BLOCK_DELAY:%d * deltaH:%d; diff %d)", h.Timestamp, baseTs.MinTimestamp(), build.BlockDelaySecs, h.Height-baseTs.Height(), diff) } msgsCheck := async.Err(func() error { diff --git a/chain/sync_test.go b/chain/sync_test.go index 92c0f72d7..efb601041 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -408,7 +408,7 @@ func TestSyncBadTimestamp(t *testing.T) { base := tu.g.CurTipset tu.g.Timestamper = func(pts *types.TipSet, tl abi.ChainEpoch) uint64 { - return pts.MinTimestamp() + (build.BlockDelay / 2) + return pts.MinTimestamp() + (build.BlockDelaySecs / 2) } fmt.Println("BASE: ", base.Cids()) diff --git a/cli/sync.go b/cli/sync.go index e9a6fb4a4..fbb69a870 100644 --- a/cli/sync.go +++ b/cli/sync.go @@ -186,7 +186,7 @@ func SyncWait(ctx context.Context, napi api.FullNode) error { fmt.Printf("\r\x1b[2KWorker %d: Target: %s\tState: %s\tHeight: %d", working, target, chain.SyncStageString(ss.Stage), ss.Height) - if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelay) { + if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelaySecs) { fmt.Println("\nDone!") return nil } diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index d3d280b9d..e8a32a719 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -63,7 +63,7 @@ var watchHeadCmd = &cli.Command{ }, &cli.IntFlag{ Name: "interval", - Value: int(build.BlockDelay), + Value: int(build.BlockDelaySecs), Usage: "interval in seconds between chain head checks", }, &cli.StringFlag{ @@ -74,7 +74,7 @@ var watchHeadCmd = &cli.Command{ &cli.IntFlag{ Name: "api-timeout", // TODO: this default value seems spurious. - Value: int(build.BlockDelay), + Value: int(build.BlockDelaySecs), Usage: "timeout between API retries", }, &cli.IntFlag{ @@ -237,7 +237,7 @@ func waitForSyncComplete(ctx context.Context, a api.FullNode, r int, t time.Dura return err } - if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelay) { + if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelaySecs) { return nil } } diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 2863e97cb..4e54252bc 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -128,7 +128,7 @@ var infoCmd = &cli.Command{ if expWinChance > 1 { expWinChance = 1 } - winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelay)) / expWinChance) + winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelaySecs)) / expWinChance) winPerDay := float64(time.Hour*24) / float64(winRate) fmt.Print("Expected block win rate: ") diff --git a/cmd/lotus-storage-miner/market.go b/cmd/lotus-storage-miner/market.go index 802e7ed66..feae26358 100644 --- a/cmd/lotus-storage-miner/market.go +++ b/cmd/lotus-storage-miner/market.go @@ -123,7 +123,7 @@ var setAskCmd = &cli.Command{ return xerrors.Errorf("cannot parse duration: %w", err) } - qty := dur.Seconds() / float64(build.BlockDelay) + qty := dur.Seconds() / float64(build.BlockDelaySecs) min, err := units.RAMInBytes(cctx.String("min-piece-size")) if err != nil { @@ -208,7 +208,7 @@ var getAskCmd = &cli.Command{ dlt := ask.Expiry - head.Height() rem := "" if dlt > 0 { - rem = (time.Second * time.Duration(int64(dlt)*int64(build.BlockDelay))).String() + rem = (time.Second * time.Duration(int64(dlt)*int64(build.BlockDelaySecs))).String() } fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, rem, ask.SeqNo) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 43170b01d..d96bd39f8 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -211,11 +211,11 @@ var provingInfoCmd = &cli.Command{ func epochTime(curr, e abi.ChainEpoch) string { switch { case curr > e: - return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(int64(build.BlockDelay)*int64(curr-e))) + return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e))) case curr == e: return fmt.Sprintf("%d (now)", e) case curr < e: - return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(int64(build.BlockDelay)*int64(e-curr))) + return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr))) } panic("math broke") diff --git a/cmd/lotus/debug_advance.go b/cmd/lotus/debug_advance.go index 2782ea074..2a7d38eab 100644 --- a/cmd/lotus/debug_advance.go +++ b/cmd/lotus/debug_advance.go @@ -69,7 +69,7 @@ func init() { } // TODO: beacon - uts := head.MinTimestamp() + uint64(build.BlockDelay) + uts := head.MinTimestamp() + uint64(build.BlockDelaySecs) nheight := head.Height() + 1 blk, err := api.MinerCreateBlock(ctx, &lapi.BlockTemplate{ addr, head.Key(), ticket, &types.ElectionProof{}, nil, msgs, nheight, uts, gen.ValidWpostForTesting, diff --git a/miner/miner.go b/miner/miner.go index 2130ce181..08a4645fd 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -150,7 +150,7 @@ func (m *Miner) mine(ctx context.Context) { } if base.TipSet.Equals(lastBase.TipSet) && lastBase.NullRounds == base.NullRounds { log.Warnf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.TipSet.Cids(), lastBase.NullRounds) - m.niceSleep(time.Duration(build.BlockDelay) * time.Second) + m.niceSleep(time.Duration(build.BlockDelaySecs) * time.Second) continue } @@ -194,7 +194,7 @@ func (m *Miner) mine(ctx context.Context) { // has enough time to form. // // See: https://github.com/filecoin-project/lotus/issues/1845 - nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+build.BlockDelay*uint64(base.NullRounds))+int64(build.PropagationDelay), 0) + nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+build.BlockDelaySecs*uint64(base.NullRounds))+int64(build.PropagationDelay), 0) select { case <-time.After(time.Until(nextRound)): @@ -356,7 +356,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, tCreateBlock := time.Now() dur := tCreateBlock.Sub(start) log.Infow("mined new block", "cid", b.Cid(), "height", b.Header.Height, "took", dur) - if dur > time.Second*time.Duration(build.BlockDelay) { + if dur > time.Second*time.Duration(build.BlockDelaySecs) { log.Warn("CAUTION: block production took longer than the block delay. Your computer may not be fast enough to keep up") log.Warnw("tMinerBaseInfo ", "duration", tMBI.Sub(start)) @@ -417,7 +417,7 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type msgs = msgs[:build.BlockMessageLimit] } - uts := base.TipSet.MinTimestamp() + build.BlockDelay*(uint64(base.NullRounds)+1) + uts := base.TipSet.MinTimestamp() + build.BlockDelaySecs*(uint64(base.NullRounds)+1) nheight := base.TipSet.Height() + base.NullRounds + 1 diff --git a/node/impl/common/common.go b/node/impl/common/common.go index c9f54470c..2d1beaa31 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -122,7 +122,7 @@ func (a *CommonAPI) Version(context.Context) (api.Version, error) { Version: build.UserVersion(), APIVersion: build.APIVersion, - BlockDelay: uint64(build.BlockDelay), + BlockDelay: uint64(build.BlockDelaySecs), }, nil } diff --git a/node/modules/services.go b/node/modules/services.go index 2cba3a0be..35cc8f40b 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -123,6 +123,6 @@ func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.Random return nil, err } - //return beacon.NewMockBeacon(build.BlockDelay * time.Second) - return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay, p.PubSub, p.DrandConfig) + //return beacon.NewMockBeacon(build.BlockDelaySecs * time.Second) + return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelaySecs, p.PubSub, p.DrandConfig) } diff --git a/node/modules/testing/beacon.go b/node/modules/testing/beacon.go index 28bdf7946..a4ef822fc 100644 --- a/node/modules/testing/beacon.go +++ b/node/modules/testing/beacon.go @@ -8,5 +8,5 @@ import ( ) func RandomBeacon() (beacon.RandomBeacon, error) { - return beacon.NewMockBeacon(time.Duration(build.BlockDelay) * time.Second), nil + return beacon.NewMockBeacon(time.Duration(build.BlockDelaySecs) * time.Second), nil } diff --git a/node/node_test.go b/node/node_test.go index a3a37bdd3..bda7cb313 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -349,7 +349,7 @@ func mockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test templ := &genesis.Template{ Accounts: genaccs, Miners: genms, - Timestamp: uint64(time.Now().Unix() - (build.BlockDelay * 20000)), + Timestamp: uint64(time.Now().Unix() - (build.BlockDelaySecs * 20000)), } // END PRESEAL SECTION diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index 61f53a911..a94ab955b 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -114,7 +114,7 @@ sync_complete: // If we get within 20 blocks of the current exected block height we // consider sync complete. Block propagation is not always great but we still // want to be recording stats as soon as we can - if timestampDelta < int64(build.BlockDelay)*20 { + if timestampDelta < int64(build.BlockDelaySecs)*20 { return nil } } From 642aed93d9ea1a8432147c98466604bc63452a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 14:38:20 +0100 Subject: [PATCH 297/379] remove superfluous comment. Co-authored-by: Anton Evangelatov --- build/params_2k.go | 1 - 1 file changed, 1 deletion(-) diff --git a/build/params_2k.go b/build/params_2k.go index 36eef602f..d9d1c1c02 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -20,7 +20,6 @@ func init() { BuildType |= Build2k } -// Seconds const BlockDelaySecs = 2 const PropagationDelay = 3 From f774d2aab1d0c7dcbc6520d25fb42cc589f24eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 14:46:28 +0100 Subject: [PATCH 298/379] add testground Makefile target; attach to buildall. --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index b143793aa..4533cc4dc 100644 --- a/Makefile +++ b/Makefile @@ -191,6 +191,12 @@ health: .PHONY: health BINS+=health +testground: + go build -tags testground -o /dev/null ./cmd/lotus + +.PHONY: testground +BINS+=testground + # MISC buildall: $(BINS) From d232299c7779d6d6ed613974020850a8bf5ddc91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 14:58:34 +0100 Subject: [PATCH 299/379] type constants on all build tags. --- build/params_2k.go | 4 ++-- build/params_shared_vals.go | 21 +++++++++++---------- build/params_testground.go | 3 +++ build/params_testnet.go | 5 ++--- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/build/params_2k.go b/build/params_2k.go index d9d1c1c02..e5b2f062f 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -20,9 +20,9 @@ func init() { BuildType |= Build2k } -const BlockDelaySecs = 2 +const BlockDelaySecs = uint64(2) -const PropagationDelay = 3 +const PropagationDelay = uint64(3) // SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after // which the miner is slashed diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index be12ec2d9..db0d0ea63 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -5,6 +5,7 @@ package build import ( "math/big" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" @@ -21,7 +22,7 @@ const UnixfsLinksPerLevel = 1024 // Consensus / Network // Seconds -const AllowableClockDrift = 1 +const AllowableClockDrift = uint64(1) // Epochs const ForkLengthThreshold = Finality @@ -31,12 +32,12 @@ var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) // Epochs const Finality = miner.ChainFinalityish -const MessageConfidence = 5 +const MessageConfidence = uint64(5) // constants for Weight calculation // The ratio of weight contributed by short-term vs long-term factors in a given round const WRatioNum = int64(1) -const WRatioDen = 2 +const WRatioDen = uint64(2) // ///// // Proofs @@ -54,25 +55,25 @@ const MaxSealLookback = SealRandomnessLookbackLimit + 2000 // TODO: Get from spe // Mining // Epochs -const TicketRandomnessLookback = 1 +const TicketRandomnessLookback = abi.ChainEpoch(1) -const WinningPoStSectorSetLookback = 10 +const WinningPoStSectorSetLookback = abi.ChainEpoch(10) // ///// // Devnet settings -const TotalFilecoin = 2_000_000_000 -const MiningRewardTotal = 1_400_000_000 +const TotalFilecoin = uint64(2_000_000_000) +const MiningRewardTotal = uint64(1_400_000_000) -const FilecoinPrecision = 1_000_000_000_000_000_000 +const FilecoinPrecision = uint64(1_000_000_000_000_000_000) var InitialRewardBalance *big.Int // TODO: Move other important consts here func init() { - InitialRewardBalance = big.NewInt(MiningRewardTotal) - InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(FilecoinPrecision)) + InitialRewardBalance = big.NewInt(int64(MiningRewardTotal)) + InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(int64(FilecoinPrecision))) } // Sync diff --git a/build/params_testground.go b/build/params_testground.go index 8cc36258e..c171da625 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -32,6 +32,9 @@ var ( Finality = miner.ChainFinalityish ForkLengthThreshold = Finality + SlashablePowerDelay = 20 + InteractivePoRepConfidence = 6 + MessageConfidence uint64 = 5 WRatioNum = int64(1) diff --git a/build/params_testnet.go b/build/params_testnet.go index 98a9d9071..3da87c08b 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -20,7 +20,6 @@ func init() { } } -// Seconds -const BlockDelaySecs = builtin.EpochDurationSeconds +const BlockDelaySecs = uint64(builtin.EpochDurationSeconds) -const PropagationDelay = 6 +const PropagationDelay = uint64(6) From 3b826e41f6afbcccd2f93c7f3fcd89f1574b4f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 15:00:01 +0100 Subject: [PATCH 300/379] rename build.AllowableClockDrift{=>Secs}. --- build/params_shared_vals.go | 3 +-- build/params_testground.go | 2 +- chain/sync.go | 2 +- documentation/en/block-validation.md | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index db0d0ea63..f00c68ed0 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -21,8 +21,7 @@ const UnixfsLinksPerLevel = 1024 // ///// // Consensus / Network -// Seconds -const AllowableClockDrift = uint64(1) +const AllowableClockDriftSecs = uint64(1) // Epochs const ForkLengthThreshold = Finality diff --git a/build/params_testground.go b/build/params_testground.go index c171da625..df03124af 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -27,7 +27,7 @@ var ( BlockDelaySecs = uint64(builtin.EpochDurationSeconds) PropagationDelay = uint64(6) - AllowableClockDrift = uint64(1) + AllowableClockDriftSecs = uint64(1) Finality = miner.ChainFinalityish ForkLengthThreshold = Finality diff --git a/chain/sync.go b/chain/sync.go index 6e2e68cee..e1bcdd506 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -657,7 +657,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er // fast checks first now := uint64(time.Now().Unix()) - if h.Timestamp > now+build.AllowableClockDrift { + if h.Timestamp > now+build.AllowableClockDriftSecs { return xerrors.Errorf("block was from the future (now=%d, blk=%d): %w", now, h.Timestamp, ErrTemporal) } if h.Timestamp > now { diff --git a/documentation/en/block-validation.md b/documentation/en/block-validation.md index a5ee49c30..ccd83a904 100644 --- a/documentation/en/block-validation.md +++ b/documentation/en/block-validation.md @@ -43,7 +43,7 @@ Assemble a `FullTipSet` populated with the single block received earlier. This function contains most of the validation logic grouped in separate closures that run asynchronously, this list does not reflect validation order then. `V:` Block `Timestamp`: - * Is not bigger than current time plus `AllowableClockDrift`. + * Is not bigger than current time plus `AllowableClockDriftSecs`. * Is not smaller than previous block's `Timestamp` plus `BlockDelay` (including null blocks). ### Messages From 1ef490feea5e35ae8eae03303f14ae40236470bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 15:01:30 +0100 Subject: [PATCH 301/379] rename build.PropagationDelay{=>Secs}. --- build/params_2k.go | 2 +- build/params_testground.go | 10 +++++----- build/params_testnet.go | 2 +- miner/miner.go | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build/params_2k.go b/build/params_2k.go index e5b2f062f..d22c6a6f8 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -22,7 +22,7 @@ func init() { const BlockDelaySecs = uint64(2) -const PropagationDelay = uint64(3) +const PropagationDelaySecs = uint64(3) // SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after // which the miner is slashed diff --git a/build/params_testground.go b/build/params_testground.go index df03124af..704503981 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -21,11 +21,11 @@ var ( UnixfsChunkSize = uint64(1 << 20) UnixfsLinksPerLevel = 1024 - BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) - BlockMessageLimit = 512 - BlockGasLimit = int64(100_000_000_000) - BlockDelaySecs = uint64(builtin.EpochDurationSeconds) - PropagationDelay = uint64(6) + BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) + BlockMessageLimit = 512 + BlockGasLimit = int64(100_000_000_000) + BlockDelaySecs = uint64(builtin.EpochDurationSeconds) + PropagationDelaySecs = uint64(6) AllowableClockDriftSecs = uint64(1) diff --git a/build/params_testnet.go b/build/params_testnet.go index 3da87c08b..e0e3fc3fa 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -22,4 +22,4 @@ func init() { const BlockDelaySecs = uint64(builtin.EpochDurationSeconds) -const PropagationDelay = uint64(6) +const PropagationDelaySecs = uint64(6) diff --git a/miner/miner.go b/miner/miner.go index 08a4645fd..6ee11d55c 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -42,7 +42,7 @@ func NewMiner(api api.FullNode, epp gen.WinningPoStProver, addr address.Address) address: addr, waitFunc: func(ctx context.Context, baseTime uint64) (func(bool), error) { // Wait around for half the block time in case other parents come in - deadline := baseTime + build.PropagationDelay + deadline := baseTime + build.PropagationDelaySecs time.Sleep(time.Until(time.Unix(int64(deadline), 0))) return func(bool) {}, nil @@ -194,7 +194,7 @@ func (m *Miner) mine(ctx context.Context) { // has enough time to form. // // See: https://github.com/filecoin-project/lotus/issues/1845 - nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+build.BlockDelaySecs*uint64(base.NullRounds))+int64(build.PropagationDelay), 0) + nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+build.BlockDelaySecs*uint64(base.NullRounds))+int64(build.PropagationDelaySecs), 0) select { case <-time.After(time.Until(nextRound)): From 05e521ab03555faf403f8ad3ede1dc87430ea7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 16:47:32 +0100 Subject: [PATCH 302/379] fix test compilation issue. --- node/node_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/node_test.go b/node/node_test.go index bda7cb313..b9837b1f0 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -349,7 +349,7 @@ func mockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test templ := &genesis.Template{ Accounts: genaccs, Miners: genms, - Timestamp: uint64(time.Now().Unix() - (build.BlockDelaySecs * 20000)), + Timestamp: uint64(time.Now().Unix()) - (build.BlockDelaySecs * 20000), } // END PRESEAL SECTION From c16ea42fad490a26ddc6344c06c11a1547d68d4d Mon Sep 17 00:00:00 2001 From: Frrist Date: Tue, 30 Jun 2020 10:26:41 -0700 Subject: [PATCH 303/379] fix: update miner_head table with new miner fields (#2142) --- cmd/lotus-chainwatch/main.go | 3 + cmd/lotus-chainwatch/storage.go | 117 ++++++++++++++++---------------- cmd/lotus-chainwatch/sync.go | 15 ++-- 3 files changed, 69 insertions(+), 66 deletions(-) diff --git a/cmd/lotus-chainwatch/main.go b/cmd/lotus-chainwatch/main.go index 704c4d457..b5ceb7348 100644 --- a/cmd/lotus-chainwatch/main.go +++ b/cmd/lotus-chainwatch/main.go @@ -18,6 +18,9 @@ var log = logging.Logger("chainwatch") func main() { _ = logging.SetLogLevel("*", "INFO") + if err := logging.SetLogLevel("rpc", "error"); err != nil { + panic(err) + } log.Info("Starting chainwatch") diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index e9361e5a4..e56cc9a9b 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/libp2p/go-libp2p-core/peer" "sync" "time" @@ -257,7 +258,6 @@ create index if not exists receipts_msg_state_index create table if not exists miner_sectors ( - stateroot text not null, miner text not null, sectorid bigint not null, activation bigint not null, @@ -267,36 +267,29 @@ create table if not exists miner_sectors sealcid text not null, sealrandepoch bigint not null, constraint miner_sectors_pk - primary key (stateroot, miner, sectorid) + primary key (miner, sectorid) ); -create index if not exists miner_sectors_stateroot_miner_sectorid_index - on miner_sectors (stateroot, miner, sectorid); -/* +create index if not exists miner_sectors_miner_sectorid_index + on miner_sectors (miner, sectorid); + create table if not exists miner_heads ( - head text not null, addr text not null, - stateroot text not null, - sectorset text not null, - setsize decimal not null, - provingset text not null, - provingsize decimal not null, owner text not null, worker text not null, - peerid text not null, - sectorsize bigint not null, - power decimal not null, - active bool, - ppe bigint not null, - slashed_at bigint not null, + peerid text, + sectorsize text not null, + windowpostpartitionsectors bigint not null, + + precommitdeposits text not null, + lockedfunds text not null, + nextdeadlineprocessfaults bigint not null, constraint miner_heads_pk - primary key (head, addr) + primary key (addr) ); -create index if not exists miner_heads_stateroot_index - on miner_heads (stateroot); - +/* create or replace function miner_tips(epoch bigint) returns table (head text, addr text, @@ -490,7 +483,7 @@ func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, s return xerrors.Errorf("prep temp: %w", err) } - stmt, err := tx.Prepare(`copy ms (stateroot, miner, sectorid, activation, dealweight, verifieddealweight, expiration, sealcid, sealrandepoch) from STDIN `) + stmt, err := tx.Prepare(`copy ms (miner, sectorid, activation, dealweight, verifieddealweight, expiration, sealcid, sealrandepoch) from STDIN `) if err != nil { return err } @@ -504,7 +497,6 @@ func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, s for _, sector := range sectors { if _, err := stmt.Exec( - miner.stateroot.String(), miner.addr.String(), uint64(sector.ID), int64(sector.Info.ActivationEpoch), @@ -531,54 +523,65 @@ func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, s return tx.Commit() } -func (st *storage) storeMiners(miners map[minerKey]*minerInfo) error { - /*tx, err := st.db.Begin() - if err != nil { - return err - } +func (st *storage) storeMiners(minerTips map[types.TipSetKey][]*newMinerInfo) error { + tx, err := st.db.Begin() + if err != nil { + return err + } - if _, err := tx.Exec(` + if _, err := tx.Exec(` create temp table mh (like miner_heads excluding constraints) on commit drop; `); err != nil { - return xerrors.Errorf("prep temp: %w", err) - } + return xerrors.Errorf("prep temp: %w", err) + } - stmt, err := tx.Prepare(`copy mh (head, addr, stateroot, sectorset, setsize, provingset, provingsize, owner, worker, peerid, sectorsize, power, ppe) from STDIN`) - if err != nil { - return err - } - for k, i := range miners { + stmt, err := tx.Prepare(`copy mh (addr, owner, worker, peerid, sectorsize, windowpostpartitionsectors, precommitdeposits, lockedfunds, nextdeadlineprocessfaults) from STDIN`) + if err != nil { + return err + } + for ts, miners := range minerTips { + for _, miner := range miners { + var pid string + if len(miner.info.PeerId) != 0 { + peerid, err := peer.IDFromBytes(miner.info.PeerId) + if err != nil { + // this should "never happen", but if it does we should still store info about the miner. + log.Warnw("failed to decode peerID", "peerID (bytes)", miner.info.PeerId, "miner", miner.addr, "tipset", ts.String()) + } else { + pid = peerid.String() + } + } if _, err := stmt.Exec( - k.act.Head.String(), - k.addr.String(), - k.stateroot.String(), - i.state.Sectors.String(), - fmt.Sprint(i.ssize), - i.state.ProvingSet.String(), - fmt.Sprint(i.psize), - i.info.Owner.String(), - i.info.Worker.String(), - i.info.PeerId.String(), - i.info.SectorSize, - i.power.String(), // TODO: SPA - i.state.PoStState.ProvingPeriodStart, + miner.addr.String(), + miner.info.Owner.String(), + miner.info.Worker.String(), + pid, + miner.info.SectorSize.ShortString(), + miner.info.WindowPoStPartitionSectors, + + miner.state.PreCommitDeposits.String(), + miner.state.LockedFunds.String(), + miner.state.NextDeadlineToProcessFaults, ); err != nil { + log.Errorw("failed to store miner state", miner.state) + log.Errorw("failed to store miner info", miner.info) return err } - } - if err := stmt.Close(); err != nil { - return err - } - if _, err := tx.Exec(`insert into miner_heads select * from mh on conflict do nothing `); err != nil { - return xerrors.Errorf("actor put: %w", err) } + } + if err := stmt.Close(); err != nil { + return err + } - return tx.Commit()*/ - return nil + if _, err := tx.Exec(`insert into miner_heads select * from mh on conflict do nothing `); err != nil { + return xerrors.Errorf("actor put: %w", err) + } + + return tx.Commit() } func (st *storage) storeHeaders(bhs map[cid.Cid]*types.BlockHeader, sync bool) error { diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index db9786d4c..9483113b6 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -123,7 +123,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. allToSync[bh.Cid()] = bh if len(allToSync)%500 == 10 { - log.Infof("to visit: (%d) %s @%d", len(allToSync), bh.Cid(), bh.Height) + log.Debugf("to visit: (%d) %s @%d", len(allToSync), bh.Cid(), bh.Height) } if len(bh.Parents) == 0 { @@ -276,7 +276,6 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. tsKey: pts.Key(), } addressToID[addr] = address.Undef - // alk.Unlock() } }) @@ -423,14 +422,12 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. } // TODO re-enable when ready to fill miner metadata, the contents of storeMiners is commented out too. - /* - log.Info("Storing miners") + log.Info("Storing miners") - if err := st.storeMiners(miners); err != nil { - log.Error(err) - return - } - */ + if err := st.storeMiners(minerTips); err != nil { + log.Error(err) + return + } log.Info("Storing miner sectors") From c811133aacf8dee300bb51d520f760c75672611c Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 19:37:52 +0200 Subject: [PATCH 304/379] Update go-log Signed-off-by: Jakub Sztandera --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ce9e48a66..90b4f1f65 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,7 @@ require ( github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf github.com/ipfs/go-ipld-format v0.2.0 github.com/ipfs/go-log v1.0.4 - github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7 + github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 github.com/ipfs/go-merkledag v0.3.1 github.com/ipfs/go-path v0.0.7 github.com/ipfs/go-unixfs v0.2.4 diff --git a/go.sum b/go.sum index 3f07626e0..0ee5cc615 100644 --- a/go.sum +++ b/go.sum @@ -591,8 +591,8 @@ github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= -github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7 h1:LtL/rvdfbKSthZGmAAD9o4KKg6HA6Qn8gXCCdgnj7lw= -github.com/ipfs/go-log/v2 v2.1.2-0.20200609205458-f8d20c392cb7/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 h1:3bijxqzQ1O9yg7gd7Aqk80oaEvsJ+uXw0zSvi2qR3Jw= +github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= From 49dccf4284ba5ef7ad14f98cdb559fe89f81239e Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Tue, 30 Jun 2020 14:24:08 -0400 Subject: [PATCH 305/379] fix: concurrent map access panic --- chain/events/events_called.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 3d8e05c02..04a87a545 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -443,8 +443,8 @@ func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, } we.lk.Lock() - we.matchers[id] = mf defer we.lk.Unlock() + we.matchers[id] = mf return nil } @@ -476,10 +476,11 @@ func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID]eventDat return nil, err } + me.lk.RLock() + defer me.lk.RUnlock() + res := make(map[triggerID]eventData) me.messagesForTs(pts, func(msg *types.Message) { - me.lk.RLock() - defer me.lk.RUnlock() // TODO: provide receipts for tid, matchFns := range me.matchers { From 6927a532cfd8679c55197baf47b978ff6340ddfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 30 Jun 2020 21:03:44 +0200 Subject: [PATCH 306/379] Update sector-storage with lower resource requirements --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d06d2bd97..4e9344f1f 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246 + github.com/filecoin-project/sector-storage v0.0.0-20200630180318-4c1968f62a8f github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea github.com/filecoin-project/storage-fsm v0.0.0-20200625160832-379a4655b044 diff --git a/go.sum b/go.sum index f984e5816..3002efe34 100644 --- a/go.sum +++ b/go.sum @@ -254,6 +254,8 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246 h1:NfYQRmVRe0LzlNbK5Ket3vbBOwFD5TvtcNtfo/Sd8mg= github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= +github.com/filecoin-project/sector-storage v0.0.0-20200630180318-4c1968f62a8f h1:EHKqNJNIcYggqfrd5nu7SV1KR93ReZygfdSV0w/jefQ= +github.com/filecoin-project/sector-storage v0.0.0-20200630180318-4c1968f62a8f/go.mod h1:r12d7tsmJKz8QDGoCvl65Ay2al6mOgDqxAGUxbyrgMs= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= From 8c54c09ab79742e877b7d97879e9304e453fd630 Mon Sep 17 00:00:00 2001 From: frrist Date: Tue, 30 Jun 2020 13:22:58 -0700 Subject: [PATCH 307/379] pair: work from pair with placer --- cmd/lotus-chainwatch/storage.go | 122 ++++++++++++++++++++++---------- cmd/lotus-chainwatch/sync.go | 34 +++------ 2 files changed, 93 insertions(+), 63 deletions(-) diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index e56cc9a9b..27cf361a0 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/libp2p/go-libp2p-core/peer" "sync" "time" @@ -258,35 +259,47 @@ create index if not exists receipts_msg_state_index create table if not exists miner_sectors ( - miner text not null, - sectorid bigint not null, - activation bigint not null, - dealweight bigint not null, - verifieddealweight bigint not null, - expiration bigint not null, - sealcid text not null, - sealrandepoch bigint not null, + miner_id text not null, + sector_id bigint not null, + activation_epoch bigint not null, + expiration_epoch bigint not null, + deal_weight text not null, + verified_deal_weight text not null, + seal_cid text not null, + seal_rand_epoch bigint not null, constraint miner_sectors_pk - primary key (miner, sectorid) + primary key (miner_id, sector_id) ); create index if not exists miner_sectors_miner_sectorid_index - on miner_sectors (miner, sectorid); + on miner_sectors (miner_id, sector_id); -create table if not exists miner_heads +create table if not exists miner_info ( - addr text not null, - owner text not null, - worker text not null, - peerid text, - sectorsize text not null, - windowpostpartitionsectors bigint not null, + miner_id text not null, + owner_addr text not null, + worker_addr text not null, + peer_id text, + sector_size text not null, - precommitdeposits text not null, - lockedfunds text not null, - nextdeadlineprocessfaults bigint not null, - constraint miner_heads_pk - primary key (addr) + precommit_deposits text not null, + locked_funds text not null, + next_deadline_process_faults bigint not null, + constraint miner_info_pk + primary key (miner_id) +); + +/* used to tell when a miners sectors (proven-not-yet-expired) changed if the miner_sectors_cid's are different a new sector was added or removed (terminated/expired) */ +create table if not exists miner_sectors_heads +( + miner_id text not null, + miner_sectors_cid text not null, + + state_root text not null, + + constraint miner_sectors_heads_pk + primary key (miner_id,miner_sectors_cid) + ); /* @@ -473,7 +486,7 @@ type storeSectorsAPI interface { StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) } -func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, sectorApi storeSectorsAPI) error { +func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*minerStateInfo, sectorApi storeSectorsAPI) error { tx, err := st.db.Begin() if err != nil { return err @@ -483,7 +496,7 @@ func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, s return xerrors.Errorf("prep temp: %w", err) } - stmt, err := tx.Prepare(`copy ms (miner, sectorid, activation, dealweight, verifieddealweight, expiration, sealcid, sealrandepoch) from STDIN `) + stmt, err := tx.Prepare(`copy ms (miner_id, sector_id, activation_epoch, expiration_epoch, deal_weight, verified_deal_weight, seal_cid, seal_rand_epoch) from STDIN`) if err != nil { return err } @@ -500,9 +513,9 @@ func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, s miner.addr.String(), uint64(sector.ID), int64(sector.Info.ActivationEpoch), - sector.Info.DealWeight.Uint64(), - sector.Info.VerifiedDealWeight.Uint64(), int64(sector.Info.Info.Expiration), + sector.Info.DealWeight.String(), + sector.Info.VerifiedDealWeight.String(), sector.Info.Info.SealedCID.String(), int64(sector.Info.Info.SealRandEpoch), ); err != nil { @@ -523,22 +536,17 @@ func (st *storage) storeSectors(minerTips map[types.TipSetKey][]*newMinerInfo, s return tx.Commit() } -func (st *storage) storeMiners(minerTips map[types.TipSetKey][]*newMinerInfo) error { +func (st *storage) storeMiners(minerTips map[types.TipSetKey][]*minerStateInfo) error { tx, err := st.db.Begin() if err != nil { return err } - if _, err := tx.Exec(` - - create temp table mh (like miner_heads excluding constraints) on commit drop; - - - `); err != nil { + if _, err := tx.Exec(`create temp table mi (like miner_info excluding constraints) on commit drop;`); err != nil { return xerrors.Errorf("prep temp: %w", err) } - stmt, err := tx.Prepare(`copy mh (addr, owner, worker, peerid, sectorsize, windowpostpartitionsectors, precommitdeposits, lockedfunds, nextdeadlineprocessfaults) from STDIN`) + stmt, err := tx.Prepare(`copy mi (miner_id, owner_addr, worker_addr, peer_id, sector_size, precommit_deposits, locked_funds, next_deadline_process_faults) from STDIN`) if err != nil { return err } @@ -560,14 +568,11 @@ func (st *storage) storeMiners(minerTips map[types.TipSetKey][]*newMinerInfo) er miner.info.Worker.String(), pid, miner.info.SectorSize.ShortString(), - miner.info.WindowPoStPartitionSectors, - miner.state.PreCommitDeposits.String(), miner.state.LockedFunds.String(), miner.state.NextDeadlineToProcessFaults, ); err != nil { - log.Errorw("failed to store miner state", miner.state) - log.Errorw("failed to store miner info", miner.info) + log.Errorw("failed to store miner state", "state", miner.state, "info", miner.info, "error", err) return err } @@ -577,7 +582,46 @@ func (st *storage) storeMiners(minerTips map[types.TipSetKey][]*newMinerInfo) er return err } - if _, err := tx.Exec(`insert into miner_heads select * from mh on conflict do nothing `); err != nil { + if _, err := tx.Exec(`insert into miner_info select * from mi on conflict do nothing `); err != nil { + return xerrors.Errorf("actor put: %w", err) + } + + return tx.Commit() +} + +func (st *storage) storeMinerSectorsHeads(minerTips map[types.TipSetKey][]*minerStateInfo) error { + tx, err := st.db.Begin() + if err != nil { + return err + } + + if _, err := tx.Exec(`create temp table msh (like miner_sectors_heads excluding constraints) on commit drop;`); err != nil { + return xerrors.Errorf("prep temp: %w", err) + } + + stmt, err := tx.Prepare(`copy msh (miner_id, miner_sectors_cid, state_root) from STDIN`) + if err != nil { + return err + } + + for _, miners := range minerTips { + for _, miner := range miners { + if _, err := stmt.Exec( + miner.addr.String(), + miner.state.Sectors.String(), + miner.stateroot.String(), + ); err != nil { + log.Errorw("failed to store miners sectors head", "state", miner.state, "info", miner.info, "error", err) + return err + } + + } + } + if err := stmt.Close(); err != nil { + return err + } + + if _, err := tx.Exec(`insert into miner_sectors_heads select * from msh on conflict do nothing `); err != nil { return xerrors.Errorf("actor put: %w", err) } diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index 9483113b6..d67f013e0 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -53,24 +53,7 @@ func runSyncer(ctx context.Context, api api.FullNode, st *storage, maxBatch int) }() } -type minerKey struct { - addr address.Address - act types.Actor - stateroot cid.Cid - tsKey types.TipSetKey -} - -type minerInfo struct { - state miner.State - info miner.MinerInfo - - rawPower big.Int - qalPower big.Int - ssize uint64 - psize uint64 -} - -type newMinerInfo struct { +type minerStateInfo struct { // common addr address.Address act types.Actor @@ -281,7 +264,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. }) // map of tipset to all miners that had a head-change at that tipset. - minerTips := make(map[types.TipSetKey][]*newMinerInfo, len(changes)) + minerTips := make(map[types.TipSetKey][]*minerStateInfo, len(changes)) // heads we've seen, im being paranoid headsSeen := make(map[cid.Cid]struct{}, len(actors)) @@ -324,7 +307,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. } minerChanges++ - minerTips[c.tsKey] = append(minerTips[c.tsKey], &newMinerInfo{ + minerTips[c.tsKey] = append(minerTips[c.tsKey], &minerStateInfo{ addr: addr, act: actor, stateroot: c.stateroot, @@ -344,7 +327,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. log.Infow("Processing miners", "numTips", len(minerTips), "numMinerChanges", minerChanges) // extract the power actor state at each tipset, loop over all miners that changed at said tipset and extract their // claims from the power actor state. This ensures we only fetch the power actors state once for each tipset. - parmap.Par(50, parmap.KVMapArr(minerTips), func(it func() (types.TipSetKey, []*newMinerInfo)) { + parmap.Par(50, parmap.KVMapArr(minerTips), func(it func() (types.TipSetKey, []*minerStateInfo)) { tsKey, minerInfo := it() // get the power actors claims map @@ -421,16 +404,13 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. return } - // TODO re-enable when ready to fill miner metadata, the contents of storeMiners is commented out too. log.Info("Storing miners") - if err := st.storeMiners(minerTips); err != nil { log.Error(err) return } log.Info("Storing miner sectors") - sectorStart := time.Now() if err := st.storeSectors(minerTips, api); err != nil { log.Error(err) @@ -438,6 +418,12 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. } log.Infow("Finished storing miner sectors", "duration", time.Since(sectorStart).String()) + log.Info("Storing miner sectors heads") + if err := st.storeMinerSectorsHeads(minerTips); err != nil { + log.Error(err) + return + } + log.Infof("Storing messages") if err := st.storeMessages(msgs); err != nil { From 77c7eb6fd9545add4b30f85f5d6488095d60f2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 30 Jun 2020 22:56:13 +0100 Subject: [PATCH 308/379] fix lint errors. --- chain/gen/gen.go | 2 +- node/impl/common/common.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index abbc87e93..ebf868765 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -414,7 +414,7 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke if cg.Timestamper != nil { ts = cg.Timestamper(parents, height-parents.Height()) } else { - ts = parents.MinTimestamp() + uint64(height-parents.Height())*uint64(build.BlockDelaySecs) + ts = parents.MinTimestamp() + uint64(height-parents.Height())*build.BlockDelaySecs } fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, &api.BlockTemplate{ diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 2d1beaa31..1d2695b6e 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -122,7 +122,7 @@ func (a *CommonAPI) Version(context.Context) (api.Version, error) { Version: build.UserVersion(), APIVersion: build.APIVersion, - BlockDelay: uint64(build.BlockDelaySecs), + BlockDelay: build.BlockDelaySecs, }, nil } From 2d180cdacfae10cd33b01adf1a4d0fc39ad628b3 Mon Sep 17 00:00:00 2001 From: jackoelv Date: Wed, 1 Jul 2020 09:45:40 +0800 Subject: [PATCH 309/379] Update mining-troubleshooting.md some code changed, document should be changed too. by default, bench is not maked by make 2k. so ,first make bench is safe. I have checked the makefile, the bundle name is not lotus-bench but 'bench'. --- documentation/en/mining-troubleshooting.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/en/mining-troubleshooting.md b/documentation/en/mining-troubleshooting.md index 111ae44f2..561031c5d 100644 --- a/documentation/en/mining-troubleshooting.md +++ b/documentation/en/mining-troubleshooting.md @@ -38,7 +38,7 @@ If you see this, that means your computer is too slow and your blocks are not in ## Error: No space left on device ```sh -lotus-storage-miner pledge-sector +lotus-storage-miner sectors pledge # No space left on device (os error 28) ``` @@ -51,7 +51,8 @@ If you suspect that your GPU is not being used, first make sure it is properly c First, to watch GPU utilization run `nvtop` in one terminal, then in a separate terminal, run: ```sh -lotus-bench --sector-size=2KiB +make bench +./bench sealing --sector-size=2KiB ``` This process uses a fair amount of GPU, and generally takes ~4 minutes to complete. If you do not see any activity in nvtop from lotus during the entire process, it is likely something is misconfigured with your GPU. From e576c7a08e500bd1e6cc5e737b382df0d7950197 Mon Sep 17 00:00:00 2001 From: frrist Date: Tue, 30 Jun 2020 21:26:46 -0700 Subject: [PATCH 310/379] "feat": add logic to update miner sector table on term --- cmd/lotus-chainwatch/storage.go | 154 +++++++++++++++++++++++++++++++- cmd/lotus-chainwatch/sync.go | 2 +- 2 files changed, 151 insertions(+), 5 deletions(-) diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index 27cf361a0..e68c586b5 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -3,13 +3,15 @@ package main import ( "context" "database/sql" - "github.com/filecoin-project/specs-actors/actors/abi" + "fmt" "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/libp2p/go-libp2p-core/peer" "sync" "time" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/abi" + miner_spec "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/ipfs/go-cid" _ "github.com/lib/pq" "golang.org/x/xerrors" @@ -22,6 +24,9 @@ type storage struct { db *sql.DB headerLk sync.Mutex + + // stateful miner data + minerSectors map[cid.Cid]struct{} } func openStorage(dbSource string) (*storage, error) { @@ -32,7 +37,10 @@ func openStorage(dbSource string) (*storage, error) { db.SetMaxOpenConns(1350) - st := &storage{db: db} + ms := make(map[cid.Cid]struct{}) + ms[cid.Undef] = struct{}{} + + st := &storage{db: db, minerSectors: ms} return st, st.setup() } @@ -261,8 +269,11 @@ create table if not exists miner_sectors ( miner_id text not null, sector_id bigint not null, + activation_epoch bigint not null, expiration_epoch bigint not null, + termination_epoch bigint, + deal_weight text not null, verified_deal_weight text not null, seal_cid text not null, @@ -589,7 +600,13 @@ func (st *storage) storeMiners(minerTips map[types.TipSetKey][]*minerStateInfo) return tx.Commit() } -func (st *storage) storeMinerSectorsHeads(minerTips map[types.TipSetKey][]*minerStateInfo) error { +type minerSectorUpdate struct { + minerState *minerStateInfo + tskey types.TipSetKey + oldSector cid.Cid +} + +func (st *storage) storeMinerSectorsHeads(minerTips map[types.TipSetKey][]*minerStateInfo, api api.FullNode) error { tx, err := st.db.Begin() if err != nil { return err @@ -604,8 +621,26 @@ func (st *storage) storeMinerSectorsHeads(minerTips map[types.TipSetKey][]*miner return err } - for _, miners := range minerTips { + var updateMiners []*minerSectorUpdate + for tsk, miners := range minerTips { for _, miner := range miners { + sectorCID, err := st.getLatestMinerSectorCID(context.TODO(), miner.addr) + if err != nil { + panic(err) + } + if sectorCID == cid.Undef { + continue + } + if _, found := st.minerSectors[sectorCID]; !found { + // schedule miner table update + updateMiners = append(updateMiners, &minerSectorUpdate{ + minerState: miner, + tskey: tsk, + oldSector: sectorCID, + }) + } + st.minerSectors[sectorCID] = struct{}{} + log.Debugw("got sector CID", "miner", miner.addr, "cid", sectorCID.String()) if _, err := stmt.Exec( miner.addr.String(), miner.state.Sectors.String(), @@ -625,6 +660,93 @@ func (st *storage) storeMinerSectorsHeads(minerTips map[types.TipSetKey][]*miner return xerrors.Errorf("actor put: %w", err) } + if err := tx.Commit(); err != nil { + return err + } + return st.updateMinerSectors(updateMiners, api) +} + +type deletedSector struct { + deletedSector miner_spec.SectorOnChainInfo + miner address.Address + tskey types.TipSetKey +} + +func (st *storage) updateMinerSectors(miners []*minerSectorUpdate, api api.FullNode) error { + log.Info("updating miners constant sector table") + var deletedSectors []*deletedSector + for _, miner := range miners { + s := &apiIpldStore{context.TODO(), api} + newSectors, err := adt.AsArray(s, miner.minerState.state.Sectors) + if err != nil { + log.Warnw("new sectors as array", "error", err, "cid", miner.minerState.state.Sectors) + return err + } + + oldSectors, err := adt.AsArray(s, miner.oldSector) + if err != nil { + log.Warnw("old sectors as array", "error", err, "cid", miner.oldSector.String()) + return err + } + + var oldSecInfo miner_spec.SectorOnChainInfo + var newSecInfo miner_spec.SectorOnChainInfo + // if we cannot find an old sector in the new list then it was removed. + if err := oldSectors.ForEach(&oldSecInfo, func(i int64) error { + found, err := newSectors.Get(uint64(oldSecInfo.Info.SectorNumber), &newSecInfo) + if err != nil { + log.Warnw("new sectors get", "error", err) + return err + } + if !found { + log.Infow("MINER DELETED SECTOR", "miner", miner.minerState.addr.String(), "sector", oldSecInfo.Info.SectorNumber, "tipset", miner.tskey.String()) + deletedSectors = append(deletedSectors, &deletedSector{ + deletedSector: oldSecInfo, + miner: miner.minerState.addr, + tskey: miner.tskey, + }) + } + return nil + }); err != nil { + log.Warnw("old sectors foreach", "error", err) + return err + } + if len(deletedSectors) > 0 { + log.Infow("Calculated updates", "miner", miner.minerState.addr, "deleted sectors", len(deletedSectors)) + } + } + // now we have all the sectors that were removed, update the database + tx, err := st.db.Begin() + if err != nil { + return err + } + stmt, err := tx.Prepare(`UPDATE miner_sectors SET termination_epoch=$1 WHERE miner_id=$2 AND sector_id=$3`) + if err != nil { + return err + } + for _, ds := range deletedSectors { + ts, err := api.ChainGetTipSet(context.TODO(), ds.tskey) + if err != nil { + log.Warnw("get tipset", "error", err) + return err + } + // TODO validate this shits right + if ts.Height() >= ds.deletedSector.Info.Expiration { + // means it expired, do nothing + log.Infow("expired sector", "miner", ds.miner.String(), "sector", ds.deletedSector.Info.SectorNumber) + continue + } + log.Infow("terminated sector", "miner", ds.miner.String(), "sector", ds.deletedSector.Info.SectorNumber) + // means it was terminated. + if _, err := stmt.Exec(int64(ts.Height()), ds.miner.String(), int64(ds.deletedSector.Info.SectorNumber)); err != nil { + return err + } + } + + if err := stmt.Close(); err != nil { + return err + } + defer log.Info("update miner sectors complete") return tx.Commit() } @@ -1130,3 +1252,27 @@ func (st *storage) refreshViews() error { func (st *storage) close() error { return st.db.Close() } + +func (st *storage) getLatestMinerSectorCID(ctx context.Context, miner address.Address) (cid.Cid, error) { + queryStr := fmt.Sprintf(` +SELECT miner_sectors_cid +FROM miner_sectors_heads +LEFT JOIN blocks ON miner_sectors_heads.state_root = blocks.parentstateroot +WHERE miner_id = '%s' +ORDER BY blocks.height DESC +LIMIT 1; +`, + miner.String()) + + var cidstr string + err := st.db.QueryRowContext(ctx, queryStr).Scan(&cidstr) + switch { + case err == sql.ErrNoRows: + log.Warnf("no miner with miner_id: %s in table", miner) + return cid.Undef, nil + case err != nil: + return cid.Undef, err + default: + return cid.Decode(cidstr) + } +} diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index d67f013e0..96821a262 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -419,7 +419,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, headTs *types. log.Infow("Finished storing miner sectors", "duration", time.Since(sectorStart).String()) log.Info("Storing miner sectors heads") - if err := st.storeMinerSectorsHeads(minerTips); err != nil { + if err := st.storeMinerSectorsHeads(minerTips, api); err != nil { log.Error(err) return } From da78ff9151afb9deb7b553501413b5ab9f127c21 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 30 Jun 2020 21:57:49 -0700 Subject: [PATCH 311/379] use bitfields to enumerate sectors for winning post --- chain/stmgr/utils.go | 55 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index cf424b4eb..1901c79eb 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/go-address" amt "github.com/filecoin-project/go-amt-ipld/v2" + "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" @@ -173,13 +174,34 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S return nil, xerrors.Errorf("(get sectors) failed to load miner actor state: %w", err) } - // TODO: Optimization: we could avoid loaditg the whole proving set here if we had AMT.GetNth with bitfield filtering - sectorSet, err := GetProvingSetRaw(ctx, sm, mas) - if err != nil { - return nil, xerrors.Errorf("getting proving set: %w", err) + cst := cbor.NewCborStore(sm.cs.Blockstore()) + var deadlines miner.Deadlines + if err := cst.Get(ctx, mas.Deadlines, &deadlines); err != nil { + return nil, xerrors.Errorf("failed to load deadlines: %w", err) } - if len(sectorSet) == 0 { + notProving, err := abi.BitFieldUnion(mas.Faults, mas.Recoveries) + if err != nil { + return nil, xerrors.Errorf("failed to union faults and recoveries: %w", err) + } + + allSectors, err := bitfield.MultiMerge(append(deadlines.Due[:], mas.NewSectors)...) + if err != nil { + return nil, xerrors.Errorf("merging deadline bitfields failed: %w", err) + } + + provingSectors, err := bitfield.SubtractBitField(allSectors, notProving) + if err != nil { + return nil, xerrors.Errorf("failed to subtract non-proving sectors from set: %w", err) + } + + numProvSect, err := provingSectors.Count() + if err != nil { + return nil, xerrors.Errorf("failed to count bits: %w", err) + } + + // TODO(review): is this right? feels fishy to me + if numProvSect == 0 { return nil, nil } @@ -198,17 +220,34 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S return nil, xerrors.Errorf("getting miner ID: %w", err) } - ids, err := pv.GenerateWinningPoStSectorChallenge(ctx, wpt, abi.ActorID(mid), rand, uint64(len(sectorSet))) + ids, err := pv.GenerateWinningPoStSectorChallenge(ctx, wpt, abi.ActorID(mid), rand, numProvSect) if err != nil { return nil, xerrors.Errorf("generating winning post challenges: %w", err) } + sectors, err := provingSectors.All(miner.SectorsMax) + if err != nil { + return nil, xerrors.Errorf("failed to enumerate all sector IDs: %w", err) + } + + sectorAmt, err := amt.LoadAMT(ctx, cst, mas.Sectors) + if err != nil { + return nil, xerrors.Errorf("failed to load sectors amt: %w", err) + } + out := make([]abi.SectorInfo, len(ids)) for i, n := range ids { + sid := sectors[n] + + var sinfo miner.SectorOnChainInfo + if err := sectorAmt.Get(ctx, sid, &sinfo); err != nil { + return nil, xerrors.Errorf("failed to get sector %d: %w", sid, err) + } + out[i] = abi.SectorInfo{ SealProof: spt, - SectorNumber: sectorSet[n].ID, - SealedCID: sectorSet[n].Info.Info.SealedCID, + SectorNumber: sinfo.Info.SectorNumber, + SealedCID: sinfo.Info.SealedCID, } } From 4c1dfd7eda17cfcd04f1cff5ea9a9ea0905b9da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 1 Jul 2020 11:24:26 +0200 Subject: [PATCH 312/379] sync: Fix build --- chain/sync.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/sync.go b/chain/sync.go index 78dfa4bc2..5253799dd 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -1534,5 +1534,5 @@ func (syncer *Syncer) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool { } now := uint64(time.Now().Unix()) - return epoch > (abi.ChainEpoch((now-g.Timestamp)/build.BlockDelay) + MaxHeightDrift) + return epoch > (abi.ChainEpoch((now-g.Timestamp)/build.BlockDelaySecs) + MaxHeightDrift) } From e949a458ecbf9d03aa717cfedd9fd5c614650fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 1 Jul 2020 12:53:27 +0200 Subject: [PATCH 313/379] miner: Fix mpool too-high-nonce-msgs log --- miner/miner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/miner.go b/miner/miner.go index 6ee11d55c..7f83321c4 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -561,7 +561,7 @@ func SelectMessages(ctx context.Context, al ActorLookup, ts *types.TipSet, msgs } if tooHighNonceMsgs > 0 { - log.Warnf("%d messages in mempool had too high nonce", tooLowFundMsgs) + log.Warnf("%d messages in mempool had too high nonce", tooHighNonceMsgs) } sm := time.Now() From 02c3f8ed8023ba6a609c8bf6a331f132d8320fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 1 Jul 2020 17:23:50 +0200 Subject: [PATCH 314/379] Update paramfetch --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 355bc160f..476cae1d7 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/filecoin-project/go-fil-markets v0.3.1 github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 - github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca + github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200630180318-4c1968f62a8f diff --git a/go.sum b/go.sum index 45316da02..60d30e59f 100644 --- a/go.sum +++ b/go.sum @@ -243,8 +243,8 @@ github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:9 github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE= github.com/filecoin-project/go-paramfetch v0.0.1/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= -github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca h1:OGykrCr6mSn/ckk2IFbIlkc76nsgEs7tSLhZXQt7+z4= -github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 h1:A256QonvzRaknIIAuWhe/M2dpV2otzs3NBhi5TWa/UA= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9 h1:k9qVR9ItcziSB2rxtlkN/MDWNlbsI6yzec+zjUatLW0= github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v0.0.0-20200612181802-4eb3d0c68eba h1:GEWb/6KQyNZt4jm8fgVcIFPH0ElAGXfHM59ZSiqPTvY= From 168b0f8df6e71d49839b2d1d1e490d1fa72d7a5e Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 1 Jul 2020 14:01:27 -0700 Subject: [PATCH 315/379] add perms listing to docgen output --- api/docgen/docgen.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index f876e280e..c9d8e8aa4 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -16,6 +16,7 @@ import ( "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/modules/dtypes" @@ -334,6 +335,9 @@ func main() { } } + permStruct := reflect.TypeOf(apistruct.FullNodeStruct{}.Internal) + commonPermStruct := reflect.TypeOf(apistruct.CommonStruct{}.Internal) + for _, g := range groupslice { g := g fmt.Printf("## %s\n", g.GroupName) @@ -347,6 +351,18 @@ func main() { fmt.Printf("### %s\n", m.Name) fmt.Printf("%s\n\n", m.Comment) + meth, ok := permStruct.FieldByName(m.Name) + if !ok { + meth, ok = commonPermStruct.FieldByName(m.Name) + if !ok { + panic("no perms for method: " + m.Name) + } + } + + perms := meth.Tag.Get("perm") + + fmt.Printf("Perms: %s\n\n", perms) + if strings.Count(m.InputExample, "\n") > 0 { fmt.Printf("Inputs:\n```json\n%s\n```\n\n", m.InputExample) } else { From 605e9bbbd7bb3a53d495d515cce3a38726946b94 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 30 Jun 2020 18:28:49 -0400 Subject: [PATCH 316/379] Add docs comments to API --- api/api_full.go | 146 ++++++++++++++++++++++++++++++++----------- chain/stmgr/utils.go | 2 +- 2 files changed, 112 insertions(+), 36 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index d5a256bd6..784651466 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -30,58 +30,59 @@ type FullNode interface { // MethodGroup: Chain // The Chain method group contains methods for interacting with the - // blockchain, but that do not require any form of state computation + // blockchain, but that do not require any form of state computation. - // ChainNotify returns channel with chain head updates - // First message is guaranteed to be of len == 1, and type == 'current' + // ChainNotify returns channel with chain head updates. + // First message is guaranteed to be of len == 1, and type == 'current'. ChainNotify(context.Context) (<-chan []*HeadChange, error) - // ChainHead returns the current head of the chain + // ChainHead returns the current head of the chain. ChainHead(context.Context) (*types.TipSet, error) - // ChainGetRandomness is used to sample the chain for randomness + // ChainGetRandomness is used to sample the chain for randomness. ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) - // ChainGetBlock returns the block specified by the given CID + // ChainGetBlock returns the block specified by the given CID. ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) + // ChainGetTipSet returns the tipset specified by the given TipSetKey. ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) - // ChainGetBlockMessages returns messages stored in the specified block + // ChainGetBlockMessages returns messages stored in the specified block. ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*BlockMessages, error) // ChainGetParentReceipts returns receipts for messages in parent tipset of - // the specified block + // the specified block. ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error) // ChainGetParentReceipts returns messages stored in parent tipset of the - // specified block + // specified block. ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]Message, error) // ChainGetTipSetByHeight looks back for a tipset at the specified epoch. // If there are no blocks at the specified epoch, a tipset at higher epoch - // will be returned + // will be returned. ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) // ChainReadObj reads ipld nodes referenced by the specified CID from chain - // blockstore and returns raw bytes + // blockstore and returns raw bytes. ChainReadObj(context.Context, cid.Cid) ([]byte, error) - // ChainHasObj checks if a given CID exists in the chain blockstore + // ChainHasObj checks if a given CID exists in the chain blockstore. ChainHasObj(context.Context, cid.Cid) (bool, error) ChainStatObj(context.Context, cid.Cid, cid.Cid) (ObjStat, error) - // ChainSetHead forcefully sets current chain head. Use with caution + // ChainSetHead forcefully sets current chain head. Use with caution. ChainSetHead(context.Context, types.TipSetKey) error - // ChainGetGenesis returns the genesis tipset + // ChainGetGenesis returns the genesis tipset. ChainGetGenesis(context.Context) (*types.TipSet, error) - // ChainTipSetWeight computes weight for the specified tipset + // ChainTipSetWeight computes weight for the specified tipset. ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error) ChainGetNode(ctx context.Context, p string) (*IpldObject, error) // ChainGetMessage reads a message referenced by the specified CID from the - // chain blockstore + // chain blockstore. ChainGetMessage(context.Context, cid.Cid) (*types.Message, error) // ChainGetPath returns a set of revert/apply operations needed to get from @@ -99,17 +100,17 @@ type FullNode interface { // Would return `[revert(tBA), apply(tAB), apply(tAA)]` ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error) - // ChainExport returns a stream of bytes with CAR dump of chain data + // ChainExport returns a stream of bytes with CAR dump of chain data. ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error) // MethodGroup: Sync // The Sync method group contains methods for interacting with and - // observing the lotus sync service + // observing the lotus sync service. - // SyncState returns the current status of the lotus sync system + // SyncState returns the current status of the lotus sync system. SyncState(context.Context) (*SyncState, error) - // SyncSubmitBlock can be used to submit a newly created block to the + // SyncSubmitBlock can be used to submit a newly created block to the. // network through this node SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error @@ -118,34 +119,34 @@ type FullNode interface { SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) // SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced. - // Use with extreme caution + // Use with extreme caution. SyncMarkBad(ctx context.Context, bcid cid.Cid) error // SyncCheckBad checks if a block was marked as bad, and if it was, returns - // the reason + // the reason. SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) // MethodGroup: Mpool // The Mpool methods are for interacting with the message pool. The message pool // manages all incoming and outgoing 'messages' going over the network. - // MpoolPending returns pending mempool messages + // MpoolPending returns pending mempool messages. MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) - // MpoolPush pushes a signed message to mempool + // MpoolPush pushes a signed message to mempool. MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error) // MpoolPushMessage atomically assigns a nonce, signs, and pushes a message - // to mempool + // to mempool. MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // MpoolGetNonce gets next nonce for the specified sender. - // Note that this method may not be atomic. Use MpoolPushMessage instead + // Note that this method may not be atomic. Use MpoolPushMessage instead. MpoolGetNonce(context.Context, address.Address) (uint64, error) MpoolSub(context.Context) (<-chan MpoolUpdate, error) // MpoolEstimateGasPrice estimates what gas price should be used for a - // message to have high likelihood of inclusion in `nblocksincl` epochs + // message to have high likelihood of inclusion in `nblocksincl` epochs. MpoolEstimateGasPrice(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) // MethodGroup: Miner @@ -157,17 +158,30 @@ type FullNode interface { // MethodGroup: Wallet + // WalletNew creates a new address in the wallet with the given sigType. WalletNew(context.Context, crypto.SigType) (address.Address, error) + // WalletHas indicates whether the given address is in the wallet. WalletHas(context.Context, address.Address) (bool, error) + // WalletHas indicates whether the given address is in the wallet. WalletList(context.Context) ([]address.Address, error) + // WalletBalance returns the balance of the given address at the current head of the chain. WalletBalance(context.Context, address.Address) (types.BigInt, error) + // WalletSign signs the given bytes using the given address. WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) + // WalletSignMessage signs the given message using the given address. WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) + // WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid. + // The address does not have to be in the wallet. WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) bool + // WalletDefaultAddress returns the address marked as default in the wallet. WalletDefaultAddress(context.Context) (address.Address, error) + // WalletSetDefault marks the given address as as the default one. WalletSetDefault(context.Context, address.Address) error + // WalletExport returns the private key of an address in the wallet. WalletExport(context.Context, address.Address) (*types.KeyInfo, error) + // WalletImport receives a KeyInfo, which includes a private key, and imports it into the wallet. WalletImport(context.Context, *types.KeyInfo) (address.Address, error) + // WalletDelete deletes an address from the wallet. WalletDelete(context.Context, address.Address) error // Other @@ -176,19 +190,27 @@ type FullNode interface { // The Client methods all have to do with interacting with the storage and // retrieval markets as a client - // ClientImport imports file under the specified path into filestore + // ClientImport imports file under the specified path into filestore. ClientImport(ctx context.Context, ref FileRef) (cid.Cid, error) - // ClientStartDeal proposes a deal with a miner + // ClientStartDeal proposes a deal with a miner. ClientStartDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error) - // ClientGetDeal info returns the latest information about a given deal + // ClientGetDealInfo returns the latest information about a given deal. ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) + // ClientListDeals returns information about the deals made by the local client. ClientListDeals(ctx context.Context) ([]DealInfo, error) + // ClientHasLocal indicates whether a certain CID is locally stored. ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) + // ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer). ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) + // ClientMinerQueryOffer returns a QueryOffer for the specific miner and file. ClientMinerQueryOffer(ctx context.Context, root cid.Cid, miner address.Address) (QueryOffer, error) + // ClientRetrieve initiates the retrieval of a file, as specified in the order. ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error + // ClientQueryAsk returns a signed StorageAsk from the specified miner. ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) + // ClientCalcCommP calculates the CommP for a specified file, based on the sector size of the provided miner. ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*CommPRet, error) + // ClientGenCar generates a CAR file for the specified file. ClientGenCar(ctx context.Context, ref FileRef, outpath string) error // ClientUnimport removes references to the specified file from filestore @@ -200,54 +222,107 @@ type FullNode interface { //ClientListAsks() []Ask // MethodGroup: State - // The State methods are used to query, inspect, and interact with chain state + // The State methods are used to query, inspect, and interact with chain state. + // All methods take a TipSetKey as a parameter. The state looked up is the state at that tipset. + // A nil TipSetKey can be provided as a param, this will cause the heaviest tipset in the chain to be used. - // if tipset is nil, we'll use heaviest + // StateCall runs the given message and returns its result without any persisted changes. StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error) + // StateReplay returns the result of executing the indicated message, assuming it was executed in the indicated tipset. StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error) + // StateGetActor returns the indicated actor's nonce and balance. StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) + // StateReadState returns the indicated actor's state. StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error) + // StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height. StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) + // StateNetworkName returns the name of the network the node is synced to StateNetworkName(context.Context) (dtypes.NetworkName, error) + // StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included. + // If the filterOut boolean is set to true, any sectors in the filter are excluded. + // If false, only those sectors in the filter are included. StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error) + // StateMinerProvingSet returns info about those sectors that a given miner is actively proving. StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error) + // StateMinerProvingDeadline calculates the deadline at some epoch for a proving period + // and returns the deadline-related calculations. StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) + // StateMinerPower returns the power of the indicated miner StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error) + // StateMinerInfo returns info about the indicated miner StateMinerInfo(context.Context, address.Address, types.TipSetKey) (MinerInfo, error) + // StateMinerDeadlines returns all the proving deadlines for the given miner StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error) + // StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner StateMinerFaults(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error) - // Returns all non-expired Faults that occur within lookback epochs of the given tipset + // StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*Fault, error) + // StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error) + // StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) + // StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) + // StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) + // StateSectorGetInfo returns the on-chain info for the specified miner's sector StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error) + // StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error) + // StateWaitMsg looks back in the chain for a message. If not found, it blocks until the + // message arrives on chain, and gets to the indicated confidence depth. + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error) + // StateListMiners returns the addresses of every miner that has claimed power in the Power Actor StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) + // StateListActors returns the addresses of every actor in the state StateListActors(context.Context, types.TipSetKey) ([]address.Address, error) + // StateMarketBalance looks up the Escrow and Locked balances of the given address in the Storage Market StateMarketBalance(context.Context, address.Address, types.TipSetKey) (MarketBalance, error) + // StateMarketParticipants returns the Escrow and Locked balances of every participant in the Storage Market StateMarketParticipants(context.Context, types.TipSetKey) (map[string]MarketBalance, error) + // StateMarketDeals returns information about every deal in the Storage Market StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error) + // StateMarketStorageDeal returns information about the indicated deal StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error) + // StateLookupID retrieves the ID address of the given address StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) + // StateAccountKey returns the public key address of the given ID address StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) + // StateChangedActors returns all the actors whose states change between the two given state CIDs + // TODO: Should this take tipset keys instead? StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) + // StateGetReceipt returns the message receipt for the given message StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) + // StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error) + // StateCompute is a flexible command that applies the given messages on the given tipset. + // The messages are run as though the VM were at the provided height. StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error) // MethodGroup: Msig // The Msig methods are used to interact with multisig wallets on the // filecoin network + // MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) + // MsigGetAvailableBalance creates a multisig wallet + // It takes the following params: , , , + // , MsigCreate(context.Context, int64, []address.Address, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) + // MsigPropose proposes a multisig message + // It takes the following params: , , , + // , , MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) + // MsigApprove approves a previously-proposed multisig message + // It takes the following params: , , , , , + // , , MsigApprove(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) + // MsigCancel cancels a previously-proposed multisig message + // It takes the following params: , , , , , + // , , + // TODO: You can't cancel someone else's proposed message, so "src" and "proposer" here are redundant MsigCancel(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) MarketEnsureAvailable(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error) @@ -304,7 +379,8 @@ type DealInfo struct { type MsgLookup struct { Receipt types.MessageReceipt - TipSet *types.TipSet + // TODO: This should probably a tipsetkey? + TipSet *types.TipSet } type BlockMessages struct { diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 1901c79eb..fd99deef1 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -38,7 +38,7 @@ func GetNetworkName(ctx context.Context, sm *StateManager, st cid.Cid) (dtypes.N var state init_.State _, err := sm.LoadActorStateRaw(ctx, builtin.InitActorAddr, &state, st) if err != nil { - return "", xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) + return "", xerrors.Errorf("(get sset) failed to load init actor state: %w", err) } return dtypes.NetworkName(state.NetworkName), nil From f8a1fb2321b7f471840413bdc3fc7c18ad68c3cd Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 1 Jul 2020 15:51:21 -0700 Subject: [PATCH 317/379] fix vm abortf log message --- chain/vm/runtime.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 595664de1..1b85d5aae 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -312,7 +312,7 @@ func (rt *Runtime) Context() context.Context { } func (rt *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) { - log.Warnf("Abortf: ", fmt.Sprintf(msg, args...)) + log.Warnf("Abortf: " + fmt.Sprintf(msg, args...)) panic(aerrors.NewfSkip(2, code, msg, args...)) } From ffd012906cc84cd713d402eb49934e90a65a4179 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 1 Jul 2020 16:20:05 -0700 Subject: [PATCH 318/379] add peer ID to hello protocol failure log --- node/modules/services.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/modules/services.go b/node/modules/services.go index 35cc8f40b..d439843c4 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -41,7 +41,7 @@ func RunHello(mctx helpers.MetricsCtx, lc fx.Lifecycle, h host.Host, svc *hello. pic := evt.(event.EvtPeerIdentificationCompleted) go func() { if err := svc.SayHello(helpers.LifecycleCtx(mctx, lc), pic.Peer); err != nil { - log.Warnw("failed to say hello", "error", err) + log.Warnw("failed to say hello", "error", err, "peer", pic.Peer) return } }() From a5935486ef4da7b669ec686fbd76fa0a72aa5e82 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 1 Jul 2020 17:09:21 -0700 Subject: [PATCH 319/379] have lotus attempt to raise its own file descriptor limit --- cmd/lotus/daemon.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 912e65253..bb17c0d87 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -32,6 +32,7 @@ import ( "github.com/filecoin-project/lotus/chain/vm" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/peermgr" + "github.com/filecoin-project/lotus/lib/ulimit" "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/modules" @@ -113,6 +114,11 @@ var DaemonCmd = &cli.Command{ Name: "profile", Usage: "specify type of node", }, + &cli.BoolFlag{ + Name: "manage-fdlimit", + Usage: "manage open file limit", + Value: true, + }, }, Action: func(cctx *cli.Context) error { err := runmetrics.Enable(runmetrics.RunMetricOptions{ @@ -122,6 +128,13 @@ var DaemonCmd = &cli.Command{ if err != nil { return xerrors.Errorf("enabling runtime metrics: %w", err) } + + if cctx.Bool("manage-fdlimit") { + if _, _, err := ulimit.ManageFdLimit(); err != nil { + log.Errorf("setting file descriptor limit: %s", err) + } + } + if prof := cctx.String("pprof"); prof != "" { profile, err := os.Create(prof) if err != nil { From 7e1e9bcd609a6561df7c2d21aec598c5e9647c55 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Thu, 2 Jul 2020 08:03:10 -0700 Subject: [PATCH 320/379] fix(markets): upgrade markets to 0.3.1.1 upgrade to 0.3.1.1 to get critical node restart fixes and retrieval map access fix --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 476cae1d7..ec3f20ebc 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.3.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 - github.com/filecoin-project/go-fil-markets v0.3.1 + github.com/filecoin-project/go-fil-markets v0.3.2-0.20200702145639-4034a18364e4 github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 diff --git a/go.sum b/go.sum index 60d30e59f..21349bbb6 100644 --- a/go.sum +++ b/go.sum @@ -235,8 +235,8 @@ github.com/filecoin-project/go-data-transfer v0.3.0 h1:BwBrrXu9Unh9JjjX4GAc5FfzU github.com/filecoin-project/go-data-transfer v0.3.0/go.mod h1:cONglGP4s/d+IUQw5mWZrQK+FQATQxr3AXzi4dRh0l4= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo= github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= -github.com/filecoin-project/go-fil-markets v0.3.1 h1:YLH4ck4hQrKBpQ3fo0VcA2SXqiAosizxBJ/QHYgR9aE= -github.com/filecoin-project/go-fil-markets v0.3.1/go.mod h1:UY+/zwNXHN73HcrN6HxNDpv6KKM6ehqfCuE9vK9khF8= +github.com/filecoin-project/go-fil-markets v0.3.2-0.20200702145639-4034a18364e4 h1:VqNmKGy4/ryzo/TqevSa1kancc3hSdws7sl/NCTZzT0= +github.com/filecoin-project/go-fil-markets v0.3.2-0.20200702145639-4034a18364e4/go.mod h1:UY+/zwNXHN73HcrN6HxNDpv6KKM6ehqfCuE9vK9khF8= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms= github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM= github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= From c97720e731b6c275e41e17c179576c57ba95c451 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 20:42:29 +0200 Subject: [PATCH 321/379] Fix import analyze Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index ebc62aa5d..71457a708 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -253,12 +253,16 @@ var importAnalyzeCmd = &cli.Command{ if err != nil { return err } + dec := json.NewDecoder(fi) var results []TipSetExec for { var tse TipSetExec - if err := json.NewDecoder(fi).Decode(&tse); err != nil { + if err := dec.Decode(&tse); err != nil { if err != io.EOF { + if e, ok := err.(*json.SyntaxError); ok { + log.Warnf("syntax error at byte offset %d", e.Offset) + } return err } break @@ -310,6 +314,9 @@ var importAnalyzeCmd = &cli.Command{ fmt.Println("Average time per epoch: ", totalTime/time.Duration(len(results))) n := 30 + if len(invocs) < n { + n = len(invocs) + } fmt.Printf("Top %d most expensive calls:\n", n) for i := 0; i < n; i++ { inv := invocs[i].Invoc From e65215f1b54cf45d77f2449a062b8bb8099ca0e0 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 21:54:20 +0200 Subject: [PATCH 322/379] Make lotus-bench import analyze multithreaded and less RAM hungry Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 89 ++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 71457a708..58de65fb8 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -255,7 +255,55 @@ var importAnalyzeCmd = &cli.Command{ } dec := json.NewDecoder(fi) - var results []TipSetExec + const nWorkers = 16 + tseIn := make(chan TipSetExec, 2*nWorkers) + type result struct { + totalTime time.Duration + chargeDeltas map[string][]float64 + expensiveInvocs []Invocation + } + + results := make(chan result, nWorkers) + + for i := 0; i < nWorkers; i++ { + go func() { + chargeDeltas := make(map[string][]float64) + var totalTime time.Duration + var expensiveInvocs []Invocation + var leastExpensiveInvoc = time.Duration(0) + + for { + tse, ok := <-tseIn + if !ok { + results <- result{ + totalTime: totalTime, + chargeDeltas: chargeDeltas, + expensiveInvocs: expensiveInvocs, + } + return + } + totalTime += tse.Duration + for _, inv := range tse.Trace { + if inv.Duration > leastExpensiveInvoc { + expensiveInvocs = append(expensiveInvocs, Invocation{ + TipSet: tse.TipSet, + Invoc: inv, + }) + } + + tallyGasCharges(chargeDeltas, &inv.ExecutionTrace) + } + sort.Slice(expensiveInvocs, func(i, j int) bool { + return expensiveInvocs[i].Invoc.Duration > expensiveInvocs[j].Invoc.Duration + }) + if len(expensiveInvocs) != 0 { + leastExpensiveInvoc = expensiveInvocs[len(expensiveInvocs)-1].Invoc.Duration + } + } + }() + } + + var totalTipsets int64 for { var tse TipSetExec if err := dec.Decode(&tse); err != nil { @@ -267,32 +315,31 @@ var importAnalyzeCmd = &cli.Command{ } break } - results = append(results, tse) + totalTipsets++ + tseIn <- tse + if totalTipsets%10 == 0 { + fmt.Printf("\rProcessed %d tipsets", totalTipsets) + } } - - chargeDeltas := make(map[string][]float64) + close(tseIn) + fmt.Printf("\n") + fmt.Printf("Collecting results\n") var invocs []Invocation var totalTime time.Duration - for i, r := range results { - _ = i - totalTime += r.Duration - - for _, inv := range r.Trace { - invocs = append(invocs, Invocation{ - TipSet: r.TipSet, - Invoc: inv, - }) - - cgas, vgas := countGasCosts(&inv.ExecutionTrace) - fmt.Printf("Invocation: %d %s: %s %d -> %0.2f\n", inv.Msg.Method, inv.Msg.To, inv.Duration, cgas+vgas, float64(GasPerNs*inv.Duration.Nanoseconds())/float64(cgas+vgas)) - - tallyGasCharges(chargeDeltas, &inv.ExecutionTrace) - + var keys []string + var chargeDeltas = make(map[string][]float64) + for i := 0; i < nWorkers; i++ { + fmt.Printf("\rProcessing results from worker %d/%d", i+1, nWorkers) + res := <-results + invocs = append(invocs, res.expensiveInvocs...) + for k, v := range res.chargeDeltas { + chargeDeltas[k] = append(chargeDeltas[k], v...) } + totalTime += res.totalTime } - var keys []string + fmt.Printf("\nCollecting gas keys\n") for k := range chargeDeltas { keys = append(keys, k) } @@ -311,7 +358,7 @@ var importAnalyzeCmd = &cli.Command{ }) fmt.Println("Total time: ", totalTime) - fmt.Println("Average time per epoch: ", totalTime/time.Duration(len(results))) + fmt.Println("Average time per epoch: ", totalTime/time.Duration(totalTipsets)) n := 30 if len(invocs) < n { From db5929f4a54f18b8573558bd0072853076910269 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 21:56:34 +0200 Subject: [PATCH 323/379] Limit size of expensiveInvocs Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 58de65fb8..959629d6a 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -299,6 +299,7 @@ var importAnalyzeCmd = &cli.Command{ if len(expensiveInvocs) != 0 { leastExpensiveInvoc = expensiveInvocs[len(expensiveInvocs)-1].Invoc.Duration } + expensiveInvocs = expensiveInvocs[:30] } }() } From 04edeccbf4b74b64b28519f3f7fd8163f41a3369 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 21:57:57 +0200 Subject: [PATCH 324/379] fix trimming Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 959629d6a..8c420e3c9 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -298,8 +298,12 @@ var importAnalyzeCmd = &cli.Command{ }) if len(expensiveInvocs) != 0 { leastExpensiveInvoc = expensiveInvocs[len(expensiveInvocs)-1].Invoc.Duration + n := 30 + if len(expensiveInvocs) < n { + n = len(expensiveInvocs) + } + expensiveInvocs = expensiveInvocs[:n] } - expensiveInvocs = expensiveInvocs[:30] } }() } From 710286d6e7f827f8e70c58d065005ab77a4d39ba Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 22:18:43 +0200 Subject: [PATCH 325/379] Add pprof Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 8c420e3c9..98a408556 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -7,6 +7,8 @@ import ( "io" "io/ioutil" "math" + "net/http" + _ "net/http/pprof" "os" "runtime" "runtime/pprof" @@ -249,6 +251,10 @@ var importAnalyzeCmd = &cli.Command{ return nil } + go func() { + http.ListenAndServe("localhost:6060", nil) + }() + fi, err := os.Open(cctx.Args().First()) if err != nil { return err @@ -282,6 +288,7 @@ var importAnalyzeCmd = &cli.Command{ } return } + totalTime += tse.Duration for _, inv := range tse.Trace { if inv.Duration > leastExpensiveInvoc { From 87d668390ec1cc529dce3c625a4bc45c8591335f Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 22:26:03 +0200 Subject: [PATCH 326/379] Use float32 Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 98a408556..a6e8de3a4 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -210,29 +210,29 @@ func countGasCosts(et *types.ExecutionTrace) (int64, int64) { return cgas, vgas } -func compStats(vals []float64) (float64, float64) { - var sum float64 +func compStats(vals []float32) (float32, float32) { + var sum float32 for _, v := range vals { sum += v } - av := sum / float64(len(vals)) + av := sum / float32(len(vals)) - var varsum float64 + var varsum float32 for _, v := range vals { delta := av - v varsum += delta * delta } - return av, math.Sqrt(varsum / float64(len(vals))) + return av, float32(math.Sqrt(float64(varsum / float32(len(vals))))) } -func tallyGasCharges(charges map[string][]float64, et *types.ExecutionTrace) { +func tallyGasCharges(charges map[string][]float32, et *types.ExecutionTrace) { for _, gc := range et.GasCharges { compGas := gc.ComputeGas + gc.VirtualComputeGas - ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) + ratio := float32(compGas) / float32(gc.TimeTaken.Nanoseconds()) charges[gc.Name] = append(charges[gc.Name], 1/(ratio/GasPerNs)) //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) @@ -265,7 +265,7 @@ var importAnalyzeCmd = &cli.Command{ tseIn := make(chan TipSetExec, 2*nWorkers) type result struct { totalTime time.Duration - chargeDeltas map[string][]float64 + chargeDeltas map[string][]float32 expensiveInvocs []Invocation } @@ -273,7 +273,7 @@ var importAnalyzeCmd = &cli.Command{ for i := 0; i < nWorkers; i++ { go func() { - chargeDeltas := make(map[string][]float64) + chargeDeltas := make(map[string][]float32) var totalTime time.Duration var expensiveInvocs []Invocation var leastExpensiveInvoc = time.Duration(0) @@ -340,7 +340,7 @@ var importAnalyzeCmd = &cli.Command{ var invocs []Invocation var totalTime time.Duration var keys []string - var chargeDeltas = make(map[string][]float64) + var chargeDeltas = make(map[string][]float32) for i := 0; i < nWorkers; i++ { fmt.Printf("\rProcessing results from worker %d/%d", i+1, nWorkers) res := <-results From 3134fcb54ac72505e9af66ce9ab403e430a11a00 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 23:08:06 +0200 Subject: [PATCH 327/379] Streaming mean and variance Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 74 +++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index a6e8de3a4..8f423437b 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -228,13 +228,54 @@ func compStats(vals []float32) (float32, float32) { return av, float32(math.Sqrt(float64(varsum / float32(len(vals))))) } -func tallyGasCharges(charges map[string][]float32, et *types.ExecutionTrace) { +type stats struct { + count float64 + mean float64 + dSqr float64 +} + +func (s *stats) AddPoint(value float64) { + s.count++ + meanDiff := (value - s.mean) / s.count + newMean := s.mean + meanDiff + + dSqrtInc := (value - newMean) * (value - s.mean) + s.dSqr += dSqrtInc + s.mean = newMean +} + +func (s *stats) variance() float64 { + return s.dSqr / (s.count - 1) +} + +func (s1 *stats) Combine(s2 *stats) { + if s1.count == 0 { + *s1 = *s2 + } + newCount := s1.count + s2.count + newMean := s1.count*s1.mean + s2.count*s2.mean + newMean /= newCount + newVar := s1.count * (s1.variance() + (s1.mean-newMean)*(s1.mean-newMean)) + newVar += s2.count * (s2.variance() + (s2.mean-newMean)*(s2.mean-newMean)) + newVar /= newCount + s1.count = newCount + s1.mean = newMean + s1.dSqr = newVar * (newCount - 1) +} + +func tallyGasCharges(charges map[string]*stats, et *types.ExecutionTrace) { for _, gc := range et.GasCharges { compGas := gc.ComputeGas + gc.VirtualComputeGas - ratio := float32(compGas) / float32(gc.TimeTaken.Nanoseconds()) + ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) - charges[gc.Name] = append(charges[gc.Name], 1/(ratio/GasPerNs)) + s := charges[gc.Name] + if s == nil { + s = new(stats) + charges[gc.Name] = s + } + + s.AddPoint(ratio) //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) for _, sub := range et.Subcalls { tallyGasCharges(charges, &sub) @@ -265,7 +306,7 @@ var importAnalyzeCmd = &cli.Command{ tseIn := make(chan TipSetExec, 2*nWorkers) type result struct { totalTime time.Duration - chargeDeltas map[string][]float32 + chargeStats map[string]*stats expensiveInvocs []Invocation } @@ -273,7 +314,7 @@ var importAnalyzeCmd = &cli.Command{ for i := 0; i < nWorkers; i++ { go func() { - chargeDeltas := make(map[string][]float32) + chargeStats := make(map[string]*stats) var totalTime time.Duration var expensiveInvocs []Invocation var leastExpensiveInvoc = time.Duration(0) @@ -283,7 +324,7 @@ var importAnalyzeCmd = &cli.Command{ if !ok { results <- result{ totalTime: totalTime, - chargeDeltas: chargeDeltas, + chargeStats: chargeStats, expensiveInvocs: expensiveInvocs, } return @@ -298,7 +339,7 @@ var importAnalyzeCmd = &cli.Command{ }) } - tallyGasCharges(chargeDeltas, &inv.ExecutionTrace) + tallyGasCharges(chargeStats, &inv.ExecutionTrace) } sort.Slice(expensiveInvocs, func(i, j int) bool { return expensiveInvocs[i].Invoc.Duration > expensiveInvocs[j].Invoc.Duration @@ -340,29 +381,32 @@ var importAnalyzeCmd = &cli.Command{ var invocs []Invocation var totalTime time.Duration var keys []string - var chargeDeltas = make(map[string][]float32) + var charges = make(map[string]*stats) for i := 0; i < nWorkers; i++ { fmt.Printf("\rProcessing results from worker %d/%d", i+1, nWorkers) res := <-results invocs = append(invocs, res.expensiveInvocs...) - for k, v := range res.chargeDeltas { - chargeDeltas[k] = append(chargeDeltas[k], v...) + for k, v := range res.chargeStats { + s := charges[k] + if s == nil { + s = new(stats) + charges[k] = s + } + s.Combine(v) } totalTime += res.totalTime } fmt.Printf("\nCollecting gas keys\n") - for k := range chargeDeltas { + for k := range charges { keys = append(keys, k) } fmt.Println("Gas Price Deltas") sort.Strings(keys) for _, k := range keys { - vals := chargeDeltas[k] - av, stdev := compStats(vals) - - fmt.Printf("%s: incr by %f (%f)\n", k, av, stdev) + s := charges[k] + fmt.Printf("%s: incr by %f (%f)\n", k, s.mean, math.Sqrt(s.variance())) } sort.Slice(invocs, func(i, j int) bool { From 9712bbc854b0ff65540c9ab4761c817715f25879 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 23:38:06 +0200 Subject: [PATCH 328/379] Decode in workers Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 44 +++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 8f423437b..bb7b229c6 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "context" "encoding/json" "fmt" @@ -300,10 +301,9 @@ var importAnalyzeCmd = &cli.Command{ if err != nil { return err } - dec := json.NewDecoder(fi) const nWorkers = 16 - tseIn := make(chan TipSetExec, 2*nWorkers) + jsonIn := make(chan []byte, 2*nWorkers) type result struct { totalTime time.Duration chargeStats map[string]*stats @@ -316,11 +316,15 @@ var importAnalyzeCmd = &cli.Command{ go func() { chargeStats := make(map[string]*stats) var totalTime time.Duration - var expensiveInvocs []Invocation + const invocsKeep = 32 + var expensiveInvocs = make([]Invocation, 0, 8*invocsKeep) var leastExpensiveInvoc = time.Duration(0) for { - tse, ok := <-tseIn + b, ok := <-jsonIn + var tse TipSetExec + + json.Unmarshal(b, &tse) if !ok { results <- result{ totalTime: totalTime, @@ -341,10 +345,11 @@ var importAnalyzeCmd = &cli.Command{ tallyGasCharges(chargeStats, &inv.ExecutionTrace) } - sort.Slice(expensiveInvocs, func(i, j int) bool { - return expensiveInvocs[i].Invoc.Duration > expensiveInvocs[j].Invoc.Duration - }) - if len(expensiveInvocs) != 0 { + if len(expensiveInvocs) > 4*invocsKeep { + sort.Slice(expensiveInvocs, func(i, j int) bool { + log.Warnf("i: %v, j: %v", expensiveInvocs[i], expensiveInvocs[j]) + return expensiveInvocs[i].Invoc.Duration > expensiveInvocs[j].Invoc.Duration + }) leastExpensiveInvoc = expensiveInvocs[len(expensiveInvocs)-1].Invoc.Duration n := 30 if len(expensiveInvocs) < n { @@ -357,24 +362,23 @@ var importAnalyzeCmd = &cli.Command{ } var totalTipsets int64 + reader := bufio.NewReader(fi) for { - var tse TipSetExec - if err := dec.Decode(&tse); err != nil { - if err != io.EOF { - if e, ok := err.(*json.SyntaxError); ok { - log.Warnf("syntax error at byte offset %d", e.Offset) - } - return err + b, err := reader.ReadBytes('\n') + if err != nil && err != io.EOF { + if e, ok := err.(*json.SyntaxError); ok { + log.Warnf("syntax error at byte offset %d", e.Offset) } - break + return err } totalTipsets++ - tseIn <- tse - if totalTipsets%10 == 0 { - fmt.Printf("\rProcessed %d tipsets", totalTipsets) + jsonIn <- b + fmt.Printf("\rProcessed %d tipsets", totalTipsets) + if err == io.EOF { + break } } - close(tseIn) + close(jsonIn) fmt.Printf("\n") fmt.Printf("Collecting results\n") From b5ae3c055b727fc7e0e17d549856dabbb82c67a3 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 26 Jun 2020 23:38:54 +0200 Subject: [PATCH 329/379] Remove warning Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index bb7b229c6..a8d962ff0 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -347,7 +347,6 @@ var importAnalyzeCmd = &cli.Command{ } if len(expensiveInvocs) > 4*invocsKeep { sort.Slice(expensiveInvocs, func(i, j int) bool { - log.Warnf("i: %v, j: %v", expensiveInvocs[i], expensiveInvocs[j]) return expensiveInvocs[i].Invoc.Duration > expensiveInvocs[j].Invoc.Duration }) leastExpensiveInvoc = expensiveInvocs[len(expensiveInvocs)-1].Invoc.Duration From 49ddcdb4b04d662702ae6b7886e9d93310de2c76 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 01:09:35 +0200 Subject: [PATCH 330/379] Don't pass pointers Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index a8d962ff0..4f1f87c4f 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -264,7 +264,7 @@ func (s1 *stats) Combine(s2 *stats) { s1.dSqr = newVar * (newCount - 1) } -func tallyGasCharges(charges map[string]*stats, et *types.ExecutionTrace) { +func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { for _, gc := range et.GasCharges { compGas := gc.ComputeGas + gc.VirtualComputeGas @@ -279,7 +279,7 @@ func tallyGasCharges(charges map[string]*stats, et *types.ExecutionTrace) { s.AddPoint(ratio) //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) for _, sub := range et.Subcalls { - tallyGasCharges(charges, &sub) + tallyGasCharges(charges, sub) } } @@ -343,7 +343,7 @@ var importAnalyzeCmd = &cli.Command{ }) } - tallyGasCharges(chargeStats, &inv.ExecutionTrace) + tallyGasCharges(chargeStats, inv.ExecutionTrace) } if len(expensiveInvocs) > 4*invocsKeep { sort.Slice(expensiveInvocs, func(i, j int) bool { From e5a7cb635c3f3c91a6961ff00bc82abb4d33fc9f Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 01:12:43 +0200 Subject: [PATCH 331/379] Siwtch back to float64 Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 4f1f87c4f..76c05135b 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -211,22 +211,22 @@ func countGasCosts(et *types.ExecutionTrace) (int64, int64) { return cgas, vgas } -func compStats(vals []float32) (float32, float32) { - var sum float32 +func compStats(vals []float64) (float64, float64) { + var sum float64 for _, v := range vals { sum += v } - av := sum / float32(len(vals)) + av := sum / float64(len(vals)) - var varsum float32 + var varsum float64 for _, v := range vals { delta := av - v varsum += delta * delta } - return av, float32(math.Sqrt(float64(varsum / float32(len(vals))))) + return av, float64(math.Sqrt(float64(varsum / float64(len(vals))))) } type stats struct { From 78ee64d9f8bcf69ad6eca2cf7c720ea042fa8df7 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 01:18:06 +0200 Subject: [PATCH 332/379] Fix stupid mistake Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 76c05135b..a9000f0da 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -278,11 +278,10 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { s.AddPoint(ratio) //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) - for _, sub := range et.Subcalls { - tallyGasCharges(charges, sub) - } } - + for _, sub := range et.Subcalls { + tallyGasCharges(charges, sub) + } } var importAnalyzeCmd = &cli.Command{ From 01e230e810eaf6caf6f7ba5e9eb13f8d3f5c7b78 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 01:25:02 +0200 Subject: [PATCH 333/379] Fix ratio Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index a9000f0da..aa3cd68e1 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -276,7 +276,7 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { charges[gc.Name] = s } - s.AddPoint(ratio) + s.AddPoint(1 / ratio) //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) } for _, sub := range et.Subcalls { From 01ac4e5da3770442202b86e447da009bdf295065 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 16 Jun 2020 18:25:48 +0200 Subject: [PATCH 334/379] Gas on actor exec Signed-off-by: Jakub Sztandera --- chain/vm/gas.go | 14 ++++++++++++++ chain/vm/vm.go | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/chain/vm/gas.go b/chain/vm/gas.go index e6bde25bf..d0e0c46ed 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -143,30 +143,40 @@ func (ps pricedSyscalls) VerifySignature(signature crypto.Signature, signer addr return err } ps.chargeGas(c) + defer ps.chargeGas(gasOnActorExec) + return ps.under.VerifySignature(signature, signer, plaintext) } // Hashes input data using blake2b with 256 bit output. func (ps pricedSyscalls) HashBlake2b(data []byte) [32]byte { ps.chargeGas(ps.pl.OnHashing(len(data))) + defer ps.chargeGas(gasOnActorExec) + return ps.under.HashBlake2b(data) } // Computes an unsealed sector CID (CommD) from its constituent piece CIDs (CommPs) and sizes. func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) { ps.chargeGas(ps.pl.OnComputeUnsealedSectorCid(reg, pieces)) + defer ps.chargeGas(gasOnActorExec) + return ps.under.ComputeUnsealedSectorCID(reg, pieces) } // Verifies a sector seal proof. func (ps pricedSyscalls) VerifySeal(vi abi.SealVerifyInfo) error { ps.chargeGas(ps.pl.OnVerifySeal(vi)) + defer ps.chargeGas(gasOnActorExec) + return ps.under.VerifySeal(vi) } // Verifies a proof of spacetime. func (ps pricedSyscalls) VerifyPoSt(vi abi.WindowPoStVerifyInfo) error { ps.chargeGas(ps.pl.OnVerifyPost(vi)) + defer ps.chargeGas(gasOnActorExec) + return ps.under.VerifyPoSt(vi) } @@ -182,6 +192,8 @@ func (ps pricedSyscalls) VerifyPoSt(vi abi.WindowPoStVerifyInfo) error { // Returns nil and an error if the headers don't prove a fault. func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*runtime.ConsensusFault, error) { ps.chargeGas(ps.pl.OnVerifyConsensusFault()) + defer ps.chargeGas(gasOnActorExec) + return ps.under.VerifyConsensusFault(h1, h2, extra) } @@ -189,6 +201,7 @@ func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVeri var gasChargeSum GasCharge gasChargeSum.Name = "BatchVerifySeals" ps.chargeGas(gasChargeSum) // TODO: this is only called by the cron actor. Should we even charge gas? + defer ps.chargeGas(gasOnActorExec) for _, svis := range inp { for _, svi := range svis { @@ -196,5 +209,6 @@ func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVeri ps.chargeGas(newGasCharge("BatchVerifySingle", 0, 0).WithVirtual(ch.VirtualCompute+ch.ComputeGas, 0)) } } + return ps.under.BatchVerifySeals(inp) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 9a4c9991d..e97d963c8 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -35,6 +35,7 @@ import ( ) var log = logging.Logger("vm") +var gasOnActorExec = newGasCharge("OnActorExec", 0, 0) // ResolveToKeyAddr returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`. func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Address) (address.Address, aerrors.ActorError) { @@ -68,11 +69,13 @@ type gasChargingBlocks struct { } func (bs *gasChargingBlocks) Get(c cid.Cid) (block.Block, error) { + bs.chargeGas(newGasCharge("OnIpldGetStart", 0, 0)) blk, err := bs.under.Get(c) if err != nil { return nil, aerrors.Escalate(err, "failed to get block from blockstore") } bs.chargeGas(bs.pricelist.OnIpldGet(len(blk.RawData()))) + bs.chargeGas(gasOnActorExec) return blk, nil } @@ -83,6 +86,7 @@ func (bs *gasChargingBlocks) Put(blk block.Block) error { if err := bs.under.Put(blk); err != nil { return aerrors.Escalate(err, "failed to write data to disk") } + bs.chargeGas(gasOnActorExec) return nil } @@ -231,6 +235,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, if msg.Method != 0 { var ret []byte + _ = rt.chargeGasSafe(gasOnActorExec) ret, err := vm.Invoke(toActor, rt, msg.Method, msg.Params) return ret, err } From a2fd0aad41a52447a551d35cdb4d9a12ff60235b Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 16 Jun 2020 19:29:33 +0200 Subject: [PATCH 335/379] More on OnActorExec Signed-off-by: Jakub Sztandera --- chain/vm/runtime.go | 4 +++- chain/vm/vm.go | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 595664de1..6de8fec9b 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -264,6 +264,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) { if err != nil { panic(aerrors.Fatalf("creating actor entry: %v", err)) } + _ = rt.chargeGasSafe(gasOnActorExec) } func (rt *Runtime) DeleteActor(addr address.Address) { @@ -284,10 +285,10 @@ func (rt *Runtime) DeleteActor(addr address.Address) { if err := rt.state.DeleteActor(rt.Message().Receiver()); err != nil { panic(aerrors.Fatalf("failed to delete actor: %s", err)) } + _ = rt.chargeGasSafe(gasOnActorExec) } func (rt *Runtime) Syscalls() vmr.Syscalls { - // TODO: Make sure this is wrapped in something that charges gas for each of the calls return rt.sys } @@ -367,6 +368,7 @@ func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars log.Warnf("vmctx send failed: to: %s, method: %d: ret: %d, err: %s", to, method, ret, err) return nil, err.RetCode() } + _ = rt.chargeGasSafe(gasOnActorExec) return &dumbWrapperType{ret}, 0 } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index e97d963c8..45114c4c5 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -237,6 +237,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, var ret []byte _ = rt.chargeGasSafe(gasOnActorExec) ret, err := vm.Invoke(toActor, rt, msg.Method, msg.Params) + _ = rt.chargeGasSafe(newGasCharge("OnActorExecDone", 0, 0)) return ret, err } return nil, nil From 9cd34509ee1c2fe975241a9f242b4029b6142ca4 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 01:39:41 +0200 Subject: [PATCH 336/379] Fix error handling of json Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index aa3cd68e1..5cb5e5eb4 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -321,9 +321,6 @@ var importAnalyzeCmd = &cli.Command{ for { b, ok := <-jsonIn - var tse TipSetExec - - json.Unmarshal(b, &tse) if !ok { results <- result{ totalTime: totalTime, @@ -333,6 +330,13 @@ var importAnalyzeCmd = &cli.Command{ return } + var tse TipSetExec + err := json.Unmarshal(b, &tse) + if err != nil { + log.Warnf("error unmarshaling tipset: %+v", err) + continue + } + totalTime += tse.Duration for _, inv := range tse.Trace { if inv.Duration > leastExpensiveInvoc { From 4f60c1afe737f932552169c23645f44823ee131b Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 01:49:01 +0200 Subject: [PATCH 337/379] If something costs 0 gas, make it 1. Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 5cb5e5eb4..d0250a73c 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -268,6 +268,10 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { for _, gc := range et.GasCharges { compGas := gc.ComputeGas + gc.VirtualComputeGas + if compGas == 0 { + compGas = 1 + } + ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) s := charges[gc.Name] From b8ab549bcb6518cb4f3627fedc774a1e66e2455d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 13:38:11 +0200 Subject: [PATCH 338/379] Cleanup lint Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index d0250a73c..a28878392 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -226,7 +226,7 @@ func compStats(vals []float64) (float64, float64) { varsum += delta * delta } - return av, float64(math.Sqrt(float64(varsum / float64(len(vals))))) + return av, math.Sqrt(varsum / float64(len(vals))) } type stats struct { From 052fc35a9144d3a1df60a58dfa4594e3b45c3bd4 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 13:55:29 +0200 Subject: [PATCH 339/379] Maybe avoid NaNs Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index a28878392..9de4e1e7b 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -253,6 +253,9 @@ func (s1 *stats) Combine(s2 *stats) { if s1.count == 0 { *s1 = *s2 } + if s2.count == 0 { + return + } newCount := s1.count + s2.count newMean := s1.count*s1.mean + s2.count*s2.mean newMean /= newCount @@ -273,6 +276,10 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { } ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) + ratio = 1 / ratio + if math.IsNaN(ratio) { + log.Errorf("NaN: comGas: %f, taken: %d", compGas, gc.TimeTaken.Nanoseconds()) + } s := charges[gc.Name] if s == nil { @@ -280,7 +287,7 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { charges[gc.Name] = s } - s.AddPoint(1 / ratio) + s.AddPoint(ratio) //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) } for _, sub := range et.Subcalls { From 369ec8221f0f689268628114133e53a4a03042fc Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 13:59:38 +0200 Subject: [PATCH 340/379] Improve edge case handling Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 9de4e1e7b..c8b61a46f 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -252,10 +252,21 @@ func (s *stats) variance() float64 { func (s1 *stats) Combine(s2 *stats) { if s1.count == 0 { *s1 = *s2 + return } if s2.count == 0 { return } + if s1.count == 1 { + s2.AddPoint(s1.mean) + *s1 = *s2 + return + } + if s2.count == 1 { + s1.AddPoint(s2.mean) + return + } + newCount := s1.count + s2.count newMean := s1.count*s1.mean + s2.count*s2.mean newMean /= newCount From 1bc9fbca20c87cb38f9d21f59e20357b4b65e98c Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 14:04:20 +0200 Subject: [PATCH 341/379] Ignore virtual Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index c8b61a46f..edc3abeac 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -281,7 +281,7 @@ func (s1 *stats) Combine(s2 *stats) { func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { for _, gc := range et.GasCharges { - compGas := gc.ComputeGas + gc.VirtualComputeGas + compGas := gc.ComputeGas if compGas == 0 { compGas = 1 } From a6417dc24b7770dc528106ba398ce0f40c8b002e Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 14:39:42 +0200 Subject: [PATCH 342/379] Add stats test and print observation count Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 2 +- cmd/lotus-bench/stats_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 cmd/lotus-bench/stats_test.go diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index edc3abeac..f6b85b557 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -434,7 +434,7 @@ var importAnalyzeCmd = &cli.Command{ sort.Strings(keys) for _, k := range keys { s := charges[k] - fmt.Printf("%s: incr by %f (%f)\n", k, s.mean, math.Sqrt(s.variance())) + fmt.Printf("%s: incr by %f (stddev: %f, count: %f)\n", k, s.mean, math.Sqrt(s.variance()), s.count) } sort.Slice(invocs, func(i, j int) bool { diff --git a/cmd/lotus-bench/stats_test.go b/cmd/lotus-bench/stats_test.go new file mode 100644 index 000000000..851dc71af --- /dev/null +++ b/cmd/lotus-bench/stats_test.go @@ -0,0 +1,26 @@ +package main + +import ( + "math" + "math/rand" + "testing" +) + +func TestStats(t *testing.T) { + N := 16 + ss := make([]*stats, N) + for i := 0; i < N; i++ { + ss[i] = &stats{} + maxJ := rand.Intn(1000) + for j := 0; j < maxJ; j++ { + ss[i].AddPoint(rand.NormFloat64()*5 + 500) + ss[i].AddPoint(rand.NormFloat64()*5 + 1000) + } + t.Logf("mean: %f, stddev: %f, count %f", ss[i].mean, math.Sqrt(ss[i].variance()), ss[i].count) + } + out := &stats{} + for i := 0; i < N; i++ { + out.Combine(ss[i]) + t.Logf("combine: mean: %f, stddev: %f", out.mean, math.Sqrt(out.variance())) + } +} From 4db61e71da1398bafa0aa8e7256ec6437381988e Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sat, 27 Jun 2020 20:32:14 +0200 Subject: [PATCH 343/379] Reduce caller depth Signed-off-by: Jakub Sztandera --- chain/vm/runtime.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 6de8fec9b..c1581dcd9 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -525,7 +525,7 @@ func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) { func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError { toUse := gas.Total() - var callers [10]uintptr + var callers [4]uintptr cout := gruntime.Callers(2+skip, callers[:]) now := time.Now() From 909440553779b1b7873298b187095aa6f489c456 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sun, 28 Jun 2020 18:41:03 +0200 Subject: [PATCH 344/379] Try without recurson Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f6b85b557..6caff50a7 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -360,6 +360,7 @@ var importAnalyzeCmd = &cli.Command{ } totalTime += tse.Duration + var execStack = make([]types.ExecutionTrace, 0, 100) for _, inv := range tse.Trace { if inv.Duration > leastExpensiveInvoc { expensiveInvocs = append(expensiveInvocs, Invocation{ @@ -367,8 +368,33 @@ var importAnalyzeCmd = &cli.Command{ Invoc: inv, }) } + execStack = append(execStack, inv.ExecutionTrace) + for len(execStack) != 0 { + et := execStack[len(execStack)-1] + execStack = execStack[:len(execStack)-1] + for _, gc := range et.GasCharges { - tallyGasCharges(chargeStats, inv.ExecutionTrace) + compGas := gc.ComputeGas + if compGas == 0 { + compGas = 1 + } + + ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) + ratio = 1 / ratio + if math.IsNaN(ratio) { + log.Errorf("NaN: comGas: %f, taken: %d", compGas, gc.TimeTaken.Nanoseconds()) + } + + s := chargeStats[gc.Name] + if s == nil { + s = new(stats) + chargeStats[gc.Name] = s + } + + s.AddPoint(ratio) + } + execStack = append(execStack, et.Subcalls...) + } } if len(expensiveInvocs) > 4*invocsKeep { sort.Slice(expensiveInvocs, func(i, j int) bool { From 3a9f1bf9a2a25fc592902eb7276f4335ce61ecb2 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sun, 28 Jun 2020 18:47:16 +0200 Subject: [PATCH 345/379] Revert "Try without recurson" This reverts commit 76e3663b2b1f1b58f9097f45124add4fa7718199. Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 6caff50a7..f6b85b557 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -360,7 +360,6 @@ var importAnalyzeCmd = &cli.Command{ } totalTime += tse.Duration - var execStack = make([]types.ExecutionTrace, 0, 100) for _, inv := range tse.Trace { if inv.Duration > leastExpensiveInvoc { expensiveInvocs = append(expensiveInvocs, Invocation{ @@ -368,33 +367,8 @@ var importAnalyzeCmd = &cli.Command{ Invoc: inv, }) } - execStack = append(execStack, inv.ExecutionTrace) - for len(execStack) != 0 { - et := execStack[len(execStack)-1] - execStack = execStack[:len(execStack)-1] - for _, gc := range et.GasCharges { - compGas := gc.ComputeGas - if compGas == 0 { - compGas = 1 - } - - ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) - ratio = 1 / ratio - if math.IsNaN(ratio) { - log.Errorf("NaN: comGas: %f, taken: %d", compGas, gc.TimeTaken.Nanoseconds()) - } - - s := chargeStats[gc.Name] - if s == nil { - s = new(stats) - chargeStats[gc.Name] = s - } - - s.AddPoint(ratio) - } - execStack = append(execStack, et.Subcalls...) - } + tallyGasCharges(chargeStats, inv.ExecutionTrace) } if len(expensiveInvocs) > 4*invocsKeep { sort.Slice(expensiveInvocs, func(i, j int) bool { From cd2595da6732ea0c40fcbcb4280f8dd0cc409bd2 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 29 Jun 2020 18:46:50 +0200 Subject: [PATCH 346/379] Adjust gas Signed-off-by: Jakub Sztandera --- chain/vm/gas_v0.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index 072c1f140..d86edbab8 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -86,12 +86,12 @@ var _ Pricelist = (*pricelistV0)(nil) // OnChainMessage returns the gas used for storing a message of a given size in the chain. func (pl *pricelistV0) OnChainMessage(msgSize int) GasCharge { - return newGasCharge("OnChainMessage", 0, pl.onChainMessageBase+pl.onChainMessagePerByte*int64(msgSize)) + return newGasCharge("OnChainMessage", 0, pl.onChainMessageBase+pl.onChainMessagePerByte*int64(msgSize)).WithVirtual(7402, 0) } // OnChainReturnValue returns the gas used for storing the response of a message in the chain. func (pl *pricelistV0) OnChainReturnValue(dataSize int) GasCharge { - return newGasCharge("OnChainReturnValue", 0, int64(dataSize)*pl.onChainReturnValuePerByte) + return newGasCharge("OnChainReturnValue", 0, int64(dataSize)*pl.onChainReturnValuePerByte).WithVirtual(11160, 0) } // OnMethodInvocation returns the gas used when invoking a method. @@ -103,22 +103,22 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M if methodNum != builtin.MethodSend { ret += pl.sendInvokeMethod } - return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(ret*15000, 0) + return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(ret*4600, 0) } // OnIpldGet returns the gas used for storing an object func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge { - return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize).WithVirtual(pl.ipldGetBase*13750+(pl.ipldGetPerByte*100), 0) + return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize) } // OnIpldPut returns the gas used for storing an object func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge { - return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(pl.ipldPutBase*8700+(pl.ipldPutPerByte*100), 0) + return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(475*(pl.ipldPutBase+int64(dataSize)*pl.ipldPutPerByte), 0) } // OnCreateActor returns the gas used for creating an actor func (pl *pricelistV0) OnCreateActor() GasCharge { - return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra) + return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra).WithVirtual(162*pl.createActorBase, 0) } // OnDeleteActor returns the gas used for deleting an actor @@ -127,6 +127,7 @@ func (pl *pricelistV0) OnDeleteActor() GasCharge { } // OnVerifySignature + func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error) { costFn, ok := pl.verifySignature[sigType] if !ok { @@ -138,13 +139,13 @@ func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize in // OnHashing func (pl *pricelistV0) OnHashing(dataSize int) GasCharge { - return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0) + return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0).WithExtra(dataSize).WithVirtual(256*(pl.hashingBase+int64(dataSize)*pl.hashingPerByte), 0) } // OnComputeUnsealedSectorCid func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(pl.computeUnsealedSectorCidBase*24500, 0) + return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(pl.computeUnsealedSectorCidBase*405, 0) } // OnVerifySeal @@ -156,10 +157,10 @@ func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge { // OnVerifyPost func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0) + return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0).WithVirtual(pl.verifyPostBase*385100, 0) } // OnVerifyConsensusFault func (pl *pricelistV0) OnVerifyConsensusFault() GasCharge { - return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0) + return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0).WithVirtual(pl.verifyConsensusFault*5466, 0) } From ca7e5f5e16d6acccd21a501a322a9e49d3c5d8dc Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 29 Jun 2020 18:56:27 +0200 Subject: [PATCH 347/379] Set gas to 1 Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f6b85b557..3d994f3b6 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -281,16 +281,24 @@ func (s1 *stats) Combine(s2 *stats) { func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { for _, gc := range et.GasCharges { - compGas := gc.ComputeGas + compGas := gc.VirtualComputeGas if compGas == 0 { compGas = 1 } + compGas = 1 ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) ratio = 1 / ratio if math.IsNaN(ratio) { log.Errorf("NaN: comGas: %f, taken: %d", compGas, gc.TimeTaken.Nanoseconds()) } + name := gc.Name + if eString, ok := gc.Extra.(string); ok { + name += "-" + eString + } else if eInt, ok := gc.Extra.(float64); ok { + // handle scaling + _ = eInt + } s := charges[gc.Name] if s == nil { From 1e17ea3fffbd53c2fff4eb2f8357eb11095daf0e Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 29 Jun 2020 19:19:02 +0200 Subject: [PATCH 348/379] Adjust gas values Signed-off-by: Jakub Sztandera --- chain/vm/gas_v0.go | 19 +++++++++++-------- chain/vm/vm.go | 2 +- cmd/lotus-bench/import.go | 28 ++++++++++++++-------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index d86edbab8..a0543cb72 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -97,13 +97,16 @@ func (pl *pricelistV0) OnChainReturnValue(dataSize int) GasCharge { // OnMethodInvocation returns the gas used when invoking a method. func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge { ret := pl.sendBase + extra := "" if value != abi.NewTokenAmount(0) { ret += pl.sendTransferFunds + extra += "t" } if methodNum != builtin.MethodSend { ret += pl.sendInvokeMethod + extra += "i" } - return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(ret*4600, 0) + return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(86315, 0).WithExtra(extra) } // OnIpldGet returns the gas used for storing an object @@ -113,12 +116,12 @@ func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge { // OnIpldPut returns the gas used for storing an object func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge { - return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(475*(pl.ipldPutBase+int64(dataSize)*pl.ipldPutPerByte), 0) + return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(9151, 0) } // OnCreateActor returns the gas used for creating an actor func (pl *pricelistV0) OnCreateActor() GasCharge { - return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra).WithVirtual(162*pl.createActorBase, 0) + return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra).WithVirtual(6549, 0) } // OnDeleteActor returns the gas used for deleting an actor @@ -139,28 +142,28 @@ func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize in // OnHashing func (pl *pricelistV0) OnHashing(dataSize int) GasCharge { - return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0).WithExtra(dataSize).WithVirtual(256*(pl.hashingBase+int64(dataSize)*pl.hashingPerByte), 0) + return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0).WithExtra(dataSize).WithVirtual(7881, 0) } // OnComputeUnsealedSectorCid func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(pl.computeUnsealedSectorCidBase*405, 0) + return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(40536, 0) } // OnVerifySeal func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnVerifySeal", pl.verifySealBase, 0).WithVirtual(pl.verifySealBase*177500, 0) + return newGasCharge("OnVerifySeal", pl.verifySealBase, 0).WithVirtual(199954003, 0) } // OnVerifyPost func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0).WithVirtual(pl.verifyPostBase*385100, 0) + return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0).WithVirtual(269570688, 0) } // OnVerifyConsensusFault func (pl *pricelistV0) OnVerifyConsensusFault() GasCharge { - return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0).WithVirtual(pl.verifyConsensusFault*5466, 0) + return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0).WithVirtual(54665, 0) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 45114c4c5..c76f01dac 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -69,7 +69,7 @@ type gasChargingBlocks struct { } func (bs *gasChargingBlocks) Get(c cid.Cid) (block.Block, error) { - bs.chargeGas(newGasCharge("OnIpldGetStart", 0, 0)) + bs.chargeGas(newGasCharge("OnIpldGetStart", 0, 0).WithVirtual(40175)) blk, err := bs.under.Get(c) if err != nil { return nil, aerrors.Escalate(err, "failed to get block from blockstore") diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 3d994f3b6..f76ef4644 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -280,18 +280,6 @@ func (s1 *stats) Combine(s2 *stats) { func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { for _, gc := range et.GasCharges { - - compGas := gc.VirtualComputeGas - if compGas == 0 { - compGas = 1 - } - compGas = 1 - - ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) - ratio = 1 / ratio - if math.IsNaN(ratio) { - log.Errorf("NaN: comGas: %f, taken: %d", compGas, gc.TimeTaken.Nanoseconds()) - } name := gc.Name if eString, ok := gc.Extra.(string); ok { name += "-" + eString @@ -300,10 +288,22 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { _ = eInt } - s := charges[gc.Name] + compGas := gc.VirtualComputeGas + if compGas == 0 { + name += "-zerogas" + compGas = 1 + } + + ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) + ratio = 1 / ratio + if math.IsNaN(ratio) { + log.Errorf("NaN: comGas: %f, taken: %d", compGas, gc.TimeTaken.Nanoseconds()) + } + + s := charges[name] if s == nil { s = new(stats) - charges[gc.Name] = s + charges[name] = s } s.AddPoint(ratio) From bc88c632d15185bfb88c068775ceeac318faba81 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 29 Jun 2020 19:23:50 +0200 Subject: [PATCH 349/379] Fix previous commit Signed-off-by: Jakub Sztandera --- chain/vm/vm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index c76f01dac..5c2f7f9ea 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -69,7 +69,7 @@ type gasChargingBlocks struct { } func (bs *gasChargingBlocks) Get(c cid.Cid) (block.Block, error) { - bs.chargeGas(newGasCharge("OnIpldGetStart", 0, 0).WithVirtual(40175)) + bs.chargeGas(newGasCharge("OnIpldGetStart", 0, 0).WithVirtual(40175, 0)) blk, err := bs.under.Get(c) if err != nil { return nil, aerrors.Escalate(err, "failed to get block from blockstore") From 21148033e20fe66ed1df687767bd381dee4222a4 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 00:31:05 +0200 Subject: [PATCH 350/379] Change alg for computing variance Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 29 +++++++++++++---------------- cmd/lotus-bench/stats_test.go | 6 +++--- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f76ef4644..ef572b13b 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -232,21 +232,20 @@ func compStats(vals []float64) (float64, float64) { type stats struct { count float64 mean float64 - dSqr float64 + m2 float64 } func (s *stats) AddPoint(value float64) { - s.count++ - meanDiff := (value - s.mean) / s.count - newMean := s.mean + meanDiff - - dSqrtInc := (value - newMean) * (value - s.mean) - s.dSqr += dSqrtInc - s.mean = newMean + // based on https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm + s.count += 1 + delta := value - s.mean + s.mean += delta / s.count + delta2 := value - s.mean + s.m2 += delta * delta2 } func (s *stats) variance() float64 { - return s.dSqr / (s.count - 1) + return s.m2 / (s.count - 1) } func (s1 *stats) Combine(s2 *stats) { @@ -268,14 +267,12 @@ func (s1 *stats) Combine(s2 *stats) { } newCount := s1.count + s2.count - newMean := s1.count*s1.mean + s2.count*s2.mean - newMean /= newCount - newVar := s1.count * (s1.variance() + (s1.mean-newMean)*(s1.mean-newMean)) - newVar += s2.count * (s2.variance() + (s2.mean-newMean)*(s2.mean-newMean)) - newVar /= newCount + delta := s2.mean - s1.mean + meanDelta := delta * s2.count / newCount + m2 := s1.m2 + s2.m2 + delta*meanDelta*s1.count s1.count = newCount - s1.mean = newMean - s1.dSqr = newVar * (newCount - 1) + s1.mean += meanDelta + s1.m2 = m2 } func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { diff --git a/cmd/lotus-bench/stats_test.go b/cmd/lotus-bench/stats_test.go index 851dc71af..6ade8a4e5 100644 --- a/cmd/lotus-bench/stats_test.go +++ b/cmd/lotus-bench/stats_test.go @@ -9,12 +9,12 @@ import ( func TestStats(t *testing.T) { N := 16 ss := make([]*stats, N) + rng := rand.New(rand.NewSource(1)) for i := 0; i < N; i++ { ss[i] = &stats{} - maxJ := rand.Intn(1000) + maxJ := rng.Intn(1000) for j := 0; j < maxJ; j++ { - ss[i].AddPoint(rand.NormFloat64()*5 + 500) - ss[i].AddPoint(rand.NormFloat64()*5 + 1000) + ss[i].AddPoint(rng.NormFloat64()*5 + 500) } t.Logf("mean: %f, stddev: %f, count %f", ss[i].mean, math.Sqrt(ss[i].variance()), ss[i].count) } From 2caa7164a6d2d69d29e049db93d58360138faced Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 01:31:09 +0200 Subject: [PATCH 351/379] Midway adding covar Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 141 ++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 38 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index ef572b13b..0a9f2c72b 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -230,49 +230,120 @@ func compStats(vals []float64) (float64, float64) { } type stats struct { - count float64 - mean float64 + timeTaken meanVar + gasRatio meanVar + + extra *meanVar + extraCovar *covar +} + +type covar struct { + meanX float64 + meanY float64 + c float64 + n float64 m2 float64 } -func (s *stats) AddPoint(value float64) { +func (cov1 *covar) Covariance() float64 { + return cov1.c / (cov1.n - 1) +} + +func (cov1 *covar) AddPoint(x, y float64) { + cov1.n += 1 + dx := x - cov1.meanX + cov1.meanX += dx / cov1.n + + dx2 := x - cov1.meanX // compute x variance using partial result for covariance + cov1.m2 += dx * dx2 + + cov1.meanY += (y - cov1.meanY) / cov1.n + cov1.c += dx * (y - cov1.meanY) +} + +func (cov1 *covar) Combine(cov2 *covar) { + if cov1.n == 0 { + *cov1 = *cov2 + return + } + if cov2.n == 0 { + return + } + + if cov1.n == 1 { + cpy := *cov2 + cpy.AddPoint(cov2.meanX, cov2.meanY) + *cov1 = cpy + return + } + if cov2.n == 1 { + cov1.AddPoint(cov2.meanX, cov2.meanY) + } + out := covar{} + out.n = cov1.n + cov2.n + + dx := cov1.meanX - cov2.meanX + out.meanX = cov1.meanX + dx*cov2.n/out.n + out.m2 = cov1.m2 + cov2.m2 + dx*dx*cov1.n*cov2.n/out.n + + dy := cov1.meanY - cov2.meanY + out.meanY = cov1.meanY + dy*cov2.n/out.n + + out.c = cov1.c + cov2.c + dx*dy*cov1.n*cov2.n/out.n + *cov1 = out +} + +type meanVar struct { + n float64 + mean float64 + m2 float64 +} + +func (v1 *meanVar) AddPoint(value float64) { // based on https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm - s.count += 1 - delta := value - s.mean - s.mean += delta / s.count - delta2 := value - s.mean - s.m2 += delta * delta2 + v1.n += 1 + delta := value - v1.mean + v1.mean += delta / v1.n + delta2 := value - v1.mean + v1.m2 += delta * delta2 } -func (s *stats) variance() float64 { - return s.m2 / (s.count - 1) +func (v1 *meanVar) Variance() float64 { + return v1.m2 / (v1.n - 1) +} +func (v1 *meanVar) Mean() float64 { + return v1.mean +} +func (v1 *meanVar) Stddev() float64 { + return math.Sqrt(v1.Variance()) } -func (s1 *stats) Combine(s2 *stats) { - if s1.count == 0 { - *s1 = *s2 +func (v1 *meanVar) Combine(v2 *meanVar) { + if v1.n == 0 { + *v1 = *v2 return } - if s2.count == 0 { + if v2.n == 0 { return } - if s1.count == 1 { - s2.AddPoint(s1.mean) - *s1 = *s2 + if v1.n == 1 { + cpy := *v2 + cpy.AddPoint(v1.mean) + *v1 = cpy return } - if s2.count == 1 { - s1.AddPoint(s2.mean) + if v2.n == 1 { + v1.AddPoint(v2.mean) return } - newCount := s1.count + s2.count - delta := s2.mean - s1.mean - meanDelta := delta * s2.count / newCount - m2 := s1.m2 + s2.m2 + delta*meanDelta*s1.count - s1.count = newCount - s1.mean += meanDelta - s1.m2 = m2 + newCount := v1.n + v2.n + delta := v2.mean - v1.mean + meanDelta := delta * v2.n / newCount + m2 := v1.m2 + v2.m2 + delta*meanDelta*v1.n + v1.n = newCount + v1.mean += meanDelta + v1.m2 = m2 } func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { @@ -287,24 +358,17 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { compGas := gc.VirtualComputeGas if compGas == 0 { - name += "-zerogas" compGas = 1 } - - ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds()) - ratio = 1 / ratio - if math.IsNaN(ratio) { - log.Errorf("NaN: comGas: %f, taken: %d", compGas, gc.TimeTaken.Nanoseconds()) - } - s := charges[name] if s == nil { s = new(stats) charges[name] = s } + s.timeTaken.AddPoint(float64(gc.TimeTaken.Nanoseconds())) - s.AddPoint(ratio) - //fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs)) + ratio := float64(gc.TimeTaken.Nanoseconds()) / float64(compGas) * GasPerNs + s.gasRatio.AddPoint(ratio) } for _, sub := range et.Subcalls { tallyGasCharges(charges, sub) @@ -425,7 +489,8 @@ var importAnalyzeCmd = &cli.Command{ s = new(stats) charges[k] = s } - s.Combine(v) + s.timeTaken.Combine(&v.timeTaken) + s.gasRatio.Combine(&v.gasRatio) } totalTime += res.totalTime } @@ -439,7 +504,7 @@ var importAnalyzeCmd = &cli.Command{ sort.Strings(keys) for _, k := range keys { s := charges[k] - fmt.Printf("%s: incr by %f (stddev: %f, count: %f)\n", k, s.mean, math.Sqrt(s.variance()), s.count) + fmt.Printf("%s: incr by %f~%f\n", k, s.gasRatio.mean, s.gasRatio.Stddev()) } sort.Slice(invocs, func(i, j int) bool { From 29f5f451b31818897158905b143f7992b77f61c3 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 02:11:54 +0200 Subject: [PATCH 352/379] Add covariance Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 66 ++++++++++++++++++++++++++++++----- cmd/lotus-bench/stats_test.go | 33 ++++++++++++++---- 2 files changed, 83 insertions(+), 16 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 0a9f2c72b..f9526e90f 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -249,6 +249,14 @@ func (cov1 *covar) Covariance() float64 { return cov1.c / (cov1.n - 1) } +func (cov1 *covar) Variance() float64 { + return cov1.m2 / (cov1.n - 1) +} + +func (v1 *covar) Stddev() float64 { + return math.Sqrt(v1.Variance()) +} + func (cov1 *covar) AddPoint(x, y float64) { cov1.n += 1 dx := x - cov1.meanX @@ -279,11 +287,12 @@ func (cov1 *covar) Combine(cov2 *covar) { if cov2.n == 1 { cov1.AddPoint(cov2.meanX, cov2.meanY) } + out := covar{} out.n = cov1.n + cov2.n dx := cov1.meanX - cov2.meanX - out.meanX = cov1.meanX + dx*cov2.n/out.n + out.meanX = cov1.meanX - dx*cov2.n/out.n out.m2 = cov1.m2 + cov2.m2 + dx*dx*cov1.n*cov2.n/out.n dy := cov1.meanY - cov2.meanY @@ -293,6 +302,13 @@ func (cov1 *covar) Combine(cov2 *covar) { *cov1 = out } +func (cov1 *covar) A() float64 { + return cov1.Covariance() / cov1.Variance() +} +func (cov1 *covar) B() float64 { + return cov1.meanY - cov1.meanX*cov1.A() +} + type meanVar struct { n float64 mean float64 @@ -347,15 +363,22 @@ func (v1 *meanVar) Combine(v2 *meanVar) { } func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { - for _, gc := range et.GasCharges { + for i, gc := range et.GasCharges { name := gc.Name + if name == "OnIpldGetStart" { + continue + } + tt := float64(gc.TimeTaken.Nanoseconds()) + if name == "OnIpldGet" { + prev := et.GasCharges[i-1] + if prev.Name != "OnIpldGetStart" { + log.Warn("OnIpldGet without OnIpldGetStart") + } + tt += float64(prev.TimeTaken.Nanoseconds()) + } if eString, ok := gc.Extra.(string); ok { name += "-" + eString - } else if eInt, ok := gc.Extra.(float64); ok { - // handle scaling - _ = eInt } - compGas := gc.VirtualComputeGas if compGas == 0 { compGas = 1 @@ -365,9 +388,19 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { s = new(stats) charges[name] = s } - s.timeTaken.AddPoint(float64(gc.TimeTaken.Nanoseconds())) - ratio := float64(gc.TimeTaken.Nanoseconds()) / float64(compGas) * GasPerNs + if extra, ok := gc.Extra.(float64); ok { + if s.extraCovar == nil { + s.extraCovar = &covar{} + s.extra = &meanVar{} + } + s.extraCovar.AddPoint(extra, tt) + s.extra.AddPoint(extra) + } + + s.timeTaken.AddPoint(tt) + + ratio := tt / float64(compGas) * GasPerNs s.gasRatio.AddPoint(ratio) } for _, sub := range et.Subcalls { @@ -491,6 +524,15 @@ var importAnalyzeCmd = &cli.Command{ } s.timeTaken.Combine(&v.timeTaken) s.gasRatio.Combine(&v.gasRatio) + + if v.extra != nil { + if s.extra == nil { + s.extra = &meanVar{} + s.extraCovar = &covar{} + } + s.extra.Combine(v.extra) + s.extraCovar.Combine(v.extraCovar) + } } totalTime += res.totalTime } @@ -504,7 +546,13 @@ var importAnalyzeCmd = &cli.Command{ sort.Strings(keys) for _, k := range keys { s := charges[k] - fmt.Printf("%s: incr by %f~%f\n", k, s.gasRatio.mean, s.gasRatio.Stddev()) + fmt.Printf("%s: incr by %f~%f; tt %f~%f\n", k, s.gasRatio.Mean(), s.gasRatio.Stddev(), + s.timeTaken.Mean(), s.timeTaken.Stddev()) + if s.extra != nil { + fmt.Printf("\t covar: %f, tt = %f * extra + %f\n", s.extraCovar.Covariance(), + s.extraCovar.A(), s.extraCovar.B()) + fmt.Printf("\t extra: %f~%f\n", s.extra.Mean(), s.extra.Stddev()) + } } sort.Slice(invocs, func(i, j int) bool { diff --git a/cmd/lotus-bench/stats_test.go b/cmd/lotus-bench/stats_test.go index 6ade8a4e5..a8cb985a1 100644 --- a/cmd/lotus-bench/stats_test.go +++ b/cmd/lotus-bench/stats_test.go @@ -1,26 +1,45 @@ package main import ( - "math" "math/rand" "testing" ) -func TestStats(t *testing.T) { +func TestMeanVar(t *testing.T) { N := 16 - ss := make([]*stats, N) + ss := make([]*meanVar, N) rng := rand.New(rand.NewSource(1)) for i := 0; i < N; i++ { - ss[i] = &stats{} + ss[i] = &meanVar{} maxJ := rng.Intn(1000) for j := 0; j < maxJ; j++ { ss[i].AddPoint(rng.NormFloat64()*5 + 500) } - t.Logf("mean: %f, stddev: %f, count %f", ss[i].mean, math.Sqrt(ss[i].variance()), ss[i].count) + t.Logf("mean: %f, stddev: %f, count %f", ss[i].mean, ss[i].Stddev(), ss[i].n) } - out := &stats{} + out := &meanVar{} for i := 0; i < N; i++ { out.Combine(ss[i]) - t.Logf("combine: mean: %f, stddev: %f", out.mean, math.Sqrt(out.variance())) + t.Logf("combine: mean: %f, stddev: %f", out.mean, out.Stddev()) + } +} + +func TestCovar(t *testing.T) { + N := 16 + ss := make([]*covar, N) + rng := rand.New(rand.NewSource(1)) + for i := 0; i < N; i++ { + ss[i] = &covar{} + maxJ := rng.Intn(1000) + 500 + for j := 0; j < maxJ; j++ { + x := rng.NormFloat64()*5 + 500 + ss[i].AddPoint(x, x*(rng.NormFloat64()/10+2)-rng.NormFloat64()-1000) + } + t.Logf("covar: %f, y = %f*x+%f @%.0f", ss[i].Covariance(), ss[i].A(), ss[i].B(), ss[i].n) + } + out := &covar{} + for i := 0; i < N; i++ { + out.Combine(ss[i]) + t.Logf("combine: covar: %f, y = %f*x+%f", ss[i].Covariance(), ss[i].A(), ss[i].B()) } } From c68a8f802ee16225179091de465263633a0d2874 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 02:31:39 +0200 Subject: [PATCH 353/379] Adjust gas Signed-off-by: Jakub Sztandera --- chain/vm/gas.go | 11 ++++------- chain/vm/gas_v0.go | 32 ++++++++++++++++++++++---------- chain/vm/vm.go | 2 +- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/chain/vm/gas.go b/chain/vm/gas.go index d0e0c46ed..e1f7952b9 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -200,15 +200,12 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { var gasChargeSum GasCharge gasChargeSum.Name = "BatchVerifySeals" - ps.chargeGas(gasChargeSum) // TODO: this is only called by the cron actor. Should we even charge gas? - defer ps.chargeGas(gasOnActorExec) - + count := 0 for _, svis := range inp { - for _, svi := range svis { - ch := ps.pl.OnVerifySeal(svi) - ps.chargeGas(newGasCharge("BatchVerifySingle", 0, 0).WithVirtual(ch.VirtualCompute+ch.ComputeGas, 0)) - } + count += len(svis) } + ps.chargeGas(gasChargeSum.WithExtra(count)) // TODO: this is only called by the cron actor. Should we even charge gas? + defer ps.chargeGas(gasOnActorExec) return ps.under.BatchVerifySeals(inp) } diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index a0543cb72..0215b7454 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/crypto" ) @@ -86,20 +87,25 @@ var _ Pricelist = (*pricelistV0)(nil) // OnChainMessage returns the gas used for storing a message of a given size in the chain. func (pl *pricelistV0) OnChainMessage(msgSize int) GasCharge { - return newGasCharge("OnChainMessage", 0, pl.onChainMessageBase+pl.onChainMessagePerByte*int64(msgSize)).WithVirtual(7402, 0) + return newGasCharge("OnChainMessage", 0, pl.onChainMessageBase+pl.onChainMessagePerByte*int64(msgSize)).WithVirtual(77302, 0) } // OnChainReturnValue returns the gas used for storing the response of a message in the chain. func (pl *pricelistV0) OnChainReturnValue(dataSize int) GasCharge { - return newGasCharge("OnChainReturnValue", 0, int64(dataSize)*pl.onChainReturnValuePerByte).WithVirtual(11160, 0) + return newGasCharge("OnChainReturnValue", 0, int64(dataSize)*pl.onChainReturnValuePerByte).WithVirtual(107294, 0) } // OnMethodInvocation returns the gas used when invoking a method. func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge { ret := pl.sendBase extra := "" + if value != abi.NewTokenAmount(0) { + // TODO: fix this, it is comparing pointers instead of values + // see vv ret += pl.sendTransferFunds + } + if big.Cmp(value, abi.NewTokenAmount(0)) == 0 { extra += "t" } if methodNum != builtin.MethodSend { @@ -111,17 +117,19 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M // OnIpldGet returns the gas used for storing an object func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge { - return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize) + return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0). + WithExtra(dataSize).WithVirtual(433685, 0) } // OnIpldPut returns the gas used for storing an object func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge { - return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(9151, 0) + return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte). + WithExtra(dataSize).WithVirtual(88970, 0) } // OnCreateActor returns the gas used for creating an actor func (pl *pricelistV0) OnCreateActor() GasCharge { - return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra).WithVirtual(6549, 0) + return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra).WithVirtual(65636, 0) } // OnDeleteActor returns the gas used for deleting an actor @@ -137,18 +145,22 @@ func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize in return GasCharge{}, fmt.Errorf("cost function for signature type %d not supported", sigType) } sigName, _ := sigType.Name() - return newGasCharge("OnVerifySignature", costFn(int64(planTextSize)), 0).WithExtra(sigName), nil + return newGasCharge("OnVerifySignature", costFn(int64(planTextSize)), 0). + WithExtra(map[string]interface{}{ + "type": sigName, + "size": planTextSize, + }), nil } // OnHashing func (pl *pricelistV0) OnHashing(dataSize int) GasCharge { - return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0).WithExtra(dataSize).WithVirtual(7881, 0) + return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0).WithExtra(dataSize).WithVirtual(77300, 0) } // OnComputeUnsealedSectorCid func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(40536, 0) + return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(382370, 0) } // OnVerifySeal @@ -160,10 +172,10 @@ func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge { // OnVerifyPost func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0).WithVirtual(269570688, 0) + return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0).WithVirtual(2629471704, 0) } // OnVerifyConsensusFault func (pl *pricelistV0) OnVerifyConsensusFault() GasCharge { - return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0).WithVirtual(54665, 0) + return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0).WithVirtual(551935, 0) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 5c2f7f9ea..45114c4c5 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -69,7 +69,7 @@ type gasChargingBlocks struct { } func (bs *gasChargingBlocks) Get(c cid.Cid) (block.Block, error) { - bs.chargeGas(newGasCharge("OnIpldGetStart", 0, 0).WithVirtual(40175, 0)) + bs.chargeGas(newGasCharge("OnIpldGetStart", 0, 0)) blk, err := bs.under.Get(c) if err != nil { return nil, aerrors.Escalate(err, "failed to get block from blockstore") From 5e7f5611338e3f19fc931e233b05601de3f94d31 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 02:56:58 +0200 Subject: [PATCH 354/379] Support complex extra, fix small bug in covariance Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f9526e90f..7d759642e 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -296,7 +296,7 @@ func (cov1 *covar) Combine(cov2 *covar) { out.m2 = cov1.m2 + cov2.m2 + dx*dx*cov1.n*cov2.n/out.n dy := cov1.meanY - cov2.meanY - out.meanY = cov1.meanY + dy*cov2.n/out.n + out.meanY = cov1.meanY - dy*cov2.n/out.n out.c = cov1.c + cov2.c + dx*dy*cov1.n*cov2.n/out.n *cov1 = out @@ -362,6 +362,30 @@ func (v1 *meanVar) Combine(v2 *meanVar) { v1.m2 = m2 } +func getExtras(ex interface{}) (*string, *float64) { + if t, ok := ex.(string); ok { + return &t, nil + } + if size, ok := ex.(float64); ok { + return nil, &size + } + if exMap, ok := ex.(map[string]interface{}); ok { + t, tok := exMap["type"].(string) + size, sok := exMap["size"].(float64) + if tok && sok { + return &t, &size + } + if tok { + return &t, nil + } + if sok { + return nil, &size + } + return nil, nil + } + return nil, nil +} + func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { for i, gc := range et.GasCharges { name := gc.Name @@ -376,8 +400,9 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { } tt += float64(prev.TimeTaken.Nanoseconds()) } - if eString, ok := gc.Extra.(string); ok { - name += "-" + eString + eType, eSize := getExtras(gc.Extra) + if eType != nil { + name += "-" + *eType } compGas := gc.VirtualComputeGas if compGas == 0 { @@ -389,13 +414,13 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { charges[name] = s } - if extra, ok := gc.Extra.(float64); ok { + if eSize != nil { if s.extraCovar == nil { s.extraCovar = &covar{} s.extra = &meanVar{} } - s.extraCovar.AddPoint(extra, tt) - s.extra.AddPoint(extra) + s.extraCovar.AddPoint(*eSize, tt) + s.extra.AddPoint(*eSize) } s.timeTaken.AddPoint(tt) From 9ccd25b0725572e8c0dbfef165027197d261a102 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 14:09:03 +0200 Subject: [PATCH 355/379] Update gas values, compute correlation coefficient Signed-off-by: Jakub Sztandera --- chain/vm/gas.go | 7 ++--- chain/vm/gas_v0.go | 20 +++++++++++++-- cmd/lotus-bench/import.go | 54 ++++++++++++++++++++++++--------------- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/chain/vm/gas.go b/chain/vm/gas.go index e1f7952b9..bee65fd8f 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -200,11 +200,12 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) { var gasChargeSum GasCharge gasChargeSum.Name = "BatchVerifySeals" - count := 0 + count := int64(0) for _, svis := range inp { - count += len(svis) + count += int64(len(svis)) } - ps.chargeGas(gasChargeSum.WithExtra(count)) // TODO: this is only called by the cron actor. Should we even charge gas? + gasChargeSum = gasChargeSum.WithExtra(count).WithVirtual(129778623*count+716683250, 0) + ps.chargeGas(gasChargeSum) // TODO: this is only called by the cron actor. Should we even charge gas? defer ps.chargeGas(gasOnActorExec) return ps.under.BatchVerifySeals(inp) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index 0215b7454..b0c839f2f 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -99,18 +99,26 @@ func (pl *pricelistV0) OnChainReturnValue(dataSize int) GasCharge { func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge { ret := pl.sendBase extra := "" + virtGas := int64(1069512) if value != abi.NewTokenAmount(0) { // TODO: fix this, it is comparing pointers instead of values // see vv ret += pl.sendTransferFunds } - if big.Cmp(value, abi.NewTokenAmount(0)) == 0 { + if big.Cmp(value, abi.NewTokenAmount(0)) != 0 { + virtGas += 498173 + if methodNum == builtin.MethodSend { + // transfer only + virtGas += 968198 + } extra += "t" } if methodNum != builtin.MethodSend { ret += pl.sendInvokeMethod extra += "i" + // running actors is cheaper becase we hand over to actors + virtGas += -294632 } return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(86315, 0).WithExtra(extra) } @@ -145,11 +153,19 @@ func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize in return GasCharge{}, fmt.Errorf("cost function for signature type %d not supported", sigType) } sigName, _ := sigType.Name() + virtGas := int64(0) + switch sigType { + case crypto.SigTypeBLS: + virtGas = 220138570 + case crypto.SigTypeSecp256k1: + virtGas = 7053730 + } + return newGasCharge("OnVerifySignature", costFn(int64(planTextSize)), 0). WithExtra(map[string]interface{}{ "type": sigName, "size": planTextSize, - }), nil + }).WithVirtual(virtGas, 0), nil } // OnHashing diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 7d759642e..b38661983 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -233,7 +233,6 @@ type stats struct { timeTaken meanVar gasRatio meanVar - extra *meanVar extraCovar *covar } @@ -242,19 +241,28 @@ type covar struct { meanY float64 c float64 n float64 - m2 float64 + m2x float64 + m2y float64 } func (cov1 *covar) Covariance() float64 { return cov1.c / (cov1.n - 1) } -func (cov1 *covar) Variance() float64 { - return cov1.m2 / (cov1.n - 1) +func (cov1 *covar) VarianceX() float64 { + return cov1.m2x / (cov1.n - 1) } -func (v1 *covar) Stddev() float64 { - return math.Sqrt(v1.Variance()) +func (v1 *covar) StddevX() float64 { + return math.Sqrt(v1.VarianceX()) +} + +func (cov1 *covar) VarianceY() float64 { + return cov1.m2y / (cov1.n - 1) +} + +func (v1 *covar) StddevY() float64 { + return math.Sqrt(v1.VarianceY()) } func (cov1 *covar) AddPoint(x, y float64) { @@ -262,11 +270,15 @@ func (cov1 *covar) AddPoint(x, y float64) { dx := x - cov1.meanX cov1.meanX += dx / cov1.n - dx2 := x - cov1.meanX // compute x variance using partial result for covariance - cov1.m2 += dx * dx2 + dx2 := x - cov1.meanX + cov1.m2x += dx * dx2 - cov1.meanY += (y - cov1.meanY) / cov1.n - cov1.c += dx * (y - cov1.meanY) + dy := y - cov1.meanY + cov1.meanY += dy / cov1.n + dy2 := y - cov1.meanY + cov1.m2y += dy * dy2 + + cov1.c += dx * dy } func (cov1 *covar) Combine(cov2 *covar) { @@ -293,21 +305,25 @@ func (cov1 *covar) Combine(cov2 *covar) { dx := cov1.meanX - cov2.meanX out.meanX = cov1.meanX - dx*cov2.n/out.n - out.m2 = cov1.m2 + cov2.m2 + dx*dx*cov1.n*cov2.n/out.n + out.m2x = cov1.m2x + cov2.m2x + dx*dx*cov1.n*cov2.n/out.n dy := cov1.meanY - cov2.meanY out.meanY = cov1.meanY - dy*cov2.n/out.n + out.m2y = cov1.m2y + cov2.m2y + dy*dy*cov1.n*cov2.n/out.n out.c = cov1.c + cov2.c + dx*dy*cov1.n*cov2.n/out.n *cov1 = out } func (cov1 *covar) A() float64 { - return cov1.Covariance() / cov1.Variance() + return cov1.Covariance() / cov1.VarianceX() } func (cov1 *covar) B() float64 { return cov1.meanY - cov1.meanX*cov1.A() } +func (cov1 *covar) Coerrel() float64 { + return cov1.Covariance() / cov1.VarianceX() / cov1.VarianceY() +} type meanVar struct { n float64 @@ -417,10 +433,8 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) { if eSize != nil { if s.extraCovar == nil { s.extraCovar = &covar{} - s.extra = &meanVar{} } s.extraCovar.AddPoint(*eSize, tt) - s.extra.AddPoint(*eSize) } s.timeTaken.AddPoint(tt) @@ -550,12 +564,10 @@ var importAnalyzeCmd = &cli.Command{ s.timeTaken.Combine(&v.timeTaken) s.gasRatio.Combine(&v.gasRatio) - if v.extra != nil { - if s.extra == nil { - s.extra = &meanVar{} + if v.extraCovar != nil { + if s.extraCovar == nil { s.extraCovar = &covar{} } - s.extra.Combine(v.extra) s.extraCovar.Combine(v.extraCovar) } } @@ -573,10 +585,10 @@ var importAnalyzeCmd = &cli.Command{ s := charges[k] fmt.Printf("%s: incr by %f~%f; tt %f~%f\n", k, s.gasRatio.Mean(), s.gasRatio.Stddev(), s.timeTaken.Mean(), s.timeTaken.Stddev()) - if s.extra != nil { - fmt.Printf("\t covar: %f, tt = %f * extra + %f\n", s.extraCovar.Covariance(), + if s.extraCovar != nil { + fmt.Printf("\t correll: %f, tt = %f * extra + %f\n", s.extraCovar.Coerrel(), s.extraCovar.A(), s.extraCovar.B()) - fmt.Printf("\t extra: %f~%f\n", s.extra.Mean(), s.extra.Stddev()) + fmt.Printf("\t extra: %f~%f\n", s.extraCovar.meanX, s.extraCovar.StddevX()) } } From 4dd79ec6fa2a2951f0d76dd4bbc772260b656f3d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 14:21:48 +0200 Subject: [PATCH 356/379] Calculate correlation Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 6 +++--- cmd/lotus-bench/stats_test.go | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index b38661983..f6a07ca05 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -321,8 +321,8 @@ func (cov1 *covar) A() float64 { func (cov1 *covar) B() float64 { return cov1.meanY - cov1.meanX*cov1.A() } -func (cov1 *covar) Coerrel() float64 { - return cov1.Covariance() / cov1.VarianceX() / cov1.VarianceY() +func (cov1 *covar) Correl() float64 { + return cov1.Covariance() / cov1.StddevX() / cov1.StddevY() } type meanVar struct { @@ -586,7 +586,7 @@ var importAnalyzeCmd = &cli.Command{ fmt.Printf("%s: incr by %f~%f; tt %f~%f\n", k, s.gasRatio.Mean(), s.gasRatio.Stddev(), s.timeTaken.Mean(), s.timeTaken.Stddev()) if s.extraCovar != nil { - fmt.Printf("\t correll: %f, tt = %f * extra + %f\n", s.extraCovar.Coerrel(), + fmt.Printf("\t correll: %f, tt = %f * extra + %f\n", s.extraCovar.Correl(), s.extraCovar.A(), s.extraCovar.B()) fmt.Printf("\t extra: %f~%f\n", s.extraCovar.meanX, s.extraCovar.StddevX()) } diff --git a/cmd/lotus-bench/stats_test.go b/cmd/lotus-bench/stats_test.go index a8cb985a1..16caf3f7e 100644 --- a/cmd/lotus-bench/stats_test.go +++ b/cmd/lotus-bench/stats_test.go @@ -33,13 +33,15 @@ func TestCovar(t *testing.T) { maxJ := rng.Intn(1000) + 500 for j := 0; j < maxJ; j++ { x := rng.NormFloat64()*5 + 500 - ss[i].AddPoint(x, x*(rng.NormFloat64()/10+2)-rng.NormFloat64()-1000) + ss[i].AddPoint(x, x*2-1000) } - t.Logf("covar: %f, y = %f*x+%f @%.0f", ss[i].Covariance(), ss[i].A(), ss[i].B(), ss[i].n) + t.Logf("corell: %f, y = %f*x+%f @%.0f", ss[i].Correl(), ss[i].A(), ss[i].B(), ss[i].n) + t.Logf("\txVar: %f yVar: %f covar: %f", ss[i].StddevX(), ss[i].StddevY(), ss[i].Covariance()) } out := &covar{} for i := 0; i < N; i++ { out.Combine(ss[i]) - t.Logf("combine: covar: %f, y = %f*x+%f", ss[i].Covariance(), ss[i].A(), ss[i].B()) + t.Logf("combine: corell: %f, y = %f*x+%f", out.Correl(), out.A(), out.B()) + t.Logf("\txVar: %f yVar: %f covar: %f", out.StddevX(), out.StddevY(), out.Covariance()) } } From 254295b9c38b8dc63f79e8fc176003eca7dcabf0 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 14:30:58 +0200 Subject: [PATCH 357/379] Readd covariance Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f6a07ca05..1e85d1757 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -588,7 +588,7 @@ var importAnalyzeCmd = &cli.Command{ if s.extraCovar != nil { fmt.Printf("\t correll: %f, tt = %f * extra + %f\n", s.extraCovar.Correl(), s.extraCovar.A(), s.extraCovar.B()) - fmt.Printf("\t extra: %f~%f\n", s.extraCovar.meanX, s.extraCovar.StddevX()) + fmt.Printf("\t covar: %f, extra: %f~%f\n", s.extraCovar.Covariance(), s.extraCovar.meanX, s.extraCovar.StddevX()) } } From 7a7e5a85ad9e7e1b105c4864d3ec36109aef0913 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 14:32:09 +0200 Subject: [PATCH 358/379] Print tt from covar Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 1e85d1757..0b2261a45 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -588,7 +588,8 @@ var importAnalyzeCmd = &cli.Command{ if s.extraCovar != nil { fmt.Printf("\t correll: %f, tt = %f * extra + %f\n", s.extraCovar.Correl(), s.extraCovar.A(), s.extraCovar.B()) - fmt.Printf("\t covar: %f, extra: %f~%f\n", s.extraCovar.Covariance(), s.extraCovar.meanX, s.extraCovar.StddevX()) + fmt.Printf("\t covar: %f, extra: %f~%f, tt2: %f~%f\n", s.extraCovar.Covariance(), + s.extraCovar.meanX, s.extraCovar.StddevX(), s.extraCovar.meanY, s.extraCovar.StddevY()) } } From 39625eada7731562e46c0d49fe55718bb1047ad4 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 14:41:14 +0200 Subject: [PATCH 359/379] Add count Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 0b2261a45..7d2455a81 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -267,9 +267,9 @@ func (v1 *covar) StddevY() float64 { func (cov1 *covar) AddPoint(x, y float64) { cov1.n += 1 + dx := x - cov1.meanX cov1.meanX += dx / cov1.n - dx2 := x - cov1.meanX cov1.m2x += dx * dx2 @@ -586,10 +586,11 @@ var importAnalyzeCmd = &cli.Command{ fmt.Printf("%s: incr by %f~%f; tt %f~%f\n", k, s.gasRatio.Mean(), s.gasRatio.Stddev(), s.timeTaken.Mean(), s.timeTaken.Stddev()) if s.extraCovar != nil { - fmt.Printf("\t correll: %f, tt = %f * extra + %f\n", s.extraCovar.Correl(), + fmt.Printf("\t correll: %.2f, tt = %f * extra + %f\n", s.extraCovar.Correl(), s.extraCovar.A(), s.extraCovar.B()) - fmt.Printf("\t covar: %f, extra: %f~%f, tt2: %f~%f\n", s.extraCovar.Covariance(), - s.extraCovar.meanX, s.extraCovar.StddevX(), s.extraCovar.meanY, s.extraCovar.StddevY()) + fmt.Printf("\t covar: %.2f, extra: %.2f~%.2f, tt2: %.2f~%.2f, count %.0f\n", + s.extraCovar.Covariance(), s.extraCovar.meanX, s.extraCovar.StddevX(), + s.extraCovar.meanY, s.extraCovar.StddevY(), s.extraCovar.n) } } From 42696372ee244e99711fe6d969e27dd7a75f5e53 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 14:42:56 +0200 Subject: [PATCH 360/379] Progress to stderr Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 7d2455a81..f55735e59 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -538,21 +538,21 @@ var importAnalyzeCmd = &cli.Command{ } totalTipsets++ jsonIn <- b - fmt.Printf("\rProcessed %d tipsets", totalTipsets) + fmt.Fprintf(os.Stderr, "\rProcessed %d tipsets", totalTipsets) if err == io.EOF { break } } close(jsonIn) - fmt.Printf("\n") - fmt.Printf("Collecting results\n") + fmt.Fprintf(os.Stderr, "\n") + fmt.Fprintf(os.Stderr, "Collecting results\n") var invocs []Invocation var totalTime time.Duration var keys []string var charges = make(map[string]*stats) for i := 0; i < nWorkers; i++ { - fmt.Printf("\rProcessing results from worker %d/%d", i+1, nWorkers) + fmt.Fprintf(os.Stderr, "\rProcessing results from worker %d/%d", i+1, nWorkers) res := <-results invocs = append(invocs, res.expensiveInvocs...) for k, v := range res.chargeStats { @@ -574,7 +574,7 @@ var importAnalyzeCmd = &cli.Command{ totalTime += res.totalTime } - fmt.Printf("\nCollecting gas keys\n") + fmt.Fprintf(os.Stderr, "\nCollecting gas keys\n") for k := range charges { keys = append(keys, k) } From e9d2a3edd9b83a9f7aaf6b4e94fc355998d37ab8 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 14:45:24 +0200 Subject: [PATCH 361/379] Limit float print precision Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index f55735e59..d3a271022 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -583,10 +583,10 @@ var importAnalyzeCmd = &cli.Command{ sort.Strings(keys) for _, k := range keys { s := charges[k] - fmt.Printf("%s: incr by %f~%f; tt %f~%f\n", k, s.gasRatio.Mean(), s.gasRatio.Stddev(), + fmt.Printf("%s: incr by %.4f~%.4f; tt %.4f~%.4f\n", k, s.gasRatio.Mean(), s.gasRatio.Stddev(), s.timeTaken.Mean(), s.timeTaken.Stddev()) if s.extraCovar != nil { - fmt.Printf("\t correll: %.2f, tt = %f * extra + %f\n", s.extraCovar.Correl(), + fmt.Printf("\t correll: %.2f, tt = %.2f * extra + %.2f\n", s.extraCovar.Correl(), s.extraCovar.A(), s.extraCovar.B()) fmt.Printf("\t covar: %.2f, extra: %.2f~%.2f, tt2: %.2f~%.2f, count %.0f\n", s.extraCovar.Covariance(), s.extraCovar.meanX, s.extraCovar.StddevX(), From 41b775fdd48c6724cfae43cfb485b8a6c5a03173 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 19:59:34 +0200 Subject: [PATCH 362/379] Compute time spent in actors Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index d3a271022..06bdffeaa 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -600,6 +600,10 @@ var importAnalyzeCmd = &cli.Command{ fmt.Println("Total time: ", totalTime) fmt.Println("Average time per epoch: ", totalTime/time.Duration(totalTipsets)) + if actorExec, ok := charges["OnActorExec"]; ok { + timeInActors := actorExec.timeTaken.Mean() * actorExec.timeTaken.n + fmt.Printf("Avarage time per epoch in actors: %s (%.1f%%)\n", time.Duration(timeInActors)/time.Duration(totalTipsets), timeInActors/float64(totalTime)*100) + } n := 30 if len(invocs) < n { From 11dc902d53deb2e805e09ce9823383292a1cd5a3 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 20:12:01 +0200 Subject: [PATCH 363/379] Adjust OnMethodInvocation Signed-off-by: Jakub Sztandera --- chain/vm/gas_v0.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index b0c839f2f..37eea066a 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -99,7 +99,7 @@ func (pl *pricelistV0) OnChainReturnValue(dataSize int) GasCharge { func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge { ret := pl.sendBase extra := "" - virtGas := int64(1069512) + virtGas := int64(1072944) if value != abi.NewTokenAmount(0) { // TODO: fix this, it is comparing pointers instead of values @@ -107,10 +107,10 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M ret += pl.sendTransferFunds } if big.Cmp(value, abi.NewTokenAmount(0)) != 0 { - virtGas += 498173 + virtGas += 497495 if methodNum == builtin.MethodSend { // transfer only - virtGas += 968198 + virtGas += 973940 } extra += "t" } @@ -118,9 +118,9 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M ret += pl.sendInvokeMethod extra += "i" // running actors is cheaper becase we hand over to actors - virtGas += -294632 + virtGas += -295779 } - return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(86315, 0).WithExtra(extra) + return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(virtGas, 0).WithExtra(extra) } // OnIpldGet returns the gas used for storing an object From 3429941639fa20f6984125bc051cff1128e34aa8 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 20:13:22 +0200 Subject: [PATCH 364/379] Add info about OnActorExecDone Signed-off-by: Jakub Sztandera --- cmd/lotus-bench/import.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 06bdffeaa..6d5f7f8ff 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -604,6 +604,10 @@ var importAnalyzeCmd = &cli.Command{ timeInActors := actorExec.timeTaken.Mean() * actorExec.timeTaken.n fmt.Printf("Avarage time per epoch in actors: %s (%.1f%%)\n", time.Duration(timeInActors)/time.Duration(totalTipsets), timeInActors/float64(totalTime)*100) } + if actorExecDone, ok := charges["OnActorExecDone"]; ok { + timeInActors := actorExecDone.timeTaken.Mean() * actorExecDone.timeTaken.n + fmt.Printf("Avarage time per epoch in OnActorExecDone %s (%.1f%%)\n", time.Duration(timeInActors)/time.Duration(totalTipsets), timeInActors/float64(totalTime)*100) + } n := 30 if len(invocs) < n { From c4158f12f120a40ac05e46c939d407e4eda9fba0 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 30 Jun 2020 23:06:36 +0200 Subject: [PATCH 365/379] Include proof number as extra in OnVerifyPost Signed-off-by: Jakub Sztandera --- chain/vm/gas_v0.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index 37eea066a..5735d0b83 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -188,7 +188,7 @@ func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge { // OnVerifyPost func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus - return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0).WithVirtual(2629471704, 0) + return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0).WithVirtual(2629471704, 0).WithExtra(len(info.ChallengedSectors)) } // OnVerifyConsensusFault From f3f92ce5bc03639ea92cf0a2edea223b35353adb Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 2 Jul 2020 18:42:06 +0200 Subject: [PATCH 366/379] add scratchpad to gitignore Signed-off-by: Jakub Sztandera --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6aaaf9240..fce23289f 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ build/paramfetch.sh bin/ipget bin/tmp/* .idea +scratchpad From 567b8082c31243c77cf54630796bd7d7e8606e9b Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 2 Jul 2020 18:42:42 +0200 Subject: [PATCH 367/379] Back to 10 callers Signed-off-by: Jakub Sztandera --- chain/vm/runtime.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index c1581dcd9..6de8fec9b 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -525,7 +525,7 @@ func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) { func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError { toUse := gas.Total() - var callers [4]uintptr + var callers [10]uintptr cout := gruntime.Callers(2+skip, callers[:]) now := time.Now() From 3e4b80e7f6abb6ea0e5ffbec72413aa541e66873 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 2 Jul 2020 19:20:35 +0200 Subject: [PATCH 368/379] Update specs actors Signed-off-by: Jakub Sztandera --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ec3f20ebc..1591639e5 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/sector-storage v0.0.0-20200630180318-4c1968f62a8f - github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 + github.com/filecoin-project/specs-actors v0.6.2-0.20200702170846-2cd72643a5cf github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea github.com/filecoin-project/storage-fsm v0.0.0-20200625160832-379a4655b044 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 21349bbb6..025c209dd 100644 --- a/go.sum +++ b/go.sum @@ -264,6 +264,8 @@ github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8o github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= +github.com/filecoin-project/specs-actors v0.6.2-0.20200702170846-2cd72643a5cf h1:2ERozAZteHYef3tVLVJRepzYieLtJdxvfXNUel19CeU= +github.com/filecoin-project/specs-actors v0.6.2-0.20200702170846-2cd72643a5cf/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY= From cc02092aaeef95351be57c2b6968499e43d394cc Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 2 Jul 2020 21:53:21 +0200 Subject: [PATCH 369/379] Go mod tidy Signed-off-by: Jakub Sztandera --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 025c209dd..0f334363a 100644 --- a/go.sum +++ b/go.sum @@ -262,8 +262,6 @@ github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.m github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= -github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= -github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.2-0.20200702170846-2cd72643a5cf h1:2ERozAZteHYef3tVLVJRepzYieLtJdxvfXNUel19CeU= github.com/filecoin-project/specs-actors v0.6.2-0.20200702170846-2cd72643a5cf/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= From 5fb76ddad265e10b0ba8075fa217dfe5fe00d4c5 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 2 Jul 2020 22:09:11 +0200 Subject: [PATCH 370/379] Bump version Signed-off-by: Jakub Sztandera --- build/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/version.go b/build/version.go index fc64eae71..b5d48eac7 100644 --- a/build/version.go +++ b/build/version.go @@ -25,7 +25,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "0.4.0" +const BuildVersion = "0.4.1" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From 809a3ba07cac6527a967a180cdb45bf96dfede16 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 2 Jul 2020 16:48:14 -0700 Subject: [PATCH 371/379] check underlying datastore for objects before putting to bufbstore --- lib/bufbstore/buf_bstore.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/bufbstore/buf_bstore.go b/lib/bufbstore/buf_bstore.go index e1aad94df..4b430828b 100644 --- a/lib/bufbstore/buf_bstore.go +++ b/lib/bufbstore/buf_bstore.go @@ -108,6 +108,15 @@ func (bs *BufferedBS) GetSize(c cid.Cid) (int, error) { } func (bs *BufferedBS) Put(blk block.Block) error { + has, err := bs.read.Has(blk.Cid()) + if err != nil { + return err + } + + if has { + return nil + } + return bs.write.Put(blk) } From 17039a5672f7e640f4dbf0a9bb82e2388c584ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Jul 2020 02:23:45 +0200 Subject: [PATCH 372/379] Update FFI --- extern/filecoin-ffi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 5342c7c97..6a143e06f 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 5342c7c97d1a1df4650629d14f2823d52889edd9 +Subproject commit 6a143e06f923f3a4f544c7a652e8b4df420a3d28 From c3393ee18527ebead69c6fbceffebd2f29a92f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Jul 2020 02:47:33 +0200 Subject: [PATCH 373/379] seed: Move sector preseal to separate func --- cmd/lotus-seed/seed/seed.go | 72 +++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 08ae91200..6650a8e6c 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -68,41 +68,12 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect sid := abi.SectorID{Miner: abi.ActorID(mid), Number: next} next++ - pi, err := sb.AddPiece(context.TODO(), sid, nil, abi.PaddedPieceSize(ssize).Unpadded(), rand.Reader) + preseal, err := presealSector(sb, sbfs, sid, spt, ssize, preimage) if err != nil { return nil, nil, err } - trand := blake2b.Sum256(preimage) - ticket := abi.SealRandomness(trand[:]) - - fmt.Printf("sector-id: %d, piece info: %v\n", sid, pi) - - in2, err := sb.SealPreCommit1(context.TODO(), sid, ticket, []abi.PieceInfo{pi}) - if err != nil { - return nil, nil, xerrors.Errorf("commit: %w", err) - } - - cids, err := sb.SealPreCommit2(context.TODO(), sid, in2) - if err != nil { - return nil, nil, xerrors.Errorf("commit: %w", err) - } - - if err := sb.FinalizeSector(context.TODO(), sid, nil); err != nil { - return nil, nil, xerrors.Errorf("trim cache: %w", err) - } - - if err := cleanupUnsealed(sbfs, sid); err != nil { - return nil, nil, xerrors.Errorf("remove unsealed file: %w", err) - } - - log.Warn("PreCommitOutput: ", sid, cids.Sealed, cids.Unsealed) - sealedSectors = append(sealedSectors, &genesis.PreSeal{ - CommR: cids.Sealed, - CommD: cids.Unsealed, - SectorID: sid.Number, - ProofType: spt, - }) + sealedSectors = append(sealedSectors, preseal) } var minerAddr *wallet.Key @@ -165,6 +136,45 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect return miner, &minerAddr.KeyInfo, nil } +func presealSector(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, sid abi.SectorID, spt abi.RegisteredSealProof, ssize abi.SectorSize, preimage []byte) (*genesis.PreSeal, error) { + pi, err := sb.AddPiece(context.TODO(), sid, nil, abi.PaddedPieceSize(ssize).Unpadded(), rand.Reader) + if err != nil { + return nil, err + } + + trand := blake2b.Sum256(preimage) + ticket := abi.SealRandomness(trand[:]) + + fmt.Printf("sector-id: %d, piece info: %v\n", sid, pi) + + in2, err := sb.SealPreCommit1(context.TODO(), sid, ticket, []abi.PieceInfo{pi}) + if err != nil { + return nil, xerrors.Errorf("commit: %w", err) + } + + cids, err := sb.SealPreCommit2(context.TODO(), sid, in2) + if err != nil { + return nil, xerrors.Errorf("commit: %w", err) + } + + if err := sb.FinalizeSector(context.TODO(), sid, nil); err != nil { + return nil, xerrors.Errorf("trim cache: %w", err) + } + + if err := cleanupUnsealed(sbfs, sid); err != nil { + return nil, xerrors.Errorf("remove unsealed file: %w", err) + } + + log.Warn("PreCommitOutput: ", sid, cids.Sealed, cids.Unsealed) + + return &genesis.PreSeal{ + CommR: cids.Sealed, + CommD: cids.Unsealed, + SectorID: sid.Number, + ProofType: spt, + }, nil +} + func cleanupUnsealed(sbfs *basicfs.Provider, sid abi.SectorID) error { paths, done, err := sbfs.AcquireSector(context.TODO(), sid, stores.FTUnsealed, stores.FTNone, stores.PathSealing) if err != nil { From bb3758f648ddcc7ef0adc762e5ffaf19fc341665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Jul 2020 03:29:06 +0200 Subject: [PATCH 374/379] seed: Support fake preseals --- chain/gen/gen.go | 4 ++-- cmd/lotus-seed/main.go | 6 +++++- cmd/lotus-seed/seed/seed.go | 42 +++++++++++++++++++++++++++++++++---- lotuspond/spawn.go | 2 +- node/node_test.go | 2 +- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index ebf868765..54040deb4 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -145,7 +145,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { return nil, err } - genm1, k1, err := seed.PreSeal(maddr1, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m1temp, []byte("some randomness"), nil) + genm1, k1, err := seed.PreSeal(maddr1, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m1temp, []byte("some randomness"), nil, true) if err != nil { return nil, err } @@ -157,7 +157,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { return nil, err } - genm2, k2, err := seed.PreSeal(maddr2, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m2temp, []byte("some randomness"), nil) + genm2, k2, err := seed.PreSeal(maddr2, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m2temp, []byte("some randomness"), nil, true) if err != nil { return nil, err } diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index 1e4f8fe0d..827c0f112 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -89,6 +89,10 @@ var preSealCmd = &cli.Command{ Value: "", Usage: "(optional) Key to use for signing / owner/worker addresses", }, + &cli.BoolFlag{ + Name: "fake-sectors", + Value: false, + }, }, Action: func(c *cli.Context) error { sdir := c.String("sector-dir") @@ -126,7 +130,7 @@ var preSealCmd = &cli.Command{ return err } - gm, key, err := seed.PreSeal(maddr, rp, abi.SectorNumber(c.Uint64("sector-offset")), c.Int("num-sectors"), sbroot, []byte(c.String("ticket-preimage")), k) + gm, key, err := seed.PreSeal(maddr, rp, abi.SectorNumber(c.Uint64("sector-offset")), c.Int("num-sectors"), sbroot, []byte(c.String("ticket-preimage")), k, c.Bool("fake-sectors")) if err != nil { return err } diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 6650a8e6c..1d6c3da29 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -17,7 +17,9 @@ import ( "github.com/minio/blake2b-simd" "golang.org/x/xerrors" + ffi "github.com/filecoin-project/filecoin-ffi" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/sector-storage/zerocomm" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin/market" @@ -33,7 +35,7 @@ import ( var log = logging.Logger("preseal") -func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) { +func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo, fakeSectors bool) (*genesis.Miner, *types.KeyInfo, error) { mid, err := address.IDFromAddress(maddr) if err != nil { return nil, nil, err @@ -68,9 +70,17 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect sid := abi.SectorID{Miner: abi.ActorID(mid), Number: next} next++ - preseal, err := presealSector(sb, sbfs, sid, spt, ssize, preimage) - if err != nil { - return nil, nil, err + var preseal *genesis.PreSeal + if !fakeSectors { + preseal, err = presealSector(sb, sbfs, sid, spt, ssize, preimage) + if err != nil { + return nil, nil, err + } + } else { + preseal, err = presealSectorFake(sbfs, sid, spt, ssize) + if err != nil { + return nil, nil, err + } } sealedSectors = append(sealedSectors, preseal) @@ -175,6 +185,30 @@ func presealSector(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, sid abi.Sector }, nil } +func presealSectorFake(sbfs *basicfs.Provider, sid abi.SectorID, spt abi.RegisteredSealProof, ssize abi.SectorSize) (*genesis.PreSeal, error) { + paths, done, err := sbfs.AcquireSector(context.TODO(), sid, 0, stores.FTSealed | stores.FTCache, true) + if err != nil { + return nil, xerrors.Errorf("acquire unsealed sector: %w", err) + } + defer done() + + if err := os.Mkdir(paths.Cache, 0755); err != nil { + return nil, xerrors.Errorf("mkdir cache: %w", err) + } + + commr, err := ffi.FauxRep(spt, paths.Cache, paths.Sealed) + if err != nil { + return nil, xerrors.Errorf("fauxrep: %w", err) + } + + return &genesis.PreSeal{ + CommR: commr, + CommD: zerocomm.ZeroPieceCommitment(abi.PaddedPieceSize(ssize).Unpadded()), + SectorID: sid.Number, + ProofType: spt, + }, nil +} + func cleanupUnsealed(sbfs *basicfs.Provider, sid abi.SectorID) error { paths, done, err := sbfs.AcquireSector(context.TODO(), sid, stores.FTUnsealed, stores.FTNone, stores.PathSealing) if err != nil { diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index 8100d784a..ef0ebaeab 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -49,7 +49,7 @@ func (api *api) Spawn() (nodeInfo, error) { } sbroot := filepath.Join(dir, "preseal") - genm, ki, err := seed.PreSeal(genMiner, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, 2, sbroot, []byte("8"), nil) + genm, ki, err := seed.PreSeal(genMiner, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, 2, sbroot, []byte("8"), nil, false) if err != nil { return nodeInfo{}, xerrors.Errorf("preseal failed: %w", err) } diff --git a/node/node_test.go b/node/node_test.go index b9837b1f0..6f33c6c57 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -189,7 +189,7 @@ func builder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test.TestN if err != nil { t.Fatal(err) } - genm, k, err := seed.PreSeal(maddr, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, test.GenesisPreseals, tdir, []byte("make genesis mem random"), nil) + genm, k, err := seed.PreSeal(maddr, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, test.GenesisPreseals, tdir, []byte("make genesis mem random"), nil, true) if err != nil { t.Fatal(err) } From 8b88c1750311025337a4ccbc6e0c6204824e11ae Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 3 Jul 2020 16:52:40 +0200 Subject: [PATCH 375/379] extract stats package --- {tools/stats => cmd/lotus-stats}/README.md | 12 +- .../lotus-stats}/chain.dashboard.json | 0 .../lotus-stats}/docker-compose.yml | 0 {tools/stats => cmd/lotus-stats}/env.stats | 0 cmd/lotus-stats/main.go | 76 +++++++++++ {tools/stats => cmd/lotus-stats}/setup.bash | 0 tools/stats/collect.go | 65 +++++++++ tools/stats/head_buffer.go | 2 +- tools/stats/head_buffer_test.go | 2 +- tools/stats/main.go | 126 ------------------ tools/stats/metrics.go | 6 +- tools/stats/rpc.go | 2 +- 12 files changed, 155 insertions(+), 136 deletions(-) rename {tools/stats => cmd/lotus-stats}/README.md (61%) rename {tools/stats => cmd/lotus-stats}/chain.dashboard.json (100%) rename {tools/stats => cmd/lotus-stats}/docker-compose.yml (100%) rename {tools/stats => cmd/lotus-stats}/env.stats (100%) create mode 100644 cmd/lotus-stats/main.go rename {tools/stats => cmd/lotus-stats}/setup.bash (100%) create mode 100644 tools/stats/collect.go delete mode 100644 tools/stats/main.go diff --git a/tools/stats/README.md b/cmd/lotus-stats/README.md similarity index 61% rename from tools/stats/README.md rename to cmd/lotus-stats/README.md index a75671220..04220aa3b 100644 --- a/tools/stats/README.md +++ b/cmd/lotus-stats/README.md @@ -1,6 +1,6 @@ -# Stats +# lotus-stats -Stats is a small tool to push chain information into influxdb +`lotus-stats` is a small tool to push chain information into influxdb ## Setup @@ -14,13 +14,13 @@ INFLUX_PASS="" ## Usage -Stats will be default look in `~/.lotus` to connect to a running daemon and resume collecting stats from last record block height. +lotus-stats will be default look in `~/.lotus` to connect to a running daemon and resume collecting stats from last record block height. -For other usage see `./stats --help` +For other usage see `./lotus-stats --help` ``` -go build -o stats *.go -. env.stats && ./stats +go build -o lotus-stats *.go +. env.stats && ./lotus-stats ``` diff --git a/tools/stats/chain.dashboard.json b/cmd/lotus-stats/chain.dashboard.json similarity index 100% rename from tools/stats/chain.dashboard.json rename to cmd/lotus-stats/chain.dashboard.json diff --git a/tools/stats/docker-compose.yml b/cmd/lotus-stats/docker-compose.yml similarity index 100% rename from tools/stats/docker-compose.yml rename to cmd/lotus-stats/docker-compose.yml diff --git a/tools/stats/env.stats b/cmd/lotus-stats/env.stats similarity index 100% rename from tools/stats/env.stats rename to cmd/lotus-stats/env.stats diff --git a/cmd/lotus-stats/main.go b/cmd/lotus-stats/main.go new file mode 100644 index 000000000..a83493762 --- /dev/null +++ b/cmd/lotus-stats/main.go @@ -0,0 +1,76 @@ +package main + +import ( + "context" + "flag" + "os" + + "github.com/filecoin-project/lotus/tools/stats" + logging "github.com/ipfs/go-log/v2" +) + +var log = logging.Logger("stats") + +const ( + INFLUX_ADDR = "INFLUX_ADDR" + INFLUX_USER = "INFLUX_USER" + INFLUX_PASS = "INFLUX_PASS" +) + +func main() { + var repo string = "~/.lotus" + var database string = "lotus" + var reset bool = false + var nosync bool = false + var height int64 = 0 + var headlag int = 3 + + flag.StringVar(&repo, "repo", repo, "lotus repo path") + flag.StringVar(&database, "database", database, "influx database") + flag.Int64Var(&height, "height", height, "block height to start syncing from (0 will resume)") + flag.IntVar(&headlag, "head-lag", headlag, "number of head events to hold to protect against small reorgs") + flag.BoolVar(&reset, "reset", reset, "truncate database before starting stats gathering") + flag.BoolVar(&nosync, "nosync", nosync, "skip waiting for sync") + + flag.Parse() + + influxAddr := os.Getenv(INFLUX_ADDR) + influxUser := os.Getenv(INFLUX_USER) + influxPass := os.Getenv(INFLUX_PASS) + + ctx := context.Background() + + influx, err := stats.InfluxClient(influxAddr, influxUser, influxPass) + if err != nil { + log.Fatal(err) + } + + if reset { + if err := stats.ResetDatabase(influx, database); err != nil { + log.Fatal(err) + } + } + + if !reset && height == 0 { + h, err := stats.GetLastRecordedHeight(influx, database) + if err != nil { + log.Info(err) + } + + height = h + } + + api, closer, err := stats.GetFullNodeAPI(repo) + if err != nil { + log.Fatal(err) + } + defer closer() + + if !nosync { + if err := stats.WaitForSyncComplete(ctx, api); err != nil { + log.Fatal(err) + } + } + + stats.Collect(ctx, api, influx, database, height) +} diff --git a/tools/stats/setup.bash b/cmd/lotus-stats/setup.bash similarity index 100% rename from tools/stats/setup.bash rename to cmd/lotus-stats/setup.bash diff --git a/tools/stats/collect.go b/tools/stats/collect.go new file mode 100644 index 000000000..98a8c79d0 --- /dev/null +++ b/tools/stats/collect.go @@ -0,0 +1,65 @@ +package stats + +import ( + "context" + "time" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/specs-actors/actors/abi" + client "github.com/influxdata/influxdb1-client/v2" +) + +var headlag int = 3 + +func Collect(ctx context.Context, api api.FullNode, influx client.Client, database string, height int64) { + tipsetsCh, err := GetTips(ctx, api, abi.ChainEpoch(height), headlag) + if err != nil { + log.Fatal(err) + } + + wq := NewInfluxWriteQueue(ctx, influx) + defer wq.Close() + + for tipset := range tipsetsCh { + log.Infow("Collect stats", "height", tipset.Height()) + pl := NewPointList() + height := tipset.Height() + + if err := RecordTipsetPoints(ctx, api, pl, tipset); err != nil { + log.Warnw("Failed to record tipset", "height", height, "error", err) + continue + } + + if err := RecordTipsetMessagesPoints(ctx, api, pl, tipset); err != nil { + log.Warnw("Failed to record messages", "height", height, "error", err) + continue + } + + if err := RecordTipsetStatePoints(ctx, api, pl, tipset); err != nil { + log.Warnw("Failed to record state", "height", height, "error", err) + continue + } + + // Instead of having to pass around a bunch of generic stuff we want for each point + // we will just add them at the end. + + tsTimestamp := time.Unix(int64(tipset.MinTimestamp()), int64(0)) + + nb, err := InfluxNewBatch() + if err != nil { + log.Fatal(err) + } + + for _, pt := range pl.Points() { + pt.SetTime(tsTimestamp) + + nb.AddPoint(NewPointFrom(pt)) + } + + nb.SetDatabase(database) + + log.Infow("Adding points", "count", len(nb.Points()), "height", tipset.Height()) + + wq.AddBatch(nb) + } +} diff --git a/tools/stats/head_buffer.go b/tools/stats/head_buffer.go index 08a817233..1c3bf9777 100644 --- a/tools/stats/head_buffer.go +++ b/tools/stats/head_buffer.go @@ -1,4 +1,4 @@ -package main +package stats import ( "container/list" diff --git a/tools/stats/head_buffer_test.go b/tools/stats/head_buffer_test.go index 6266f35fd..098c90a96 100644 --- a/tools/stats/head_buffer_test.go +++ b/tools/stats/head_buffer_test.go @@ -1,4 +1,4 @@ -package main +package stats import ( "testing" diff --git a/tools/stats/main.go b/tools/stats/main.go deleted file mode 100644 index b3f6eff33..000000000 --- a/tools/stats/main.go +++ /dev/null @@ -1,126 +0,0 @@ -package main - -import ( - "context" - "flag" - "os" - "time" - - "github.com/filecoin-project/specs-actors/actors/abi" - logging "github.com/ipfs/go-log/v2" -) - -var log = logging.Logger("stats") - -const ( - INFLUX_ADDR = "INFLUX_ADDR" - INFLUX_USER = "INFLUX_USER" - INFLUX_PASS = "INFLUX_PASS" -) - -func main() { - var repo string = "~/.lotus" - var database string = "lotus" - var reset bool = false - var nosync bool = false - var height int64 = 0 - var headlag int = 3 - - flag.StringVar(&repo, "repo", repo, "lotus repo path") - flag.StringVar(&database, "database", database, "influx database") - flag.Int64Var(&height, "height", height, "block height to start syncing from (0 will resume)") - flag.IntVar(&headlag, "head-lag", headlag, "number of head events to hold to protect against small reorgs") - flag.BoolVar(&reset, "reset", reset, "truncate database before starting stats gathering") - flag.BoolVar(&nosync, "nosync", nosync, "skip waiting for sync") - - flag.Parse() - - influxAddr := os.Getenv(INFLUX_ADDR) - influxUser := os.Getenv(INFLUX_USER) - influxPass := os.Getenv(INFLUX_PASS) - - ctx := context.Background() - - influx, err := InfluxClient(influxAddr, influxUser, influxPass) - if err != nil { - log.Fatal(err) - } - - if reset { - if err := ResetDatabase(influx, database); err != nil { - log.Fatal(err) - } - } - - if !reset && height == 0 { - h, err := GetLastRecordedHeight(influx, database) - if err != nil { - log.Info(err) - } - - height = h - } - - api, closer, err := GetFullNodeAPI(repo) - if err != nil { - log.Fatal(err) - } - defer closer() - - if !nosync { - if err := WaitForSyncComplete(ctx, api); err != nil { - log.Fatal(err) - } - } - - tipsetsCh, err := GetTips(ctx, api, abi.ChainEpoch(height), headlag) - if err != nil { - log.Fatal(err) - } - - wq := NewInfluxWriteQueue(ctx, influx) - defer wq.Close() - - for tipset := range tipsetsCh { - log.Infow("Collect stats", "height", tipset.Height()) - pl := NewPointList() - height := tipset.Height() - - if err := RecordTipsetPoints(ctx, api, pl, tipset); err != nil { - log.Warnw("Failed to record tipset", "height", height, "error", err) - continue - } - - if err := RecordTipsetMessagesPoints(ctx, api, pl, tipset); err != nil { - log.Warnw("Failed to record messages", "height", height, "error", err) - continue - } - - if err := RecordTipsetStatePoints(ctx, api, pl, tipset); err != nil { - log.Warnw("Failed to record state", "height", height, "error", err) - continue - } - - // Instead of having to pass around a bunch of generic stuff we want for each point - // we will just add them at the end. - - tsTimestamp := time.Unix(int64(tipset.MinTimestamp()), int64(0)) - - nb, err := InfluxNewBatch() - if err != nil { - log.Fatal(err) - } - - for _, pt := range pl.Points() { - pt.SetTime(tsTimestamp) - - nb.AddPoint(NewPointFrom(pt)) - } - - nb.SetDatabase(database) - - log.Infow("Adding points", "count", len(nb.Points()), "height", tipset.Height()) - - wq.AddBatch(nb) - } -} diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index 53fa6ed63..626363731 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -1,4 +1,4 @@ -package main +package stats import ( "bytes" @@ -25,8 +25,12 @@ import ( _ "github.com/influxdata/influxdb1-client" models "github.com/influxdata/influxdb1-client/models" client "github.com/influxdata/influxdb1-client/v2" + + logging "github.com/ipfs/go-log/v2" ) +var log = logging.Logger("stats") + type PointList struct { points []models.Point } diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index a94ab955b..d053ff561 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -1,4 +1,4 @@ -package main +package stats import ( "context" From 4679c35e61798b9f93cb435d20ce9d12a9f1afdb Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 3 Jul 2020 19:22:04 +0200 Subject: [PATCH 376/379] include headlag in func signature --- cmd/lotus-stats/main.go | 2 +- tools/stats/collect.go | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-stats/main.go b/cmd/lotus-stats/main.go index a83493762..2dd654737 100644 --- a/cmd/lotus-stats/main.go +++ b/cmd/lotus-stats/main.go @@ -72,5 +72,5 @@ func main() { } } - stats.Collect(ctx, api, influx, database, height) + stats.Collect(ctx, api, influx, database, height, headlag) } diff --git a/tools/stats/collect.go b/tools/stats/collect.go index 98a8c79d0..3d031a415 100644 --- a/tools/stats/collect.go +++ b/tools/stats/collect.go @@ -9,9 +9,7 @@ import ( client "github.com/influxdata/influxdb1-client/v2" ) -var headlag int = 3 - -func Collect(ctx context.Context, api api.FullNode, influx client.Client, database string, height int64) { +func Collect(ctx context.Context, api api.FullNode, influx client.Client, database string, height int64, headlag int) { tipsetsCh, err := GetTips(ctx, api, abi.ChainEpoch(height), headlag) if err != nil { log.Fatal(err) From fe49bcd9faa797ce96f39736f24e40b00ef4e1f3 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 3 Jul 2020 19:52:15 +0200 Subject: [PATCH 377/379] make linter happy --- cmd/lotus-stats/main.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/cmd/lotus-stats/main.go b/cmd/lotus-stats/main.go index 2dd654737..ddc33b7ac 100644 --- a/cmd/lotus-stats/main.go +++ b/cmd/lotus-stats/main.go @@ -12,9 +12,9 @@ import ( var log = logging.Logger("stats") const ( - INFLUX_ADDR = "INFLUX_ADDR" - INFLUX_USER = "INFLUX_USER" - INFLUX_PASS = "INFLUX_PASS" + influxAddrEnvVar = "INFLUX_ADDR" + influxUserEnvVar = "INFLUX_USER" + influxPassEnvVar = "INFLUX_PASS" ) func main() { @@ -34,13 +34,9 @@ func main() { flag.Parse() - influxAddr := os.Getenv(INFLUX_ADDR) - influxUser := os.Getenv(INFLUX_USER) - influxPass := os.Getenv(INFLUX_PASS) - ctx := context.Background() - influx, err := stats.InfluxClient(influxAddr, influxUser, influxPass) + influx, err := stats.InfluxClient(os.Getenv(influxAddrEnvVar), os.Getenv(influxUserEnvVar), os.Getenv(influxPassEnvVar)) if err != nil { log.Fatal(err) } From 4e0cf1644f62aff09cb93ccf0ed6f721431a1cec Mon Sep 17 00:00:00 2001 From: Travis Person Date: Fri, 3 Jul 2020 19:01:56 +0000 Subject: [PATCH 378/379] fountain: populate miner sector dropdown from specs-actors --- cmd/lotus-fountain/main.go | 71 +++++++++++++++++++ .../site/{miner.html => _miner.html} | 5 +- 2 files changed, 74 insertions(+), 2 deletions(-) rename cmd/lotus-fountain/site/{miner.html => _miner.html} (90%) diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index c5c6d5857..9743f209f 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -4,9 +4,13 @@ import ( "bytes" "context" "fmt" + "html/template" + "io" + "io/ioutil" "net" "net/http" "os" + "sort" "strconv" "time" @@ -28,12 +32,47 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" ) var log = logging.Logger("main") var sendPerRequest, _ = types.ParseFIL("50") +var supportedSectors struct { + SectorSizes []struct { + Name string + Value uint64 + Default bool + } +} + +func init() { + for supportedSector, _ := range miner.SupportedProofTypes { + sectorSize, err := supportedSector.SectorSize() + if err != nil { + panic(err) + } + + supportedSectors.SectorSizes = append(supportedSectors.SectorSizes, struct { + Name string + Value uint64 + Default bool + }{ + Name: sectorSize.ShortString(), + Value: uint64(sectorSize), + Default: false, + }) + + } + + sort.Slice(supportedSectors.SectorSizes[:], func(i, j int) bool { + return supportedSectors.SectorSizes[i].Value < supportedSectors.SectorSizes[j].Value + }) + + supportedSectors.SectorSizes[0].Default = true +} + func main() { logging.SetLogLevel("*", "INFO") @@ -125,6 +164,7 @@ var runCmd = &cli.Command{ } http.Handle("/", http.FileServer(rice.MustFindBox("site").HTTPBox())) + http.HandleFunc("/miner.html", h.minerhtml) http.HandleFunc("/send", h.send) http.HandleFunc("/mkminer", h.mkminer) http.HandleFunc("/msgwait", h.msgwait) @@ -153,6 +193,37 @@ type handler struct { defaultMinerPeer peer.ID } +func (h *handler) minerhtml(w http.ResponseWriter, r *http.Request) { + f, err := rice.MustFindBox("site").Open("_miner.html") + if err != nil { + w.WriteHeader(500) + _, _ = w.Write([]byte(err.Error())) + return + } + + tmpl, err := ioutil.ReadAll(f) + if err != nil { + w.WriteHeader(500) + _, _ = w.Write([]byte(err.Error())) + return + } + + var executedTmpl bytes.Buffer + + t, err := template.New("miner.html").Parse(string(tmpl)) + if err := t.Execute(&executedTmpl, supportedSectors); err != nil { + w.WriteHeader(500) + _, _ = w.Write([]byte(err.Error())) + return + } + + if _, err := io.Copy(w, &executedTmpl); err != nil { + log.Errorf("failed to write template to string %s", err) + } + + return +} + func (h *handler) send(w http.ResponseWriter, r *http.Request) { to, err := address.NewFromString(r.FormValue("address")) if err != nil { diff --git a/cmd/lotus-fountain/site/miner.html b/cmd/lotus-fountain/site/_miner.html similarity index 90% rename from cmd/lotus-fountain/site/miner.html rename to cmd/lotus-fountain/site/_miner.html index b8d6a1edd..d83f90d72 100644 --- a/cmd/lotus-fountain/site/miner.html +++ b/cmd/lotus-fountain/site/_miner.html @@ -15,8 +15,9 @@ Enter owner/worker address: From d3a007fd0a19722928eed3148a34db181e5a4479 Mon Sep 17 00:00:00 2001 From: Travis Person Date: Fri, 3 Jul 2020 19:03:02 +0000 Subject: [PATCH 379/379] lotus-shed: fix secp256k1 --- cmd/lotus-shed/keyinfo.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cmd/lotus-shed/keyinfo.go b/cmd/lotus-shed/keyinfo.go index 2d8ca3dca..028ead413 100644 --- a/cmd/lotus-shed/keyinfo.go +++ b/cmd/lotus-shed/keyinfo.go @@ -121,8 +121,7 @@ var keyinfoImportCmd = &cli.Command{ fmt.Printf("%s\n", peerid.String()) break - case wallet.KTSecp256k1: - case wallet.KTBLS: + case wallet.KTSecp256k1, wallet.KTBLS: w, err := wallet.NewWallet(keystore) if err != nil { return err @@ -223,8 +222,7 @@ var keyinfoInfoCmd = &cli.Command{ kio.PublicKey = base64.StdEncoding.EncodeToString(pkBytes) break - case wallet.KTSecp256k1: - case wallet.KTBLS: + case wallet.KTSecp256k1, wallet.KTBLS: kio.Type = keyInfo.Type key, err := wallet.NewKey(keyInfo) @@ -311,8 +309,7 @@ var keyinfoNewCmd = &cli.Command{ keyInfo = ki break - case wallet.KTSecp256k1: - case wallet.KTBLS: + case wallet.KTSecp256k1, wallet.KTBLS: key, err := wallet.GenerateKey(wallet.ActSigType(keyType)) if err != nil { return err