Merge remote-tracking branch 'origin/master' into feat/chainwatch-pg

This commit is contained in:
Łukasz Magiera 2020-01-08 15:08:34 +01:00
commit ab922ed1ba
240 changed files with 3241 additions and 4515 deletions

View File

@ -37,14 +37,13 @@ commands:
- restore_cache: - restore_cache:
name: Restore parameters cache name: Restore parameters cache
keys: keys:
- 'v20-1k-lotus-params-{{ checksum "build/proof-params/parameters.json" }}-{{ checksum "build/paramfetch.go" }}' - 'v20-1k-lotus-params'
- 'v20-1k-lotus-params-{{ checksum "build/proof-params/parameters.json" }}-'
paths: paths:
- /var/tmp/filecoin-proof-parameters/ - /var/tmp/filecoin-proof-parameters/
- run: ./lotus fetch-params --proving-params 1024 - run: ./lotus fetch-params --proving-params 1024
- save_cache: - save_cache:
name: Save parameters cache name: Save parameters cache
key: 'v20-1k-lotus-params-{{ checksum "build/proof-params/parameters.json" }}-{{ checksum "build/paramfetch.go" }}' key: 'v20-1k-lotus-params'
paths: paths:
- /var/tmp/filecoin-proof-parameters/ - /var/tmp/filecoin-proof-parameters/
@ -157,7 +156,7 @@ jobs:
test-short: test-short:
<<: *test <<: *test
build_macos: build-macos:
description: build darwin lotus binary description: build darwin lotus binary
macos: macos:
xcode: "10.0.0" xcode: "10.0.0"
@ -187,23 +186,20 @@ jobs:
chmod +x $HOME/.bin/jq chmod +x $HOME/.bin/jq
- restore_cache: - restore_cache:
name: restore go mod and cargo cache name: restore go mod and cargo cache
key: v1-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.mod" }} key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
- install-deps - install-deps
- go/mod-download - go/mod-download
- run: - run:
command: make build command: make buildall
no_output_timeout: 30m no_output_timeout: 30m
- store_artifacts: - store_artifacts:
path: lotus path: lotus
- store_artifacts: - store_artifacts:
path: lotus-storage-miner path: lotus-storage-miner
- save_cache: - save_cache:
name: save go mod and cargo cache name: save cargo cache
key: v1-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.mod" }} key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
paths: paths:
- "~/go/pkg"
- "~/go/src/github.com"
- "~/go/src/golang.org"
- "~/.rustup" - "~/.rustup"
- "~/.cargo" - "~/.cargo"
@ -262,7 +258,4 @@ workflows:
go-test-flags: "--timeout 10m --short" go-test-flags: "--timeout 10m --short"
- mod-tidy-check - mod-tidy-check
- build-all - build-all
- build_macos: - build-macos
filters:
branches:
only: master

27
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,27 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Run '...'
2. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Version (run `lotus --version`):**
**Additional context**
Add any other context about the problem here.

1
.gitignore vendored
View File

@ -12,6 +12,7 @@
/lotuspond/front/build /lotuspond/front/build
/cmd/lotus-townhall/townhall/node_modules /cmd/lotus-townhall/townhall/node_modules
/cmd/lotus-townhall/townhall/build /cmd/lotus-townhall/townhall/build
extern/filecoin-ffi/rust/target
**/*.h **/*.h
**/*.a **/*.a
**/*.pc **/*.pc

View File

@ -4,10 +4,9 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/filecoin-project/lotus/build"
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/lotus/build"
) )
type Permission = string type Permission = string
@ -40,7 +39,7 @@ type Version struct {
// this api // this api
// //
// See APIVersion in build/version.go // See APIVersion in build/version.go
APIVersion uint32 APIVersion build.Version
// TODO: git commit / os / genesis cid? // TODO: git commit / os / genesis cid?
@ -49,6 +48,5 @@ type Version struct {
} }
func (v Version) String() string { func (v Version) String() string {
vM, vm, vp := build.VersionInts(v.APIVersion) return fmt.Sprintf("%s+api%s", v.Version, v.APIVersion.String())
return fmt.Sprintf("%s+api%d.%d.%d", v.Version, vM, vm, vp)
} }

View File

@ -8,8 +8,8 @@ import (
"github.com/ipfs/go-filestore" "github.com/ipfs/go-filestore"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
@ -35,15 +35,18 @@ type FullNode interface {
ChainSetHead(context.Context, *types.TipSet) error ChainSetHead(context.Context, *types.TipSet) error
ChainGetGenesis(context.Context) (*types.TipSet, error) ChainGetGenesis(context.Context) (*types.TipSet, error)
ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error) ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error)
ChainGetNode(ctx context.Context, p string) (interface{}, error)
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
// syncer // syncer
SyncState(context.Context) (*SyncState, error) SyncState(context.Context) (*SyncState, error)
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
// messages // messages
MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error) MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error)
MpoolPush(context.Context, *types.SignedMessage) error // TODO: remove MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push
MpoolGetNonce(context.Context, address.Address) (uint64, error) MpoolGetNonce(context.Context, address.Address) (uint64, error)
MpoolSub(context.Context) (<-chan MpoolUpdate, error) MpoolSub(context.Context) (<-chan MpoolUpdate, error)
@ -73,7 +76,7 @@ type FullNode interface {
// ClientImport imports file under the specified path into filestore // ClientImport imports file under the specified path into filestore
ClientImport(ctx context.Context, path string) (cid.Cid, error) ClientImport(ctx context.Context, path string) (cid.Cid, error)
ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, epochPrice types.BigInt, blocksDuration uint64) (*cid.Cid, error) ClientStartDeal(ctx context.Context, data cid.Cid, addr address.Address, miner address.Address, epochPrice types.BigInt, blocksDuration uint64) (*cid.Cid, error)
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error)
ClientListDeals(ctx context.Context) ([]DealInfo, error) ClientListDeals(ctx context.Context) ([]DealInfo, error)
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
@ -94,6 +97,7 @@ type FullNode interface {
StateReplay(context.Context, *types.TipSet, cid.Cid) (*ReplayResults, error) StateReplay(context.Context, *types.TipSet, cid.Cid) (*ReplayResults, error)
StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error)
StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error)
StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)

View File

@ -3,8 +3,8 @@ package api
import ( import (
"context" "context"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/go-sectorbuilder"
) )
// alias because cbor-gen doesn't like non-alias types // alias because cbor-gen doesn't like non-alias types

View File

@ -3,15 +3,15 @@ package apistruct
import ( import (
"context" "context"
"github.com/filecoin-project/lotus/lib/sectorbuilder" sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
@ -53,13 +53,16 @@ type FullNodeStruct struct {
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"` ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"` ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"` ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"`
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"` SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"` SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
SyncIncomingBlocks func(ctx context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` SyncIncomingBlocks func(ctx context.Context) (<-chan *types.BlockHeader, error) `perm:"read"`
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"` MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"` MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"` MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"` MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
@ -77,39 +80,40 @@ type FullNodeStruct struct {
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"` WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
ClientImport func(ctx context.Context, path string) (cid.Cid, error) `perm:"admin"` ClientImport func(ctx context.Context, path string) (cid.Cid, error) `perm:"admin"`
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"` ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, 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"` ClientFindData func(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"` ClientStartDeal func(ctx context.Context, data cid.Cid, addr address.Address, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"`
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"` ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, path string) error `perm:"admin"` ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, path string) error `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"` ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) `perm:"read"` StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) `perm:"read"` StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, *types.TipSet) (api.MinerPower, error) `perm:"read"` StateMinerPower func(context.Context, address.Address, *types.TipSet) (api.MinerPower, error) `perm:"read"`
StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"` StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"`
StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"` StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"`
StateMinerElectionPeriodStart func(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) `perm:"read"` StateMinerElectionPeriodStart func(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) `perm:"read"`
StateMinerSectorSize func(context.Context, address.Address, *types.TipSet) (uint64, error) `perm:"read"` StateMinerSectorSize func(context.Context, address.Address, *types.TipSet) (uint64, error) `perm:"read"`
StateCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` StateCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
StateReplay func(context.Context, *types.TipSet, cid.Cid) (*api.ReplayResults, error) `perm:"read"` StateReplay func(context.Context, *types.TipSet, cid.Cid) (*api.ReplayResults, error) `perm:"read"`
StateGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"` StateGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"`
StateReadState func(context.Context, *types.Actor, *types.TipSet) (*api.ActorState, error) `perm:"read"` StateReadState func(context.Context, *types.Actor, *types.TipSet) (*api.ActorState, error) `perm:"read"`
StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"` StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
StateWaitMsg func(context.Context, cid.Cid) (*api.MsgWait, error) `perm:"read"` StateWaitMsg func(context.Context, cid.Cid) (*api.MsgWait, error) `perm:"read"`
StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"` StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"`
StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"` StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"`
StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"` StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"`
StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"` StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"`
StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"` StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"`
StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"` StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"`
StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, error) `perm:"read"` StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, error) `perm:"read"`
StateListMessages func(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error) `perm:"read"`
MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"` MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"`
@ -208,8 +212,8 @@ func (c *FullNodeStruct) ClientFindData(ctx context.Context, root cid.Cid) ([]ap
return c.Internal.ClientFindData(ctx, root) return c.Internal.ClientFindData(ctx, root)
} }
func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) { func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, data cid.Cid, addr address.Address, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) {
return c.Internal.ClientStartDeal(ctx, data, miner, price, blocksDuration) return c.Internal.ClientStartDeal(ctx, data, addr, miner, price, blocksDuration)
} }
func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*api.DealInfo, error) { func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*api.DealInfo, error) {
return c.Internal.ClientGetDealInfo(ctx, deal) return c.Internal.ClientGetDealInfo(ctx, deal)
@ -231,7 +235,7 @@ func (c *FullNodeStruct) MpoolPending(ctx context.Context, ts *types.TipSet) ([]
return c.Internal.MpoolPending(ctx, ts) return c.Internal.MpoolPending(ctx, ts)
} }
func (c *FullNodeStruct) MpoolPush(ctx context.Context, smsg *types.SignedMessage) error { func (c *FullNodeStruct) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) {
return c.Internal.MpoolPush(ctx, smsg) return c.Internal.MpoolPush(ctx, smsg)
} }
@ -343,6 +347,14 @@ func (c *FullNodeStruct) ChainTipSetWeight(ctx context.Context, ts *types.TipSet
return c.Internal.ChainTipSetWeight(ctx, ts) return c.Internal.ChainTipSetWeight(ctx, ts)
} }
func (c *FullNodeStruct) ChainGetNode(ctx context.Context, p string) (interface{}, error) {
return c.Internal.ChainGetNode(ctx, p)
}
func (c *FullNodeStruct) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) {
return c.Internal.ChainGetMessage(ctx, mc)
}
func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) { func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) {
return c.Internal.SyncState(ctx) return c.Internal.SyncState(ctx)
} }
@ -355,6 +367,10 @@ func (c *FullNodeStruct) SyncIncomingBlocks(ctx context.Context) (<-chan *types.
return c.Internal.SyncIncomingBlocks(ctx) return c.Internal.SyncIncomingBlocks(ctx)
} }
func (c *FullNodeStruct) SyncMarkBad(ctx context.Context, bcid cid.Cid) error {
return c.Internal.SyncMarkBad(ctx, bcid)
}
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) { func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, ts) return c.Internal.StateMinerSectors(ctx, addr, ts)
} }
@ -442,6 +458,10 @@ func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, ts *t
return c.Internal.StateGetReceipt(ctx, msg, ts) return c.Internal.StateGetReceipt(ctx, msg, ts)
} }
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error) {
return c.Internal.StateListMessages(ctx, match, ts, toht)
}
func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error { func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error {
return c.Internal.MarketEnsureAvailable(ctx, addr, amt) return c.Internal.MarketEnsureAvailable(ctx, addr, amt)
} }

View File

@ -71,7 +71,11 @@ func TestDealFlow(t *testing.T, b APIBuilder) {
} }
} }
}() }()
deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(40000000), 100) addr, err := client.WalletDefaultAddress(ctx)
if err != nil {
t.Fatal(err)
}
deal, err := client.ClientStartDeal(ctx, fcid, addr, maddr, types.NewInt(40000000), 100)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -50,7 +50,7 @@ func (ts *testSuite) testVersion(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if v.Version != build.Version { if v.Version != build.BuildVersion {
t.Error("Version didn't work properly") t.Error("Version didn't work properly")
} }
} }

View File

@ -3,7 +3,7 @@ package api
import ( import (
"context" "context"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -1,3 +1,4 @@
package build package build
const ForkCCM = 1750 const ForkCCM = 1750
const ForkNoPowerEPSUpdates = 16450

View File

@ -1,6 +1,12 @@
package build package build
import rice "github.com/GeertJohan/go.rice" import (
rice "github.com/GeertJohan/go.rice"
logging "github.com/ipfs/go-log"
)
// moved from now-defunct build/paramfetch.go
var log = logging.Logger("build")
func MaybeGenesis() []byte { func MaybeGenesis() []byte {
builtinGen, err := rice.FindBox("genesis") builtinGen, err := rice.FindBox("genesis")

View File

@ -1,189 +0,0 @@
package build
import (
"encoding/hex"
"encoding/json"
"io"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
rice "github.com/GeertJohan/go.rice"
logging "github.com/ipfs/go-log"
"github.com/minio/blake2b-simd"
"go.uber.org/multierr"
"golang.org/x/xerrors"
pb "gopkg.in/cheggaaa/pb.v1"
)
var log = logging.Logger("build")
//const gateway = "http://198.211.99.118/ipfs/"
const gateway = "https://ipfs.io/ipfs/"
const paramdir = "/var/tmp/filecoin-proof-parameters"
const dirEnv = "FIL_PROOFS_PARAMETER_CACHE"
type paramFile struct {
Cid string `json:"cid"`
Digest string `json:"digest"`
SectorSize uint64 `json:"sector_size"`
}
type fetch struct {
wg sync.WaitGroup
fetchLk sync.Mutex
errs []error
}
func getParamDir() string {
if os.Getenv(dirEnv) == "" {
return paramdir
}
return os.Getenv(dirEnv)
}
func GetParams(storageSize uint64) error {
if err := os.Mkdir(getParamDir(), 0755); err != nil && !os.IsExist(err) {
return err
}
var params map[string]paramFile
paramBytes := rice.MustFindBox("proof-params").MustBytes("parameters.json")
if err := json.Unmarshal(paramBytes, &params); err != nil {
return err
}
ft := &fetch{}
for name, info := range params {
if storageSize != info.SectorSize && strings.HasSuffix(name, ".params") {
continue
}
ft.maybeFetchAsync(name, info)
}
return ft.wait()
}
func (ft *fetch) maybeFetchAsync(name string, info paramFile) {
ft.wg.Add(1)
go func() {
defer ft.wg.Done()
path := filepath.Join(getParamDir(), name)
err := ft.checkFile(path, info)
if !os.IsNotExist(err) && err != nil {
log.Warn(err)
}
if err == nil {
return
}
ft.fetchLk.Lock()
defer ft.fetchLk.Unlock()
if err := doFetch(path, info); err != nil {
ft.errs = append(ft.errs, xerrors.Errorf("fetching file %s failed: %w", path, err))
return
}
err = ft.checkFile(path, info)
if err != nil {
ft.errs = append(ft.errs, xerrors.Errorf("checking file %s failed: %w", path, err))
err := os.Remove(path)
if err != nil {
ft.errs = append(ft.errs, xerrors.Errorf("remove file %s failed: %w", path, err))
}
}
}()
}
func (ft *fetch) checkFile(path string, info paramFile) error {
if os.Getenv("TRUST_PARAMS") == "1" {
log.Warn("Assuming parameter files are ok. DO NOT USE IN PRODUCTION")
return nil
}
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
h := blake2b.New512()
if _, err := io.Copy(h, f); err != nil {
return err
}
sum := h.Sum(nil)
strSum := hex.EncodeToString(sum[:16])
if strSum == info.Digest {
log.Infof("Parameter file %s is ok", path)
return nil
}
return xerrors.Errorf("checksum mismatch in param file %s, %s != %s", path, strSum, info.Digest)
}
func (ft *fetch) wait() error {
ft.wg.Wait()
return multierr.Combine(ft.errs...)
}
func doFetch(out string, info paramFile) error {
gw := os.Getenv("IPFS_GATEWAY")
if gw == "" {
gw = gateway
}
log.Infof("Fetching %s from %s", out, gw)
outf, err := os.OpenFile(out, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
return err
}
defer outf.Close()
fStat, err := outf.Stat()
if err != nil {
return err
}
header := http.Header{}
header.Set("Range", "bytes="+strconv.FormatInt(fStat.Size(), 10)+"-")
url, err := url.Parse(gw + info.Cid)
if err != nil {
return err
}
log.Infof("GET %s", url)
req := http.Request{
Method: "GET",
URL: url,
Header: header,
Close: true,
}
resp, err := http.DefaultClient.Do(&req)
if err != nil {
return err
}
defer resp.Body.Close()
bar := pb.New64(resp.ContentLength)
bar.Units = pb.U_BYTES
bar.ShowSpeed = true
bar.Start()
_, err = io.Copy(outf, bar.NewProxyReader(resp.Body))
bar.Finish()
return err
}

View File

@ -31,7 +31,7 @@ const PaymentChannelClosingDelay = 6 * 60 * 60 / BlockDelay // six hours
// Consensus / Network // Consensus / Network
// Seconds // Seconds
const AllowableClockDrift = BlockDelay * 2 const AllowableClockDrift = 1
// Epochs // Epochs
const ForkLengthThreshold = Finality const ForkLengthThreshold = Finality
@ -56,11 +56,6 @@ const SealRandomnessLookback = Finality
// Epochs // Epochs
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
// 1 / n
const SectorChallengeRatioDiv = 25
const MaxFallbackPostChallengeCount = 10
// ///// // /////
// Mining // Mining

View File

@ -1,20 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
function b64() {
f="$1"
case `uname` in
Darwin)
base64 -i "$f"
;;
Linux)
base64 "$f" -w 0
;;
esac
printf "unsupported system" 1>&2
exit 1
}
sed "s/{{PARAMSJSON}}/$(b64 build/proof-params/parameters.json)/g" build/proof-params/paramfetch.sh.template > ./build/paramfetch.sh
chmod +x ./build/paramfetch.sh

View File

@ -1,103 +0,0 @@
{
"v20-proof-of-spacetime-election-5f585aca354eb68e411c8582ed0efd800792430e4e76d73468c4fc03f1a8d6d2.params": {
"cid": "QmX7tYeNPWae2fjZ3Am6GB9dmHvLqvoz8dKo3PR98VYxH9",
"digest": "39a9edec3355516674f0d12b926be493",
"sector_size": 34359738368
},
"v20-proof-of-spacetime-election-5f585aca354eb68e411c8582ed0efd800792430e4e76d73468c4fc03f1a8d6d2.vk": {
"cid": "QmbNGx7pNbGiEr8ykoHxVXHW2LNSmGdsxKtj1onZCyguCX",
"digest": "0227ae7df4f2affe529ebafbbc7540ee",
"sector_size": 34359738368
},
"v20-proof-of-spacetime-election-a4e18190d4b4657ba1b4d08a341871b2a6f398e327cb9951b28ab141fbdbf49d.params": {
"cid": "QmRGZsNp4mp1cZshcXqt3VMuWscAEsiMa2iepF4CsWWoiv",
"digest": "991041a354b12c280542741f58c7f2ca",
"sector_size": 1024
},
"v20-proof-of-spacetime-election-a4e18190d4b4657ba1b4d08a341871b2a6f398e327cb9951b28ab141fbdbf49d.vk": {
"cid": "QmWpmrhCGVcfqLyqp5oGAnhPmCE5hGTPaauHi25mpQwRSU",
"digest": "91fac550e1f9bccab213830bb0c85bd6",
"sector_size": 1024
},
"v20-proof-of-spacetime-election-a9eb6d90b896a282ec2d3a875c6143e3fcff778f0da1460709e051833651559b.params": {
"cid": "QmenSZXh1EsSyHiSRvA6wb8yaPhYBTjrKehJw96Px5HnN4",
"digest": "6322eacd2773163ddd51f9ca7d645fc4",
"sector_size": 1073741824
},
"v20-proof-of-spacetime-election-a9eb6d90b896a282ec2d3a875c6143e3fcff778f0da1460709e051833651559b.vk": {
"cid": "QmPvZoMKofw6eDhDg5ESJA2QAZP8HvM6qMQk7fw4pq9bQf",
"digest": "0df62745fceac922e3e70847cfc70b52",
"sector_size": 1073741824
},
"v20-proof-of-spacetime-election-bf872523641b1de33553db2a177df13e412d7b3b0103e6696ae0a1cf5d525259.params": {
"cid": "QmVibFqzkZoL8cwQmzj8njPokCQGCCx4pBcUH77bzgJgV9",
"digest": "de9d71e672f286706a1673bd57abdaac",
"sector_size": 16777216
},
"v20-proof-of-spacetime-election-bf872523641b1de33553db2a177df13e412d7b3b0103e6696ae0a1cf5d525259.vk": {
"cid": "QmZa5FX27XyiEXQQLQpHqtMJKLzrcY8wMuj3pxzmSimSyu",
"digest": "7f796d3a0f13499181e44b5eee0cc744",
"sector_size": 16777216
},
"v20-proof-of-spacetime-election-ffc3fb192364238b60977839d14e3154d4a98313e30d46694a12af54b6874975.params": {
"cid": "Qmbt2SWWAmMcYoY3DAiRDXA8fAuqdqRLWucJMSxYmzBCmN",
"digest": "151ae0ae183fc141e8c2bebc28e5cc10",
"sector_size": 268435456
},
"v20-proof-of-spacetime-election-ffc3fb192364238b60977839d14e3154d4a98313e30d46694a12af54b6874975.vk": {
"cid": "QmUxvPu4xdVmjMFihUKoYyEdXBqxsXkvmxRweU7KouWHji",
"digest": "95eb89588e9d1832aca044c3a13178af",
"sector_size": 268435456
},
"v20-stacked-proof-of-replication-117839dacd1ef31e5968a6fd13bcd6fa86638d85c40c9241a1d07c2a954eb89b.params": {
"cid": "QmQZe8eLo2xXbhSDxtyYZNqEjqjdcWGdADywECRvNEZQdX",
"digest": "fcd50e2e08a8560a6bb3418e883567ed",
"sector_size": 268435456
},
"v20-stacked-proof-of-replication-117839dacd1ef31e5968a6fd13bcd6fa86638d85c40c9241a1d07c2a954eb89b.vk": {
"cid": "Qme1hn6QT1covfoUFGDZkqoE1pMTax9FNW3nWWmTNqFe7y",
"digest": "872e244d86499fd659082e3bcf3f13e7",
"sector_size": 268435456
},
"v20-stacked-proof-of-replication-b46f3a1051afbb67f70aae7082da95def62eee943662f3e1bf69837fb08aaae4.params": {
"cid": "QmSfrPDC9jwY4MKrjzhCqDBBAG44wSDM8oE5NuDwWSh2xN",
"digest": "0a338b941c5f17946340de5fc95cab30",
"sector_size": 34359738368
},
"v20-stacked-proof-of-replication-b46f3a1051afbb67f70aae7082da95def62eee943662f3e1bf69837fb08aaae4.vk": {
"cid": "QmTDGynCmnbaZNBP3Bv3F3duC3ecKRubCKeMUiQQZYbGpF",
"digest": "c752e070a6b7aa8b79aa661a6b600b55",
"sector_size": 34359738368
},
"v20-stacked-proof-of-replication-e71093863cadc71de61f38311ee45816633973bbf34849316b147f8d2e66f199.params": {
"cid": "QmXjSSnMUnc7EjQBYtTHhvLU3kXJTbUyhVhJRSTRehh186",
"digest": "efa407fd09202dffd15799a8518e73d3",
"sector_size": 1024
},
"v20-stacked-proof-of-replication-e71093863cadc71de61f38311ee45816633973bbf34849316b147f8d2e66f199.vk": {
"cid": "QmYHW3zhQouDP4okFbXSsRMcZ8bokKGvzxqbv7ZrunPMiG",
"digest": "b2f09a0ccb62da28c890d5b881c8dcd2",
"sector_size": 1024
},
"v20-stacked-proof-of-replication-e99a585174b6a45b254ba4780d72c89ad808c305c6d11711009ade4f39dba8e9.params": {
"cid": "QmUhyfNeLb32LfSkjsUwTFYLXQGMj6JQ8daff4DdVMt79q",
"digest": "b53c1916a63839ec345aa2224e9198b7",
"sector_size": 1073741824
},
"v20-stacked-proof-of-replication-e99a585174b6a45b254ba4780d72c89ad808c305c6d11711009ade4f39dba8e9.vk": {
"cid": "QmWReGfbuoozNErbskmFvqV4q36BY6F2WWb4cVFc3zoYkA",
"digest": "20d58a3fae7343481f8298a2dd493dd7",
"sector_size": 1073741824
},
"v20-stacked-proof-of-replication-f571ee2386f4c65a68e802747f2d78691006fc81a67971c4d9641403fffece16.params": {
"cid": "QmSAHu14Pe8iav6BYCt9XkpHJ73XM7tcpY4d9JK9BST9HU",
"digest": "7698426202c7e07b26ef056d31485b3a",
"sector_size": 16777216
},
"v20-stacked-proof-of-replication-f571ee2386f4c65a68e802747f2d78691006fc81a67971c4d9641403fffece16.vk": {
"cid": "QmaKtFLShnhMGVn7P9UsHjkgqtqRFSwCStqqykBN7u8dax",
"digest": "834408e5c3fce6ec5d1bf64e64cee94e",
"sector_size": 16777216
}
}

View File

@ -1,95 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
PARAMS='{{PARAMSJSON}}'
die() {
echo "$@" >&2
exit 1
}
have_binary() {
type "$1" > /dev/null 2> /dev/null
}
check_writable() {
printf "" > "$1" && rm "$1"
}
try_download() {
url="$1"
output="$2"
command="$3"
util_name="$(set -- $command; echo "$1")"
if ! have_binary "$util_name"; then
return 1
fi
printf '==> Using %s to download "%s" to "%s"\n' "$util_name" "$url" "$output"
if eval "$command"; then
echo "==> Download complete!"
return
else
echo "error: couldn't download with $util_name ($?)"
return 1
fi
}
download() {
dl_url="$1"
dl_output="$2"
test "$#" -eq "2" || die "download requires exactly two arguments, was given $@"
if ! check_writable "$dl_output"; then
die "download error: cannot write to $dl_output"
fi
try_download "$dl_url" "$dl_output" "wget '$dl_url' -O '$dl_output'" && return
try_download "$dl_url" "$dl_output" "curl --silent --fail --output '$dl_output' '$dl_url'" && return
try_download "$dl_url" "$dl_output" "fetch '$dl_url' -o '$dl_output'" && return
try_download "$dl_url" "$dl_output" "http '$dl_url' > '$dl_output'" && return
try_download "$dl_url" "$dl_output" "ftp -o '$dl_output' '$dl_url'" && return
die "Unable to download $dl_url. exiting."
}
fetch_ipget() {
local dest="$1"
local cid="$2"
IPGET_PARAMS="--node=spawn -p=/ip4/138.201.67.219/tcp/4002/ws/ipfs/QmUd6zHcbkbcs7SMxwLs48qZVX3vpcM8errYS7xEczwRMA -p=/ip4/138.201.67.218/tcp/4002/ws/ipfs/QmbVWZQhCGrS7DhgLqWbgvdmKN7JueKCREVanfnVpgyq8x -p=/ip4/94.130.135.167/tcp/4002/ws/ipfs/QmUEMvxS2e7iDrereVYc5SWPauXPyNwxcy9BXZrC1QTcHE -p=/ip4/138.201.68.74/tcp/4001/ipfs/QmdnXwLrC8p1ueiq2Qya8joNvk3TVVDAut7PrikmZwubtR -p=/ip4/138.201.67.220/tcp/4001/ipfs/QmNSYxZAiJHeLdkBg38roksAR9So7Y5eojks1yjEcUtZ7i"
./bin/ipget $IPGET_PARAMS -o "$dest" "$cid"
}
fetch_gateway() {
local dest="$1"
local cid="$2"
local url="http://198.211.99.118/ipfs/$cid"
download "$url" "$dest"
}
OUT_DIR="/var/tmp/filecoin-proof-parameters"
mkdir -p $OUT_DIR
printf $PARAMS | base64 -d | jq '. | to_entries | map("'$OUT_DIR'/\(.key) \(.value.cid) \(.value.digest)") | .[]' --raw-output | \
while read -r dest cid digest; do
if [[ -f "$dest" ]]; then
b2=$(b2sum "$dest" | head -c 32)
if [[ "$digest" == "$b2" ]]; then
echo "$dest exists and has correct hash"
continue
else
echo "$dest has incorrect hash"
rm -f "$dest"
fi
fi
echo "downloading $dest"
fetch_gateway "$dest" "$cid"
done

View File

@ -1,34 +1,44 @@
package build package build
import "fmt"
var CurrentCommit string var CurrentCommit string
// Version is the local build version, set by build system // BuildVersion is the local build version, set by build system
const Version = "0.1.1" const BuildVersion = "0.1.5"
var UserVersion = Version + CurrentCommit var UserVersion = BuildVersion + CurrentCommit
// APIVersion is a hex semver version of the rpc api exposed type Version uint32
//
// M M P func newVer(major, minor, patch uint8) Version {
// A I A return Version(uint32(major)<<16 | uint32(minor)<<8 | uint32(patch))
// J N T }
// O O C
// R R H // Ints returns (major, minor, patch) versions
// |\vv/| func (ve Version) Ints() (uint32, uint32, uint32) {
// vv vv v := uint32(ve)
const APIVersion = 0x000101 return (v & majorOnlyMask) >> 16, (v & minorOnlyMask) >> 8, v & patchOnlyMask
}
func (ve Version) String() string {
vmj, vmi, vp := ve.Ints()
return fmt.Sprintf("%d.%d.%d", vmj, vmi, vp)
}
func (ve Version) EqMajorMinor(v2 Version) bool {
return ve&minorMask == v2&minorMask
}
// APIVersion is a semver version of the rpc api exposed
var APIVersion Version = newVer(0, 1, 6)
const ( const (
MajorMask = 0xff0000 majorMask = 0xff0000
MinorMask = 0xffff00 minorMask = 0xffff00
PatchMask = 0xffffff patchMask = 0xffffff
MajorOnlyMask = 0xff0000 majorOnlyMask = 0xff0000
MinorOnlyMask = 0x00ff00 minorOnlyMask = 0x00ff00
PatchOnlyMask = 0x0000ff patchOnlyMask = 0x0000ff
) )
// VersionInts returns (major, minor, patch) versions
func VersionInts(version uint32) (uint32, uint32, uint32) {
return (version & MajorOnlyMask) >> 16, (version & MinorOnlyMask) >> 8, version & PatchOnlyMask
}

View File

@ -1,8 +1,8 @@
package actors package actors
import ( import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -6,8 +6,8 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"

View File

@ -8,11 +8,11 @@ import (
ffi "github.com/filecoin-project/filecoin-ffi" ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
"github.com/filecoin-project/go-amt-ipld" "github.com/filecoin-project/go-amt-ipld"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
@ -140,7 +140,10 @@ func (sma StorageMinerActor) Exports() []interface{} {
return []interface{}{ return []interface{}{
1: sma.StorageMinerConstructor, 1: sma.StorageMinerConstructor,
2: sma.PreCommitSector, 2: sma.PreCommitSector,
3: sma.ProveCommitSector, 3: withUpdates(
update{start: 0, method: sma.ProveCommitSectorV0},
update{start: build.ForkNoPowerEPSUpdates, method: sma.ProveCommitSectorV1},
),
4: sma.SubmitFallbackPoSt, 4: sma.SubmitFallbackPoSt,
//5: sma.SlashStorageFault, //5: sma.SlashStorageFault,
//6: sma.GetCurrentProvingSet, //6: sma.GetCurrentProvingSet,
@ -155,7 +158,10 @@ func (sma StorageMinerActor) Exports() []interface{} {
//15: sma.ChangeWorker, //15: sma.ChangeWorker,
16: sma.IsSlashed, 16: sma.IsSlashed,
17: sma.CheckMiner, 17: sma.CheckMiner,
18: sma.DeclareFaults, 18: withUpdates(
update{start: 0, method: sma.DeclareFaultsV0},
update{start: build.ForkNoPowerEPSUpdates, method: sma.DeclareFaultsV1},
),
19: sma.SlashConsensusFault, 19: sma.SlashConsensusFault,
20: sma.SubmitElectionPoSt, 20: sma.SubmitElectionPoSt,
} }
@ -238,7 +244,7 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon
} }
if vmctx.Message().From != mi.Worker { if vmctx.Message().From != mi.Worker {
return nil, aerrors.New(1, "not authorized to commit sector for miner") return nil, aerrors.New(1, "not authorized to precommit sector for miner")
} }
// make sure the miner isnt trying to submit a pre-existing sector // make sure the miner isnt trying to submit a pre-existing sector
@ -291,7 +297,7 @@ type SectorProveCommitInfo struct {
DealIDs []uint64 DealIDs []uint64
} }
func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorProveCommitInfo) ([]byte, ActorError) { func (sma StorageMinerActor) ProveCommitSectorV0(act *types.Actor, vmctx types.VMContext, params *SectorProveCommitInfo) ([]byte, ActorError) {
ctx := vmctx.Context() ctx := vmctx.Context()
oldstate, self, err := loadState(vmctx) oldstate, self, err := loadState(vmctx)
if err != nil { if err != nil {
@ -391,7 +397,114 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
} }
_, err = vmctx.Send(StorageMarketAddress, SMAMethods.ActivateStorageDeals, types.NewInt(0), activateParams) _, err = vmctx.Send(StorageMarketAddress, SMAMethods.ActivateStorageDeals, types.NewInt(0), activateParams)
return nil, err return nil, aerrors.Wrapf(err, "calling ActivateStorageDeals failed")
}
func (sma StorageMinerActor) ProveCommitSectorV1(act *types.Actor, vmctx types.VMContext, params *SectorProveCommitInfo) ([]byte, ActorError) {
ctx := vmctx.Context()
oldstate, self, err := loadState(vmctx)
if err != nil {
return nil, err
}
mi, err := loadMinerInfo(vmctx, self)
if err != nil {
return nil, err
}
if vmctx.Message().From != mi.Worker {
return nil, aerrors.New(1, "not authorized to submit sector proof for miner")
}
us, ok := self.PreCommittedSectors[uintToStringKey(params.SectorID)]
if !ok {
return nil, aerrors.New(1, "no pre-commitment found for sector")
}
if us.ReceivedEpoch+build.InteractivePoRepDelay >= vmctx.BlockHeight() {
return nil, aerrors.New(2, "too early for proof submission")
}
delete(self.PreCommittedSectors, uintToStringKey(params.SectorID))
// TODO: ensure normalization to ID address
maddr := vmctx.Message().To
ticket, err := vmctx.GetRandomness(us.Info.SealEpoch - build.SealRandomnessLookback)
if err != nil {
return nil, aerrors.Wrap(err, "failed to get ticket randomness")
}
seed, err := vmctx.GetRandomness(us.ReceivedEpoch + build.InteractivePoRepDelay)
if err != nil {
return nil, aerrors.Wrap(err, "failed to get randomness for prove sector commitment")
}
enc, err := SerializeParams(&ComputeDataCommitmentParams{
DealIDs: params.DealIDs,
SectorSize: mi.SectorSize,
})
if err != nil {
return nil, aerrors.Wrap(err, "failed to serialize ComputeDataCommitmentParams")
}
commD, err := vmctx.Send(StorageMarketAddress, SMAMethods.ComputeDataCommitment, types.NewInt(0), enc)
if err != nil {
return nil, aerrors.Wrapf(err, "failed to compute data commitment (sector %d, deals: %v)", params.SectorID, params.DealIDs)
}
if ok, err := vmctx.Sys().ValidatePoRep(ctx, maddr, mi.SectorSize, commD, us.Info.CommR, ticket, params.Proof, seed, params.SectorID); err != nil {
return nil, err
} else if !ok {
return nil, aerrors.Newf(2, "porep proof was invalid (t:%x; s:%x(%d); p:%s)", ticket, seed, us.ReceivedEpoch+build.InteractivePoRepDelay, truncateHexPrint(params.Proof))
}
// Note: There must exist a unique index in the miner's sector set for each
// sector ID. The `faults`, `recovered`, and `done` parameters of the
// SubmitPoSt method express indices into this sector set.
nssroot, err := AddToSectorSet(ctx, types.WrapStorage(vmctx.Storage()), self.Sectors, params.SectorID, us.Info.CommR, commD)
if err != nil {
return nil, err
}
self.Sectors = nssroot
// if miner is not mining, start their proving period now
// Note: As written here, every miners first PoSt will only be over one sector.
// We could set up a 'grace period' for starting mining that would allow miners
// to submit several sectors for their first proving period. Alternatively, we
// could simply make the 'PreCommitSector' call take multiple sectors at a time.
//
// Note: Proving period is a function of sector size; small sectors take less
// time to prove than large sectors do. Sector size is selected when pledging.
pss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
if lerr != nil {
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
}
if pss.Count == 0 && !self.Active {
self.ProvingSet = self.Sectors
// TODO: probably want to wait until the miner is above a certain
// threshold before starting this
self.ElectionPeriodStart = vmctx.BlockHeight()
}
nstate, err := vmctx.Storage().Put(self)
if err != nil {
return nil, err
}
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
return nil, err
}
activateParams, err := SerializeParams(&ActivateStorageDealsParams{
Deals: params.DealIDs,
})
if err != nil {
return nil, err
}
_, err = vmctx.Send(StorageMarketAddress, SMAMethods.ActivateStorageDeals, types.NewInt(0), activateParams)
return nil, aerrors.Wrapf(err, "calling ActivateStorageDeals failed")
} }
func truncateHexPrint(b []byte) string { func truncateHexPrint(b []byte) string {
@ -508,7 +621,7 @@ func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VM
} }
if ok, lerr := sectorbuilder.VerifyFallbackPost(vmctx.Context(), mi.SectorSize, if ok, lerr := sectorbuilder.VerifyFallbackPost(vmctx.Context(), mi.SectorSize,
sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), seed[:], params.Proof, candidates, proverID); !ok || lerr != nil { sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), seed[:], params.Proof, candidates, proverID, 0); !ok || lerr != nil { // TODO: FORK - set faults to len(faults)
if lerr != nil { if lerr != nil {
// TODO: study PoST errors // TODO: study PoST errors
return nil, aerrors.Absorb(lerr, 4, "PoST error") return nil, aerrors.Absorb(lerr, 4, "PoST error")
@ -608,8 +721,10 @@ func RemoveFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, ids [
return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node") return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node")
} }
if err := ssr.BatchDelete(ids); err != nil { for _, id := range ids {
return cid.Undef, aerrors.HandleExternalError(err, "failed to delete from sector set") if err := ssr.Delete(id); err != nil {
log.Warnf("failed to delete sector %d from set: %s", id, err)
}
} }
ncid, err := ssr.Flush() ncid, err := ssr.Flush()
@ -808,7 +923,7 @@ type DeclareFaultsParams struct {
Faults types.BitField Faults types.BitField
} }
func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) { func (sma StorageMinerActor) DeclareFaultsV0(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) {
oldstate, self, aerr := loadState(vmctx) oldstate, self, aerr := loadState(vmctx)
if aerr != nil { if aerr != nil {
return nil, aerr return nil, aerr
@ -824,7 +939,42 @@ func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMConte
self.LastFaultSubmission = vmctx.BlockHeight() self.LastFaultSubmission = vmctx.BlockHeight()
nstate, aerr := vmctx.Storage().Put(self) nstate, aerr := vmctx.Storage().Put(self)
if err != nil { // TODO: FORK: should be aerr
return nil, aerr
}
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
return nil, err
}
return nil, nil
}
func (sma StorageMinerActor) DeclareFaultsV1(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) {
oldstate, self, aerr := loadState(vmctx)
if aerr != nil {
return nil, aerr
}
mi, aerr := loadMinerInfo(vmctx, self)
if aerr != nil {
return nil, aerr
}
if vmctx.Message().From != mi.Worker {
return nil, aerrors.New(1, "not authorized to declare faults for miner")
}
nfaults, err := types.MergeBitFields(params.Faults, self.FaultSet)
if err != nil { if err != nil {
return nil, aerrors.Absorb(err, 1, "failed to merge bitfields")
}
self.FaultSet = nfaults
self.LastFaultSubmission = vmctx.BlockHeight()
nstate, aerr := vmctx.Storage().Put(self)
if aerr != nil {
return nil, aerr return nil, aerr
} }
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
@ -910,6 +1060,81 @@ func (sma StorageMinerActor) SubmitElectionPoSt(act *types.Actor, vmctx types.VM
} }
func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerrors.ActorError { func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerrors.ActorError {
if vmctx.BlockHeight() >= build.ForkNoPowerEPSUpdates {
return onSuccessfulPoStV1(self, vmctx)
}
return onSuccessfulPoStV0(self, vmctx)
}
func onSuccessfulPoStV0(self *StorageMinerActorState, vmctx types.VMContext) aerrors.ActorError {
var mi MinerInfo
if err := vmctx.Storage().Get(self.Info, &mi); err != nil {
return err
}
pss, nerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
if nerr != nil {
return aerrors.HandleExternalError(nerr, "failed to load proving set")
}
faults, nerr := self.FaultSet.All()
if nerr != nil {
return aerrors.Absorb(nerr, 1, "invalid bitfield (fatal?)")
}
self.FaultSet = types.NewBitField()
oldPower := self.Power
newPower := types.BigMul(types.NewInt(pss.Count-uint64(len(faults))), types.NewInt(mi.SectorSize))
// If below the minimum size requirement, miners have zero power
if newPower.LessThan(types.NewInt(build.MinimumMinerPower)) {
newPower = types.NewInt(0)
}
self.Power = newPower
delta := types.BigSub(self.Power, oldPower)
if self.SlashedAt != 0 {
self.SlashedAt = 0
delta = self.Power
}
prevSlashingDeadline := self.ElectionPeriodStart + build.SlashablePowerDelay
if !self.Active && newPower.GreaterThan(types.NewInt(0)) {
self.Active = true
prevSlashingDeadline = 0
}
if !(oldPower.IsZero() && newPower.IsZero()) {
enc, err := SerializeParams(&UpdateStorageParams{
Delta: delta,
NextSlashDeadline: vmctx.BlockHeight() + build.SlashablePowerDelay,
PreviousSlashDeadline: prevSlashingDeadline,
})
if err != nil {
return err
}
_, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc)
if err != nil {
return aerrors.Wrap(err, "updating storage failed")
}
}
ncid, err := RemoveFromSectorSet(vmctx.Context(), vmctx.Storage(), self.Sectors, faults)
if err != nil {
return err
}
self.Sectors = ncid
self.ProvingSet = ncid
self.ElectionPeriodStart = vmctx.BlockHeight()
return nil
}
func onSuccessfulPoStV1(self *StorageMinerActorState, vmctx types.VMContext) aerrors.ActorError {
// TODO: some sector upkeep stuff that is very haphazard and unclear in the spec // TODO: some sector upkeep stuff that is very haphazard and unclear in the spec
var mi MinerInfo var mi MinerInfo
@ -953,9 +1178,9 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro
if !(oldPower.IsZero() && newPower.IsZero()) { if !(oldPower.IsZero() && newPower.IsZero()) {
enc, err := SerializeParams(&UpdateStorageParams{ enc, err := SerializeParams(&UpdateStorageParams{
Delta: delta, Delta: delta,
NextProvingPeriodEnd: vmctx.BlockHeight() + build.SlashablePowerDelay, NextSlashDeadline: vmctx.BlockHeight() + build.SlashablePowerDelay,
PreviousProvingPeriodEnd: prevSlashingDeadline, PreviousSlashDeadline: prevSlashingDeadline,
}) })
if err != nil { if err != nil {
return err return err
@ -963,8 +1188,10 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro
_, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc) _, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc)
if err != nil { if err != nil {
return err return aerrors.Wrap(err, "updating storage failed")
} }
self.ElectionPeriodStart = vmctx.BlockHeight()
} }
ncid, err := RemoveFromSectorSet(vmctx.Context(), vmctx.Storage(), self.Sectors, faults) ncid, err := RemoveFromSectorSet(vmctx.Context(), vmctx.Storage(), self.Sectors, faults)
@ -974,7 +1201,6 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro
self.Sectors = ncid self.Sectors = ncid
self.ProvingSet = ncid self.ProvingSet = ncid
self.ElectionPeriodStart = vmctx.BlockHeight()
return nil return nil
} }

View File

@ -6,13 +6,13 @@ import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
blockstore "github.com/ipfs/go-ipfs-blockstore" blockstore "github.com/ipfs/go-ipfs-blockstore"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
@ -52,6 +52,71 @@ func TestMinerCommitSectors(t *testing.T) {
assertSectorIDs(h, t, minerAddr, []uint64{1}) assertSectorIDs(h, t, minerAddr, []uint64{1})
} }
func TestMinerSubmitBadFault(t *testing.T) {
var worker, client address.Address
var minerAddr address.Address
opts := []HarnessOpt{
HarnessAddr(&worker, 1000000),
HarnessAddr(&client, 1000000),
HarnessActor(&minerAddr, &worker, actors.StorageMinerCodeCid,
func() cbg.CBORMarshaler {
return &actors.StorageMinerConstructorParams{
Owner: worker,
Worker: worker,
SectorSize: 1024,
PeerID: "fakepeerid",
}
}),
}
h := NewHarness(t, opts...)
h.vm.Syscalls.ValidatePoRep = func(ctx context.Context, maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, aerrors.ActorError) {
// all proofs are valid
return true, nil
}
ret, _ := h.SendFunds(t, worker, minerAddr, types.NewInt(100000))
ApplyOK(t, ret)
ret, _ = h.InvokeWithValue(t, client, actors.StorageMarketAddress, actors.SMAMethods.AddBalance, types.NewInt(2000), nil)
ApplyOK(t, ret)
addSectorToMiner(h, t, minerAddr, worker, client, 1)
assertSectorIDs(h, t, minerAddr, []uint64{1})
bf := types.NewBitField()
bf.Set(6)
ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf})
ApplyOK(t, ret)
ret, _ = h.Invoke(t, actors.NetworkAddress, minerAddr, actors.MAMethods.SubmitElectionPoSt, nil)
ApplyOK(t, ret)
assertSectorIDs(h, t, minerAddr, []uint64{1})
badnum := uint64(0)
badnum--
bf = types.NewBitField()
bf.Set(badnum)
ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf})
ApplyOK(t, ret)
ret, _ = h.Invoke(t, actors.NetworkAddress, minerAddr, actors.MAMethods.SubmitElectionPoSt, nil)
ApplyOK(t, ret)
bf = types.NewBitField()
bf.Set(1)
ret, _ = h.Invoke(t, worker, minerAddr, actors.MAMethods.DeclareFaults, &actors.DeclareFaultsParams{bf})
ApplyOK(t, ret)
ret, _ = h.Invoke(t, actors.NetworkAddress, minerAddr, actors.MAMethods.SubmitElectionPoSt, nil)
ApplyOK(t, ret)
assertSectorIDs(h, t, minerAddr, []uint64{})
}
func addSectorToMiner(h *Harness, t *testing.T, minerAddr, worker, client address.Address, sid uint64) { func addSectorToMiner(h *Harness, t *testing.T, minerAddr, worker, client address.Address, sid uint64) {
t.Helper() t.Helper()
s := sectorbuilder.UserBytesForSectorSize(1024) s := sectorbuilder.UserBytesForSectorSize(1024)

View File

@ -3,8 +3,8 @@ package actors
import ( import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"

View File

@ -7,8 +7,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
) )

View File

@ -7,9 +7,9 @@ import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -4,8 +4,8 @@ import (
"context" "context"
"testing" "testing"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
) )

View File

@ -5,18 +5,19 @@ import (
"context" "context"
"sort" "sort"
"go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-amt-ipld" "github.com/filecoin-project/go-amt-ipld"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-hamt-ipld" "github.com/ipfs/go-hamt-ipld"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
) )
type StorageMarketActor struct{} type StorageMarketActor struct{}
@ -254,6 +255,9 @@ func setMarketBalances(vmctx types.VMContext, nd *hamt.Node, set map[address.Add
} }
func GetMarketBalances(ctx context.Context, store *hamt.CborIpldStore, rcid cid.Cid, addrs ...address.Address) ([]StorageParticipantBalance, *hamt.Node, ActorError) { func GetMarketBalances(ctx context.Context, store *hamt.CborIpldStore, rcid cid.Cid, addrs ...address.Address) ([]StorageParticipantBalance, *hamt.Node, ActorError) {
ctx, span := trace.StartSpan(ctx, "GetMarketBalances")
defer span.End()
nd, err := hamt.LoadNode(ctx, store, rcid) nd, err := hamt.LoadNode(ctx, store, rcid)
if err != nil { if err != nil {
return nil, nil, aerrors.HandleExternalError(err, "failed to load miner set") return nil, nil, aerrors.HandleExternalError(err, "failed to load miner set")
@ -381,6 +385,9 @@ func (sma StorageMarketActor) PublishStorageDeals(act *types.Actor, vmctx types.
} }
func (st *StorageMarketState) validateDeal(vmctx types.VMContext, deal StorageDealProposal, providerWorker address.Address) aerrors.ActorError { func (st *StorageMarketState) validateDeal(vmctx types.VMContext, deal StorageDealProposal, providerWorker address.Address) aerrors.ActorError {
ctx, span := trace.StartSpan(vmctx.Context(), "validateDeal")
defer span.End()
if vmctx.BlockHeight() > deal.ProposalExpiration { if vmctx.BlockHeight() > deal.ProposalExpiration {
return aerrors.New(1, "deal proposal already expired") return aerrors.New(1, "deal proposal already expired")
} }
@ -394,7 +401,7 @@ func (st *StorageMarketState) validateDeal(vmctx types.VMContext, deal StorageDe
} }
// TODO: do some caching (changes gas so needs to be in spec too) // TODO: do some caching (changes gas so needs to be in spec too)
b, bnd, aerr := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), st.Balances, deal.Client, providerWorker) b, bnd, aerr := GetMarketBalances(ctx, vmctx.Ipld(), st.Balances, deal.Client, providerWorker)
if aerr != nil { if aerr != nil {
return aerrors.Wrap(aerr, "getting client, and provider balances") return aerrors.Wrap(aerr, "getting client, and provider balances")
} }

View File

@ -13,9 +13,9 @@ import (
"go.opencensus.io/trace" "go.opencensus.io/trace"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
@ -267,9 +267,9 @@ func shouldSlash(block1, block2 *types.BlockHeader) bool {
} }
type UpdateStorageParams struct { type UpdateStorageParams struct {
Delta types.BigInt Delta types.BigInt
NextProvingPeriodEnd uint64 NextSlashDeadline uint64
PreviousProvingPeriodEnd uint64 PreviousSlashDeadline uint64
} }
func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) { func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) {
@ -289,10 +289,10 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta) self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
previousBucket := params.PreviousProvingPeriodEnd % build.SlashablePowerDelay previousBucket := params.PreviousSlashDeadline % build.SlashablePowerDelay
nextBucket := params.NextProvingPeriodEnd % build.SlashablePowerDelay nextBucket := params.NextSlashDeadline % build.SlashablePowerDelay
if previousBucket == nextBucket && params.PreviousProvingPeriodEnd != 0 { if previousBucket == nextBucket && params.PreviousSlashDeadline != 0 {
nroot, err := vmctx.Storage().Put(&self) nroot, err := vmctx.Storage().Put(&self)
if err != nil { if err != nil {
return nil, err return nil, err
@ -310,10 +310,10 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte
return nil, aerrors.HandleExternalError(eerr, "loading proving buckets amt") return nil, aerrors.HandleExternalError(eerr, "loading proving buckets amt")
} }
if params.PreviousProvingPeriodEnd != 0 { // delete from previous bucket if params.PreviousSlashDeadline != 0 { // delete from previous bucket
err := deleteMinerFromBucket(vmctx, buckets, previousBucket) err := deleteMinerFromBucket(vmctx, buckets, previousBucket)
if err != nil { if err != nil {
return nil, err return nil, aerrors.Wrapf(err, "delete from bucket %d, next %d", previousBucket, nextBucket)
} }
} }
@ -393,7 +393,7 @@ func addMinerToBucket(vmctx types.VMContext, buckets *amt.Root, nextBucket uint6
return aerrors.HandleExternalError(err, "getting proving bucket") return aerrors.HandleExternalError(err, "getting proving bucket")
} }
err = bhamt.Set(vmctx.Context(), string(vmctx.Message().From.Bytes()), cborNull) err = bhamt.Set(vmctx.Context(), string(vmctx.Message().From.Bytes()), CborNull)
if err != nil { if err != nil {
return aerrors.HandleExternalError(err, "setting miner in proving bucket") return aerrors.HandleExternalError(err, "setting miner in proving bucket")
} }
@ -768,7 +768,7 @@ func MinerSetRemove(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, ma
type cbgNull struct{} type cbgNull struct{}
var cborNull = &cbgNull{} var CborNull = &cbgNull{}
func (cbgNull) MarshalCBOR(w io.Writer) error { func (cbgNull) MarshalCBOR(w io.Writer) error {
n, err := w.Write(cbg.CborNull) n, err := w.Write(cbg.CborNull)

View File

@ -8,8 +8,8 @@ import (
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-address"
. "github.com/filecoin-project/lotus/chain/actors" . "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"

View File

@ -1,7 +1,7 @@
package actors package actors
import ( import (
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
mh "github.com/multiformats/go-multihash" mh "github.com/multiformats/go-multihash"

View File

@ -8,8 +8,8 @@ import (
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/go-address"
. "github.com/filecoin-project/lotus/chain/actors" . "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"

View File

@ -1,8 +1,8 @@
package actors package actors
import ( import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
) )
func NewIDAddress(id uint64) (address.Address, ActorError) { func NewIDAddress(id uint64) (address.Address, ActorError) {

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
hamt "github.com/ipfs/go-hamt-ipld"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
@ -159,6 +160,16 @@ func HandleExternalError(err error, msg string) ActorError {
} }
} }
if xerrors.Is(err, &hamt.SerializationError{}) {
return &actorError{
fatal: false,
retCode: 253,
msg: msg,
frame: xerrors.Caller(1),
err: err,
}
}
return &actorError{ return &actorError{
fatal: true, fatal: true,

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"sort" "sort"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
@ -94,6 +94,10 @@ func (t *ExecParams) MarshalCBOR(w io.Writer) error {
} }
// t.Params ([]uint8) (slice) // t.Params ([]uint8) (slice)
if len(t.Params) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Params was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil {
return err return err
} }
@ -220,6 +224,10 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
for _, k := range keys { for _, k := range keys {
v := t.PreCommittedSectors[k] v := t.PreCommittedSectors[k]
if len(k) > cbg.MaxLength {
return xerrors.Errorf("Value in field k was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil {
return err return err
} }
@ -481,6 +489,10 @@ func (t *StorageMinerConstructorParams) MarshalCBOR(w io.Writer) error {
} }
// t.PeerID (peer.ID) (string) // t.PeerID (peer.ID) (string)
if len(t.PeerID) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.PeerID was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil {
return err return err
} }
@ -561,6 +573,10 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error {
} }
// t.CommR ([]uint8) (slice) // t.CommR ([]uint8) (slice)
if len(t.CommR) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.CommR was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil {
return err return err
} }
@ -574,6 +590,10 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error {
} }
// t.DealIDs ([]uint64) (slice) // t.DealIDs ([]uint64) (slice)
if len(t.DealIDs) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.DealIDs was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil {
return err return err
} }
@ -749,6 +769,10 @@ func (t *MinerInfo) MarshalCBOR(w io.Writer) error {
} }
// t.PeerID (peer.ID) (string) // t.PeerID (peer.ID) (string)
if len(t.PeerID) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.PeerID was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil {
return err return err
} }
@ -829,6 +853,10 @@ func (t *SubmitFallbackPoStParams) MarshalCBOR(w io.Writer) error {
} }
// t.Proof ([]uint8) (slice) // t.Proof ([]uint8) (slice)
if len(t.Proof) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Proof was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
return err return err
} }
@ -837,6 +865,10 @@ func (t *SubmitFallbackPoStParams) MarshalCBOR(w io.Writer) error {
} }
// t.Candidates ([]types.EPostTicket) (slice) // t.Candidates ([]types.EPostTicket) (slice)
if len(t.Candidates) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Candidates was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil {
return err return err
} }
@ -920,6 +952,10 @@ func (t *PaymentVerifyParams) MarshalCBOR(w io.Writer) error {
} }
// t.Extra ([]uint8) (slice) // t.Extra ([]uint8) (slice)
if len(t.Extra) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Extra was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Extra)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Extra)))); err != nil {
return err return err
} }
@ -928,6 +964,10 @@ func (t *PaymentVerifyParams) MarshalCBOR(w io.Writer) error {
} }
// t.Proof ([]uint8) (slice) // t.Proof ([]uint8) (slice)
if len(t.Proof) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Proof was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
return err return err
} }
@ -999,6 +1039,10 @@ func (t *UpdatePeerIDParams) MarshalCBOR(w io.Writer) error {
} }
// t.PeerID (peer.ID) (string) // t.PeerID (peer.ID) (string)
if len(t.PeerID) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.PeerID was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil {
return err return err
} }
@ -1089,6 +1133,10 @@ func (t *MultiSigActorState) MarshalCBOR(w io.Writer) error {
} }
// t.Signers ([]address.Address) (slice) // t.Signers ([]address.Address) (slice)
if len(t.Signers) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Signers was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Signers)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Signers)))); err != nil {
return err return err
} }
@ -1124,6 +1172,10 @@ func (t *MultiSigActorState) MarshalCBOR(w io.Writer) error {
} }
// t.Transactions ([]actors.MTransaction) (slice) // t.Transactions ([]actors.MTransaction) (slice)
if len(t.Transactions) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Transactions was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Transactions)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Transactions)))); err != nil {
return err return err
} }
@ -1266,6 +1318,10 @@ func (t *MultiSigConstructorParams) MarshalCBOR(w io.Writer) error {
} }
// t.Signers ([]address.Address) (slice) // t.Signers ([]address.Address) (slice)
if len(t.Signers) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Signers was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Signers)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Signers)))); err != nil {
return err return err
} }
@ -1377,6 +1433,10 @@ func (t *MultiSigProposeParams) MarshalCBOR(w io.Writer) error {
} }
// t.Params ([]uint8) (slice) // t.Params ([]uint8) (slice)
if len(t.Params) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Params was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil {
return err return err
} }
@ -1629,6 +1689,10 @@ func (t *MTransaction) MarshalCBOR(w io.Writer) error {
} }
// t.Params ([]uint8) (slice) // t.Params ([]uint8) (slice)
if len(t.Params) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Params was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil {
return err return err
} }
@ -1637,6 +1701,10 @@ func (t *MTransaction) MarshalCBOR(w io.Writer) error {
} }
// t.Approved ([]address.Address) (slice) // t.Approved ([]address.Address) (slice)
if len(t.Approved) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Approved was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Approved)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Approved)))); err != nil {
return err return err
} }
@ -1999,6 +2067,10 @@ func (t *PaymentChannelActorState) MarshalCBOR(w io.Writer) error {
for _, k := range keys { for _, k := range keys {
v := t.LaneStates[k] v := t.LaneStates[k]
if len(k) > cbg.MaxLength {
return xerrors.Errorf("Value in field k was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(k)))); err != nil {
return err return err
} }
@ -2271,6 +2343,10 @@ func (t *PCAUpdateChannelStateParams) MarshalCBOR(w io.Writer) error {
} }
// t.Secret ([]uint8) (slice) // t.Secret ([]uint8) (slice)
if len(t.Secret) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Secret was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Secret)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Secret)))); err != nil {
return err return err
} }
@ -2279,6 +2355,10 @@ func (t *PCAUpdateChannelStateParams) MarshalCBOR(w io.Writer) error {
} }
// t.Proof ([]uint8) (slice) // t.Proof ([]uint8) (slice)
if len(t.Proof) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Proof was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
return err return err
} }
@ -2381,6 +2461,10 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
} }
// t.Vouchers ([]*types.SignedVoucher) (slice) // t.Vouchers ([]*types.SignedVoucher) (slice)
if len(t.Vouchers) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Vouchers was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Vouchers)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Vouchers)))); err != nil {
return err return err
} }
@ -2613,6 +2697,10 @@ func (t *CreateStorageMinerParams) MarshalCBOR(w io.Writer) error {
} }
// t.PeerID (peer.ID) (string) // t.PeerID (peer.ID) (string)
if len(t.PeerID) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.PeerID was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.PeerID)))); err != nil {
return err return err
} }
@ -2778,13 +2866,13 @@ func (t *UpdateStorageParams) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.NextProvingPeriodEnd (uint64) (uint64) // t.NextSlashDeadline (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextProvingPeriodEnd))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextSlashDeadline))); err != nil {
return err return err
} }
// t.PreviousProvingPeriodEnd (uint64) (uint64) // t.PreviousSlashDeadline (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PreviousProvingPeriodEnd))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PreviousSlashDeadline))); err != nil {
return err return err
} }
return nil return nil
@ -2814,7 +2902,7 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error {
} }
} }
// t.NextProvingPeriodEnd (uint64) (uint64) // t.NextSlashDeadline (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br) maj, extra, err = cbg.CborReadHeader(br)
if err != nil { if err != nil {
@ -2823,8 +2911,8 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajUnsignedInt { if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field") return fmt.Errorf("wrong type for uint64 field")
} }
t.NextProvingPeriodEnd = uint64(extra) t.NextSlashDeadline = uint64(extra)
// t.PreviousProvingPeriodEnd (uint64) (uint64) // t.PreviousSlashDeadline (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br) maj, extra, err = cbg.CborReadHeader(br)
if err != nil { if err != nil {
@ -2833,7 +2921,7 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajUnsignedInt { if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field") return fmt.Errorf("wrong type for uint64 field")
} }
t.PreviousProvingPeriodEnd = uint64(extra) t.PreviousSlashDeadline = uint64(extra)
return nil return nil
} }
@ -3223,6 +3311,10 @@ func (t *StorageDealProposal) MarshalCBOR(w io.Writer) error {
} }
// t.PieceRef ([]uint8) (slice) // t.PieceRef ([]uint8) (slice)
if len(t.PieceRef) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.PieceRef was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PieceRef)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PieceRef)))); err != nil {
return err return err
} }
@ -3404,6 +3496,10 @@ func (t *PublishStorageDealsParams) MarshalCBOR(w io.Writer) error {
} }
// t.Deals ([]actors.StorageDealProposal) (slice) // t.Deals ([]actors.StorageDealProposal) (slice)
if len(t.Deals) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Deals was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Deals)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Deals)))); err != nil {
return err return err
} }
@ -3470,6 +3566,10 @@ func (t *PublishStorageDealResponse) MarshalCBOR(w io.Writer) error {
} }
// t.DealIDs ([]uint64) (slice) // t.DealIDs ([]uint64) (slice)
if len(t.DealIDs) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.DealIDs was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil {
return err return err
} }
@ -3540,6 +3640,10 @@ func (t *ActivateStorageDealsParams) MarshalCBOR(w io.Writer) error {
} }
// t.Deals ([]uint64) (slice) // t.Deals ([]uint64) (slice)
if len(t.Deals) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Deals was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Deals)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Deals)))); err != nil {
return err return err
} }
@ -3610,6 +3714,10 @@ func (t *ProcessStorageDealsPaymentParams) MarshalCBOR(w io.Writer) error {
} }
// t.DealIDs ([]uint64) (slice) // t.DealIDs ([]uint64) (slice)
if len(t.DealIDs) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.DealIDs was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil {
return err return err
} }
@ -3680,6 +3788,10 @@ func (t *OnChainDeal) MarshalCBOR(w io.Writer) error {
} }
// t.PieceRef ([]uint8) (slice) // t.PieceRef ([]uint8) (slice)
if len(t.PieceRef) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.PieceRef was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PieceRef)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PieceRef)))); err != nil {
return err return err
} }
@ -3850,6 +3962,10 @@ func (t *ComputeDataCommitmentParams) MarshalCBOR(w io.Writer) error {
} }
// t.DealIDs ([]uint64) (slice) // t.DealIDs ([]uint64) (slice)
if len(t.DealIDs) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.DealIDs was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil {
return err return err
} }
@ -3935,6 +4051,10 @@ func (t *SectorProveCommitInfo) MarshalCBOR(w io.Writer) error {
} }
// t.Proof ([]uint8) (slice) // t.Proof ([]uint8) (slice)
if len(t.Proof) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Proof was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
return err return err
} }
@ -3948,6 +4068,10 @@ func (t *SectorProveCommitInfo) MarshalCBOR(w io.Writer) error {
} }
// t.DealIDs ([]uint64) (slice) // t.DealIDs ([]uint64) (slice)
if len(t.DealIDs) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.DealIDs was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil {
return err return err
} }

46
chain/actors/forks.go Normal file
View File

@ -0,0 +1,46 @@
package actors
import (
"reflect"
"sort"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/types"
)
type update struct {
start uint64
method interface{}
}
func withUpdates(updates ...update) interface{} {
sort.Slice(updates, func(i, j int) bool { // so we iterate from newest below
return updates[i].start > updates[j].start
})
// <script type="application/javascript">
typ := reflect.TypeOf(updates[0].method)
out := reflect.MakeFunc(typ, func(args []reflect.Value) (results []reflect.Value) {
vmctx := args[1].Interface().(types.VMContext)
for _, u := range updates {
if vmctx.BlockHeight() >= u.start {
return reflect.ValueOf(u.method).Call(args)
}
}
return reflect.ValueOf(notFound(vmctx)).Call([]reflect.Value{})
})
return out.Interface()
// </script>
}
func notFound(vmctx types.VMContext) func() ([]byte, ActorError) {
return func() ([]byte, ActorError) {
return nil, aerrors.Fatal("no code for method %d at height %d", vmctx.Message().Method, vmctx.BlockHeight())
}
}

View File

@ -14,8 +14,8 @@ import (
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"

View File

@ -1,415 +0,0 @@
package address
import (
"bytes"
"encoding/json"
"fmt"
"io"
"strconv"
bls "github.com/filecoin-project/filecoin-ffi"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/minio/blake2b-simd"
"github.com/multiformats/go-varint"
"github.com/polydawn/refmt/obj/atlas"
"golang.org/x/xerrors"
cbg "github.com/whyrusleeping/cbor-gen"
)
func init() {
cbor.RegisterCborType(addressAtlasEntry)
}
var addressAtlasEntry = atlas.BuildEntry(Address{}).Transform().
TransformMarshal(atlas.MakeMarshalTransformFunc(
func(a Address) (string, error) {
return string(a.Bytes()), nil
})).
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
func(x string) (Address, error) {
return NewFromBytes([]byte(x))
})).
Complete()
// Address is the go type that represents an address in the filecoin network.
type Address struct{ str string }
// Undef is the type that represents an undefined address.
var Undef = Address{}
// Network represents which network an address belongs to.
type Network = byte
const (
// Mainnet is the main network.
Mainnet Network = iota
// Testnet is the test network.
Testnet
)
// MainnetPrefix is the main network prefix.
const MainnetPrefix = "f"
// TestnetPrefix is the main network prefix.
const TestnetPrefix = "t"
// Protocol represents which protocol an address uses.
type Protocol = byte
const (
// ID represents the address ID protocol.
ID Protocol = iota
// SECP256K1 represents the address SECP256K1 protocol.
SECP256K1
// Actor represents the address Actor protocol.
Actor
// BLS represents the address BLS protocol.
BLS
Unknown = Protocol(255)
)
// Protocol returns the protocol used by the address.
func (a Address) Protocol() Protocol {
if len(a.str) == 0 {
return Unknown
}
return a.str[0]
}
// Payload returns the payload of the address.
func (a Address) Payload() []byte {
return []byte(a.str[1:])
}
// Bytes returns the address as bytes.
func (a Address) Bytes() []byte {
return []byte(a.str)
}
// String returns an address encoded as a string.
func (a Address) String() string {
str, err := encode(Testnet, a)
if err != nil {
panic(err) // I don't know if this one is okay
}
return str
}
// Empty returns true if the address is empty, false otherwise.
func (a Address) Empty() bool {
return a == Undef
}
// Unmarshal unmarshals the cbor bytes into the address.
func (a Address) Unmarshal(b []byte) error {
return cbor.DecodeInto(b, &a)
}
// Marshal marshals the address to cbor.
func (a Address) Marshal() ([]byte, error) {
return cbor.DumpObject(a)
}
// UnmarshalJSON implements the json unmarshal interface.
func (a *Address) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
addr, err := decode(s)
if err != nil {
return err
}
*a = addr
return nil
}
// MarshalJSON implements the json marshal interface.
func (a Address) MarshalJSON() ([]byte, error) {
return []byte(`"` + a.String() + `"`), nil
}
// Format implements the Formatter interface.
func (a Address) Format(f fmt.State, c rune) {
switch c {
case 'v':
if a.Empty() {
fmt.Fprint(f, UndefAddressString) //nolint: errcheck
} else {
fmt.Fprintf(f, "[%x - %x]", a.Protocol(), a.Payload()) // nolint: errcheck
}
case 's':
fmt.Fprintf(f, "%s", a.String()) // nolint: errcheck
default:
fmt.Fprintf(f, "%"+string(c), a.Bytes()) // nolint: errcheck
}
}
func (a *Address) Scan(value interface{}) error {
switch value := value.(type) {
case string:
a1, err := decode(value)
if err != nil {
return err
}
*a = a1
return nil
default:
return xerrors.New("non-string types unsupported")
}
}
// NewIDAddress returns an address using the ID protocol.
func NewIDAddress(id uint64) (Address, error) {
return newAddress(ID, varint.ToUvarint(id))
}
// NewSecp256k1Address returns an address using the SECP256K1 protocol.
func NewSecp256k1Address(pubkey []byte) (Address, error) {
return newAddress(SECP256K1, addressHash(pubkey))
}
// NewActorAddress returns an address using the Actor protocol.
func NewActorAddress(data []byte) (Address, error) {
return newAddress(Actor, addressHash(data))
}
// NewBLSAddress returns an address using the BLS protocol.
func NewBLSAddress(pubkey []byte) (Address, error) {
return newAddress(BLS, pubkey)
}
// NewFromString returns the address represented by the string `addr`.
func NewFromString(addr string) (Address, error) {
return decode(addr)
}
// NewFromBytes return the address represented by the bytes `addr`.
func NewFromBytes(addr []byte) (Address, error) {
if len(addr) == 0 {
return Undef, nil
}
if len(addr) == 1 {
return Undef, ErrInvalidLength
}
return newAddress(addr[0], addr[1:])
}
// Checksum returns the checksum of `ingest`.
func Checksum(ingest []byte) []byte {
return hash(ingest, checksumHashConfig)
}
// ValidateChecksum returns true if the checksum of `ingest` is equal to `expected`>
func ValidateChecksum(ingest, expect []byte) bool {
digest := Checksum(ingest)
return bytes.Equal(digest, expect)
}
func addressHash(ingest []byte) []byte {
return hash(ingest, payloadHashConfig)
}
func newAddress(protocol Protocol, payload []byte) (Address, error) {
switch protocol {
case ID:
_, n, err := varint.FromUvarint(payload)
if err != nil {
return Undef, xerrors.Errorf("could not decode: %v: %w", err, ErrInvalidPayload)
}
if n != len(payload) {
return Undef, xerrors.Errorf("different varint length (v:%d != p:%d): %w",
n, len(payload), ErrInvalidPayload)
}
case SECP256K1, Actor:
if len(payload) != PayloadHashLength {
return Undef, ErrInvalidPayload
}
case BLS:
if len(payload) != bls.PublicKeyBytes {
return Undef, ErrInvalidPayload
}
default:
return Undef, ErrUnknownProtocol
}
explen := 1 + len(payload)
buf := make([]byte, explen)
buf[0] = protocol
copy(buf[1:], payload)
return Address{string(buf)}, nil
}
func encode(network Network, addr Address) (string, error) {
if addr == Undef {
return UndefAddressString, nil
}
var ntwk string
switch network {
case Mainnet:
ntwk = MainnetPrefix
case Testnet:
ntwk = TestnetPrefix
default:
return UndefAddressString, ErrUnknownNetwork
}
var strAddr string
switch addr.Protocol() {
case SECP256K1, Actor, BLS:
cksm := Checksum(append([]byte{addr.Protocol()}, addr.Payload()...))
strAddr = ntwk + fmt.Sprintf("%d", addr.Protocol()) + AddressEncoding.WithPadding(-1).EncodeToString(append(addr.Payload(), cksm[:]...))
case ID:
i, n, err := varint.FromUvarint(addr.Payload())
if err != nil {
return UndefAddressString, xerrors.Errorf("could not decode varint: %w", err)
}
if n != len(addr.Payload()) {
return UndefAddressString, xerrors.Errorf("payload contains additional bytes")
}
strAddr = fmt.Sprintf("%s%d%d", ntwk, addr.Protocol(), i)
default:
return UndefAddressString, ErrUnknownProtocol
}
return strAddr, nil
}
func decode(a string) (Address, error) {
if len(a) == 0 {
return Undef, nil
}
if a == UndefAddressString {
return Undef, nil
}
if len(a) > MaxAddressStringLength || len(a) < 3 {
return Undef, ErrInvalidLength
}
if string(a[0]) != MainnetPrefix && string(a[0]) != TestnetPrefix {
return Undef, ErrUnknownNetwork
}
var protocol Protocol
switch a[1] {
case '0':
protocol = ID
case '1':
protocol = SECP256K1
case '2':
protocol = Actor
case '3':
protocol = BLS
default:
return Undef, ErrUnknownProtocol
}
raw := a[2:]
if protocol == ID {
// 20 is length of math.MaxUint64 as a string
if len(raw) > 20 {
return Undef, ErrInvalidLength
}
id, err := strconv.ParseUint(raw, 10, 64)
if err != nil {
return Undef, ErrInvalidPayload
}
return newAddress(protocol, varint.ToUvarint(id))
}
payloadcksm, err := AddressEncoding.WithPadding(-1).DecodeString(raw)
if err != nil {
return Undef, err
}
payload := payloadcksm[:len(payloadcksm)-ChecksumHashLength]
cksm := payloadcksm[len(payloadcksm)-ChecksumHashLength:]
if protocol == SECP256K1 || protocol == Actor {
if len(payload) != 20 {
return Undef, ErrInvalidPayload
}
}
if !ValidateChecksum(append([]byte{protocol}, payload...), cksm) {
return Undef, ErrInvalidChecksum
}
return newAddress(protocol, payload)
}
func hash(ingest []byte, cfg *blake2b.Config) []byte {
hasher, err := blake2b.New(cfg)
if err != nil {
// If this happens sth is very wrong.
panic(fmt.Sprintf("invalid address hash configuration: %v", err)) // ok
}
if _, err := hasher.Write(ingest); err != nil {
// blake2bs Write implementation never returns an error in its current
// setup. So if this happens sth went very wrong.
panic(fmt.Sprintf("blake2b is unable to process hashes: %v", err)) // ok
}
return hasher.Sum(nil)
}
func (a Address) MarshalCBOR(w io.Writer) error {
if a == Undef {
return fmt.Errorf("cannot marshal undefined address")
}
abytes := a.Bytes()
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(abytes)))); err != nil {
return err
}
if _, err := w.Write(abytes); err != nil {
return err
}
return nil
}
func (a *Address) UnmarshalCBOR(br io.Reader) error {
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajByteString {
return fmt.Errorf("cbor type for address unmarshal was not byte string")
}
if extra > 64 {
return fmt.Errorf("too many bytes to unmarshal for an address")
}
buf := make([]byte, int(extra))
if _, err := io.ReadFull(br, buf); err != nil {
return err
}
addr, err := NewFromBytes(buf)
if err != nil {
return err
}
if addr == Undef {
return fmt.Errorf("cbor input should not contain empty addresses")
}
*a = addr
return nil
}
func IDFromAddress(addr Address) (uint64, error) {
if addr.Protocol() != ID {
return 0, xerrors.Errorf("cannot get id from non id address")
}
i, _, err := varint.FromUvarint(addr.Payload())
return i, err
}

View File

@ -1,542 +0,0 @@
package address
import (
"bytes"
"encoding/base32"
"fmt"
"math"
"math/rand"
"strconv"
"testing"
"time"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/multiformats/go-varint"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/lotus/lib/crypto"
)
func init() {
rand.Seed(time.Now().Unix())
}
func TestRandomIDAddress(t *testing.T) {
assert := assert.New(t)
addr, err := NewIDAddress(uint64(rand.Int()))
assert.NoError(err)
assert.Equal(ID, addr.Protocol())
str, err := encode(Testnet, addr)
assert.NoError(err)
maybe, err := decode(str)
assert.NoError(err)
assert.Equal(addr, maybe)
}
var allTestAddresses = []string{
"t00",
"t01",
"t010",
"t0150",
"t0499",
"t01024",
"t01729",
"t0999999",
"t15ihq5ibzwki2b4ep2f46avlkrqzhpqgtga7pdrq",
"t12fiakbhe2gwd5cnmrenekasyn6v5tnaxaqizq6a",
"t1wbxhu3ypkuo6eyp6hjx6davuelxaxrvwb2kuwva",
"t1xtwapqc6nh4si2hcwpr3656iotzmlwumogqbuaa",
"t1xcbgdhkgkwht3hrrnui3jdopeejsoatkzmoltqy",
"t17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy",
"t24vg6ut43yw2h2jqydgbg2xq7x6f4kub3bg6as6i",
"t25nml2cfbljvn4goqtclhifepvfnicv6g7mfmmvq",
"t2nuqrg7vuysaue2pistjjnt3fadsdzvyuatqtfei",
"t24dd4ox4c2vpf5vk5wkadgyyn6qtuvgcpxxon64a",
"t2gfvuyh7v2sx3patm5k23wdzmhyhtmqctasbr23y",
"t3vvmn62lofvhjd2ugzca6sof2j2ubwok6cj4xxbfzz4yuxfkgobpihhd2thlanmsh3w2ptld2gqkn2jvlss4a",
"t3wmuu6crofhqmm3v4enos73okk2l366ck6yc4owxwbdtkmpk42ohkqxfitcpa57pjdcftql4tojda2poeruwa",
"t3s2q2hzhkpiknjgmf4zq3ejab2rh62qbndueslmsdzervrhapxr7dftie4kpnpdiv2n6tvkr743ndhrsw6d3a",
"t3q22fijmmlckhl56rn5nkyamkph3mcfu5ed6dheq53c244hfmnq2i7efdma3cj5voxenwiummf2ajlsbxc65a",
"t3u5zgwa4ael3vuocgc5mfgygo4yuqocrntuuhcklf4xzg5tcaqwbyfabxetwtj4tsam3pbhnwghyhijr5mixa",
}
func TestVectorsIDAddress(t *testing.T) {
testCases := []struct {
input uint64
expected string
}{
{uint64(0), "t00"},
{uint64(1), "t01"},
{uint64(10), "t010"},
{uint64(150), "t0150"},
{uint64(499), "t0499"},
{uint64(1024), "t01024"},
{uint64(1729), "t01729"},
{uint64(999999), "t0999999"},
{math.MaxUint64, fmt.Sprintf("t0%s", strconv.FormatUint(math.MaxUint64, 10))},
}
for _, tc := range testCases {
tc := tc
t.Run(fmt.Sprintf("testing actorID address: %s", tc.expected), func(t *testing.T) {
assert := assert.New(t)
// Round trip encoding and decoding from string
addr, err := NewIDAddress(tc.input)
assert.NoError(err)
assert.Equal(tc.expected, addr.String())
maybeAddr, err := NewFromString(tc.expected)
assert.NoError(err)
assert.Equal(ID, maybeAddr.Protocol())
id, _, err := varint.FromUvarint(maybeAddr.Payload())
assert.NoError(err)
assert.Equal(tc.input, id)
// Round trip to and from bytes
maybeAddrBytes, err := NewFromBytes(maybeAddr.Bytes())
assert.NoError(err)
assert.Equal(maybeAddr, maybeAddrBytes)
// Round trip encoding and decoding json
b, err := addr.MarshalJSON()
assert.NoError(err)
var newAddr Address
err = newAddr.UnmarshalJSON(b)
assert.NoError(err)
assert.Equal(addr, newAddr)
})
}
}
func TestSecp256k1Address(t *testing.T) {
assert := assert.New(t)
sk, err := crypto.GenerateKey()
assert.NoError(err)
addr, err := NewSecp256k1Address(crypto.PublicKey(sk))
assert.NoError(err)
assert.Equal(SECP256K1, addr.Protocol())
str, err := encode(Mainnet, addr)
assert.NoError(err)
maybe, err := decode(str)
assert.NoError(err)
assert.Equal(addr, maybe)
}
func TestVectorSecp256k1Address(t *testing.T) {
testCases := []struct {
input []byte
expected string
}{
{[]byte{4, 148, 2, 250, 195, 126, 100, 50, 164, 22, 163, 160, 202, 84,
38, 181, 24, 90, 179, 178, 79, 97, 52, 239, 162, 92, 228, 135, 200,
45, 46, 78, 19, 191, 69, 37, 17, 224, 210, 36, 84, 33, 248, 97, 59,
193, 13, 114, 250, 33, 102, 102, 169, 108, 59, 193, 57, 32, 211,
255, 35, 63, 208, 188, 5},
"t15ihq5ibzwki2b4ep2f46avlkrqzhpqgtga7pdrq"},
{[]byte{4, 118, 135, 185, 16, 55, 155, 242, 140, 190, 58, 234, 103, 75,
18, 0, 12, 107, 125, 186, 70, 255, 192, 95, 108, 148, 254, 42, 34,
187, 204, 38, 2, 255, 127, 92, 118, 242, 28, 165, 93, 54, 149, 145,
82, 176, 225, 232, 135, 145, 124, 57, 53, 118, 238, 240, 147, 246,
30, 189, 58, 208, 111, 127, 218},
"t12fiakbhe2gwd5cnmrenekasyn6v5tnaxaqizq6a"},
{[]byte{4, 222, 253, 208, 16, 1, 239, 184, 110, 1, 222, 213, 206, 52,
248, 71, 167, 58, 20, 129, 158, 230, 65, 188, 182, 11, 185, 41, 147,
89, 111, 5, 220, 45, 96, 95, 41, 133, 248, 209, 37, 129, 45, 172,
65, 99, 163, 150, 52, 155, 35, 193, 28, 194, 255, 53, 157, 229, 75,
226, 135, 234, 98, 49, 155},
"t1wbxhu3ypkuo6eyp6hjx6davuelxaxrvwb2kuwva"},
{[]byte{4, 3, 237, 18, 200, 20, 182, 177, 13, 46, 224, 157, 149, 180,
104, 141, 178, 209, 128, 208, 169, 163, 122, 107, 106, 125, 182, 61,
41, 129, 30, 233, 115, 4, 121, 216, 239, 145, 57, 233, 18, 73, 202,
189, 57, 50, 145, 207, 229, 210, 119, 186, 118, 222, 69, 227, 224,
133, 163, 118, 129, 191, 54, 69, 210},
"t1xtwapqc6nh4si2hcwpr3656iotzmlwumogqbuaa"},
{[]byte{4, 247, 150, 129, 154, 142, 39, 22, 49, 175, 124, 24, 151, 151,
181, 69, 214, 2, 37, 147, 97, 71, 230, 1, 14, 101, 98, 179, 206, 158,
254, 139, 16, 20, 65, 97, 169, 30, 208, 180, 236, 137, 8, 0, 37, 63,
166, 252, 32, 172, 144, 251, 241, 251, 242, 113, 48, 164, 236, 195,
228, 3, 183, 5, 118},
"t1xcbgdhkgkwht3hrrnui3jdopeejsoatkzmoltqy"},
{[]byte{4, 66, 131, 43, 248, 124, 206, 158, 163, 69, 185, 3, 80, 222,
125, 52, 149, 133, 156, 164, 73, 5, 156, 94, 136, 221, 231, 66, 133,
223, 251, 158, 192, 30, 186, 188, 95, 200, 98, 104, 207, 234, 235,
167, 174, 5, 191, 184, 214, 142, 183, 90, 82, 104, 120, 44, 248, 111,
200, 112, 43, 239, 138, 31, 224},
"t17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy"},
}
for _, tc := range testCases {
tc := tc
t.Run(fmt.Sprintf("testing secp256k1 address: %s", tc.expected), func(t *testing.T) {
assert := assert.New(t)
// Round trip encoding and decoding from string
addr, err := NewSecp256k1Address(tc.input)
assert.NoError(err)
assert.Equal(tc.expected, addr.String())
maybeAddr, err := NewFromString(tc.expected)
assert.NoError(err)
assert.Equal(SECP256K1, maybeAddr.Protocol())
assert.Equal(addressHash(tc.input), maybeAddr.Payload())
// Round trip to and from bytes
maybeAddrBytes, err := NewFromBytes(maybeAddr.Bytes())
assert.NoError(err)
assert.Equal(maybeAddr, maybeAddrBytes)
// Round trip encoding and decoding json
b, err := addr.MarshalJSON()
assert.NoError(err)
var newAddr Address
err = newAddr.UnmarshalJSON(b)
assert.NoError(err)
assert.Equal(addr, newAddr)
})
}
}
func TestRandomActorAddress(t *testing.T) {
assert := assert.New(t)
actorMsg := make([]byte, 20)
rand.Read(actorMsg)
addr, err := NewActorAddress(actorMsg)
assert.NoError(err)
assert.Equal(Actor, addr.Protocol())
str, err := encode(Mainnet, addr)
assert.NoError(err)
maybe, err := decode(str)
assert.NoError(err)
assert.Equal(addr, maybe)
}
func TestVectorActorAddress(t *testing.T) {
testCases := []struct {
input []byte
expected string
}{
{[]byte{118, 18, 129, 144, 205, 240, 104, 209, 65, 128, 68, 172, 192,
62, 11, 103, 129, 151, 13, 96},
"t24vg6ut43yw2h2jqydgbg2xq7x6f4kub3bg6as6i"},
{[]byte{44, 175, 184, 226, 224, 107, 186, 152, 234, 101, 124, 92, 245,
244, 32, 35, 170, 35, 232, 142},
"t25nml2cfbljvn4goqtclhifepvfnicv6g7mfmmvq"},
{[]byte{2, 44, 158, 14, 162, 157, 143, 64, 197, 106, 190, 195, 92, 141,
88, 125, 160, 166, 76, 24},
"t2nuqrg7vuysaue2pistjjnt3fadsdzvyuatqtfei"},
{[]byte{223, 236, 3, 14, 32, 79, 15, 89, 216, 15, 29, 94, 233, 29, 253,
6, 109, 127, 99, 189},
"t24dd4ox4c2vpf5vk5wkadgyyn6qtuvgcpxxon64a"},
{[]byte{61, 58, 137, 232, 221, 171, 84, 120, 50, 113, 108, 109, 70, 140,
53, 96, 201, 244, 127, 216},
"t2gfvuyh7v2sx3patm5k23wdzmhyhtmqctasbr23y"},
}
for _, tc := range testCases {
tc := tc
t.Run(fmt.Sprintf("testing Actor address: %s", tc.expected), func(t *testing.T) {
assert := assert.New(t)
// Round trip encoding and decoding from string
addr, err := NewActorAddress(tc.input)
assert.NoError(err)
assert.Equal(tc.expected, addr.String())
maybeAddr, err := NewFromString(tc.expected)
assert.NoError(err)
assert.Equal(Actor, maybeAddr.Protocol())
assert.Equal(addressHash(tc.input), maybeAddr.Payload())
// Round trip to and from bytes
maybeAddrBytes, err := NewFromBytes(maybeAddr.Bytes())
assert.NoError(err)
assert.Equal(maybeAddr, maybeAddrBytes)
// Round trip encoding and decoding json
b, err := addr.MarshalJSON()
assert.NoError(err)
var newAddr Address
err = newAddr.UnmarshalJSON(b)
assert.NoError(err)
assert.Equal(addr, newAddr)
})
}
}
func TestRandomBLSAddress(t *testing.T) {
assert := assert.New(t)
pk := ffi.PrivateKeyPublicKey(ffi.PrivateKeyGenerate())
addr, err := NewBLSAddress(pk[:])
assert.NoError(err)
assert.Equal(BLS, addr.Protocol())
str, err := encode(Mainnet, addr)
assert.NoError(err)
maybe, err := decode(str)
assert.NoError(err)
assert.Equal(addr, maybe)
}
func TestVectorBLSAddress(t *testing.T) {
testCases := []struct {
input []byte
expected string
}{
{[]byte{173, 88, 223, 105, 110, 45, 78, 145, 234, 134, 200, 129, 233, 56,
186, 78, 168, 27, 57, 94, 18, 121, 123, 132, 185, 207, 49, 75, 149, 70,
112, 94, 131, 156, 122, 153, 214, 6, 178, 71, 221, 180, 249, 172, 122,
52, 20, 221},
"t3vvmn62lofvhjd2ugzca6sof2j2ubwok6cj4xxbfzz4yuxfkgobpihhd2thlanmsh3w2ptld2gqkn2jvlss4a"},
{[]byte{179, 41, 79, 10, 46, 41, 224, 198, 110, 188, 35, 93, 47, 237,
202, 86, 151, 191, 120, 74, 246, 5, 199, 90, 246, 8, 230, 166, 61, 92,
211, 142, 168, 92, 168, 152, 158, 14, 253, 233, 24, 139, 56, 47,
147, 114, 70, 13},
"t3wmuu6crofhqmm3v4enos73okk2l366ck6yc4owxwbdtkmpk42ohkqxfitcpa57pjdcftql4tojda2poeruwa"},
{[]byte{150, 161, 163, 228, 234, 122, 20, 212, 153, 133, 230, 97, 178,
36, 1, 212, 79, 237, 64, 45, 29, 9, 37, 178, 67, 201, 35, 88, 156,
15, 188, 126, 50, 205, 4, 226, 158, 215, 141, 21, 211, 125, 58, 170,
63, 230, 218, 51},
"t3s2q2hzhkpiknjgmf4zq3ejab2rh62qbndueslmsdzervrhapxr7dftie4kpnpdiv2n6tvkr743ndhrsw6d3a"},
{[]byte{134, 180, 84, 37, 140, 88, 148, 117, 247, 209, 111, 90, 172, 1,
138, 121, 246, 193, 22, 157, 32, 252, 51, 146, 29, 216, 181, 206, 28,
172, 108, 52, 143, 144, 163, 96, 54, 36, 246, 174, 185, 27, 100, 81,
140, 46, 128, 149},
"t3q22fijmmlckhl56rn5nkyamkph3mcfu5ed6dheq53c244hfmnq2i7efdma3cj5voxenwiummf2ajlsbxc65a"},
{[]byte{167, 114, 107, 3, 128, 34, 247, 90, 56, 70, 23, 88, 83, 96, 206,
230, 41, 7, 10, 45, 157, 40, 113, 41, 101, 229, 242, 110, 204, 64,
133, 131, 130, 128, 55, 36, 237, 52, 242, 114, 3, 54, 240, 157, 182,
49, 240, 116},
"t3u5zgwa4ael3vuocgc5mfgygo4yuqocrntuuhcklf4xzg5tcaqwbyfabxetwtj4tsam3pbhnwghyhijr5mixa"},
}
for _, tc := range testCases {
tc := tc
t.Run(fmt.Sprintf("testing bls address: %s", tc.expected), func(t *testing.T) {
assert := assert.New(t)
// Round trip encoding and decoding from string
addr, err := NewBLSAddress(tc.input)
assert.NoError(err)
assert.Equal(tc.expected, addr.String())
maybeAddr, err := NewFromString(tc.expected)
assert.NoError(err)
assert.Equal(BLS, maybeAddr.Protocol())
assert.Equal(tc.input, maybeAddr.Payload())
// Round trip to and from bytes
maybeAddrBytes, err := NewFromBytes(maybeAddr.Bytes())
assert.NoError(err)
assert.Equal(maybeAddr, maybeAddrBytes)
// Round trip encoding and decoding json
b, err := addr.MarshalJSON()
assert.NoError(err)
var newAddr Address
err = newAddr.UnmarshalJSON(b)
assert.NoError(err)
assert.Equal(addr, newAddr)
})
}
}
func TestInvalidStringAddresses(t *testing.T) {
testCases := []struct {
input string
expetErr error
}{
{"Q2gfvuyh7v2sx3patm5k23wdzmhyhtmqctasbr23y", ErrUnknownNetwork},
{"t4gfvuyh7v2sx3patm5k23wdzmhyhtmqctasbr23y", ErrUnknownProtocol},
{"t2gfvuyh7v2sx3patm5k23wdzmhyhtmqctasbr24y", ErrInvalidChecksum},
{"t0banananananannnnnnnnn", ErrInvalidLength},
{"t0banananananannnnnnnn", ErrInvalidPayload},
{"t2gfvuyh7v2sx3patm1k23wdzmhyhtmqctasbr24y", base32.CorruptInputError(16)}, // '1' is not in base32 alphabet
{"t2gfvuyh7v2sx3paTm1k23wdzmhyhtmqctasbr24y", base32.CorruptInputError(14)}, // 'T' is not in base32 alphabet
{"t2", ErrInvalidLength},
}
for _, tc := range testCases {
tc := tc
t.Run(fmt.Sprintf("testing string address: %s", tc.expetErr), func(t *testing.T) {
assert := assert.New(t)
_, err := NewFromString(tc.input)
assert.Equal(tc.expetErr, err)
})
}
}
func TestInvalidByteAddresses(t *testing.T) {
testCases := []struct {
input []byte
expetErr error
}{
// Unknown Protocol
{[]byte{4, 4, 4}, ErrUnknownProtocol},
// ID protocol
{[]byte{0}, ErrInvalidLength},
// SECP256K1 Protocol
{append([]byte{1}, make([]byte, PayloadHashLength-1)...), ErrInvalidPayload},
{append([]byte{1}, make([]byte, PayloadHashLength+1)...), ErrInvalidPayload},
// Actor Protocol
{append([]byte{2}, make([]byte, PayloadHashLength-1)...), ErrInvalidPayload},
{append([]byte{2}, make([]byte, PayloadHashLength+1)...), ErrInvalidPayload},
// BLS Protocol
{append([]byte{3}, make([]byte, ffi.PublicKeyBytes-1)...), ErrInvalidPayload},
{append([]byte{3}, make([]byte, ffi.PrivateKeyBytes+1)...), ErrInvalidPayload},
}
for _, tc := range testCases {
tc := tc
t.Run(fmt.Sprintf("testing byte address: %s", tc.expetErr), func(t *testing.T) {
assert := assert.New(t)
_, err := NewFromBytes(tc.input)
assert.Equal(tc.expetErr, err)
})
}
}
func TestChecksum(t *testing.T) {
assert := assert.New(t)
data := []byte("helloworld")
bata := []byte("kittinmittins")
cksm := Checksum(data)
assert.Len(cksm, ChecksumHashLength)
assert.True(ValidateChecksum(data, cksm))
assert.False(ValidateChecksum(bata, cksm))
}
func TestAddressFormat(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
a, err := NewActorAddress([]byte("hello"))
require.NoError(err)
assert.Equal("t2wvjry4bx6bwj6kkhcmvgu5zafqyi5cjzbtet3va", a.String())
assert.Equal("02B5531C7037F06C9F2947132A6A77202C308E8939", fmt.Sprintf("%X", a))
assert.Equal("[2 - b5531c7037f06c9f2947132a6a77202c308e8939]", fmt.Sprintf("%v", a))
assert.Equal("", fmt.Sprintf("%X", Undef))
assert.Equal(UndefAddressString, Undef.String())
assert.Equal(UndefAddressString, fmt.Sprintf("%v", Undef))
}
func TestCborMarshal(t *testing.T) {
for _, a := range allTestAddresses {
addr, err := NewFromString(a)
if err != nil {
t.Fatal(err)
}
buf := new(bytes.Buffer)
if err := addr.MarshalCBOR(buf); err != nil {
t.Fatal(err)
}
/*
// Note: this is commented out because we're currently serializing addresses as cbor "text strings", not "byte strings".
// This is to get around the restriction that refmt only allows string keys in maps.
// if you change it to serialize to byte strings and uncomment this, the tests pass fine
oldbytes, err := cbor.DumpObject(addr)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(oldbytes, buf.Bytes()) {
t.Fatalf("serialization doesnt match old serialization: %s", a)
}
*/
var out Address
if err := out.UnmarshalCBOR(buf); err != nil {
t.Fatal(err)
}
if out != addr {
t.Fatalf("failed to round trip %s", a)
}
}
}
func BenchmarkCborMarshal(b *testing.B) {
addr, err := NewFromString("t15ihq5ibzwki2b4ep2f46avlkrqzhpqgtga7pdrq")
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
buf := new(bytes.Buffer)
for i := 0; i < b.N; i++ {
buf.Reset()
if err := addr.MarshalCBOR(buf); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkCborUnmarshal(b *testing.B) {
addr, err := NewFromString("t15ihq5ibzwki2b4ep2f46avlkrqzhpqgtga7pdrq")
if err != nil {
b.Fatal(err)
}
buf := new(bytes.Buffer)
if err := addr.MarshalCBOR(buf); err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
var a Address
if err := a.UnmarshalCBOR(bytes.NewReader(buf.Bytes())); err != nil {
b.Fatal(err)
}
}
}
func TestIDEdgeCase(t *testing.T) {
a, err := NewFromBytes([]byte{0, 0x80})
_ = a.String()
assert.Error(t, err)
}

View File

@ -1,94 +0,0 @@
package address
import (
"fmt"
"math/rand"
"testing"
)
func blsaddr(n int64) Address {
buf := make([]byte, 48)
r := rand.New(rand.NewSource(n))
r.Read(buf)
addr, err := NewBLSAddress(buf)
if err != nil {
panic(err) // ok
}
return addr
}
func makeActorAddresses(n int) [][]byte {
var addrs [][]byte
for i := 0; i < n; i++ {
a, err := NewActorAddress([]byte(fmt.Sprintf("ACTOR ADDRESS %d", i)))
if err != nil {
panic(err) // ok
}
addrs = append(addrs, a.Bytes())
}
return addrs
}
func makeBlsAddresses(n int64) [][]byte {
var addrs [][]byte
for i := int64(0); i < n; i++ {
addrs = append(addrs, blsaddr(n).Bytes())
}
return addrs
}
func makeSecpAddresses(n int) [][]byte {
var addrs [][]byte
for i := 0; i < n; i++ {
r := rand.New(rand.NewSource(int64(i)))
buf := make([]byte, 32)
r.Read(buf)
a, err := NewSecp256k1Address(buf)
if err != nil {
panic(err) // ok
}
addrs = append(addrs, a.Bytes())
}
return addrs
}
func makeIDAddresses(n int) [][]byte {
var addrs [][]byte
for i := 0; i < n; i++ {
a, err := NewIDAddress(uint64(i))
if err != nil {
panic(err) // ok
}
addrs = append(addrs, a.Bytes())
}
return addrs
}
func BenchmarkParseActorAddress(b *testing.B) {
benchTestWithAddrs := func(a [][]byte) func(b *testing.B) {
return func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := NewFromBytes(a[i%len(a)])
if err != nil {
b.Fatal(err)
}
}
}
}
b.Run("actor", benchTestWithAddrs(makeActorAddresses(20)))
b.Run("bls", benchTestWithAddrs(makeBlsAddresses(20)))
b.Run("secp256k1", benchTestWithAddrs(makeSecpAddresses(20)))
b.Run("id", benchTestWithAddrs(makeIDAddresses(20)))
}

View File

@ -1,65 +0,0 @@
package address
import (
"encoding/base32"
"errors"
"github.com/minio/blake2b-simd"
)
func init() {
var err error
TestAddress, err = NewActorAddress([]byte("satoshi"))
if err != nil {
panic(err)
}
TestAddress2, err = NewActorAddress([]byte("nakamoto"))
if err != nil {
panic(err)
}
}
var (
// TestAddress is an account with some initial funds in it.
TestAddress Address
// TestAddress2 is an account with some initial funds in it.
TestAddress2 Address
)
var (
// ErrUnknownNetwork is returned when encountering an unknown network in an address.
ErrUnknownNetwork = errors.New("unknown address network")
// ErrUnknownProtocol is returned when encountering an unknown protocol in an address.
ErrUnknownProtocol = errors.New("unknown address protocol")
// ErrInvalidPayload is returned when encountering an invalid address payload.
ErrInvalidPayload = errors.New("invalid address payload")
// ErrInvalidLength is returned when encountering an address of invalid length.
ErrInvalidLength = errors.New("invalid address length")
// ErrInvalidChecksum is returned when encountering an invalid address checksum.
ErrInvalidChecksum = errors.New("invalid address checksum")
)
// UndefAddressString is the string used to represent an empty address when encoded to a string.
var UndefAddressString = "<empty>"
// PayloadHashLength defines the hash length taken over addresses using the Actor and SECP256K1 protocols.
const PayloadHashLength = 20
// ChecksumHashLength defines the hash length used for calculating address checksums.
const ChecksumHashLength = 4
// MaxAddressStringLength is the max length of an address encoded as a string
// it include the network prefx, protocol, and bls publickey
const MaxAddressStringLength = 2 + 84
var payloadHashConfig = &blake2b.Config{Size: PayloadHashLength}
var checksumHashConfig = &blake2b.Config{Size: ChecksumHashLength}
const encodeStd = "abcdefghijklmnopqrstuvwxyz234567"
// AddressEncoding defines the base32 config used for address encoding and decoding.
var AddressEncoding = base32.NewEncoding(encodeStd)

View File

@ -1,20 +0,0 @@
package address
import (
"fmt"
)
// NewForTestGetter returns a closure that returns an address unique to that invocation.
// The address is unique wrt the closure returned, not globally.
func NewForTestGetter() func() Address {
i := 0
return func() Address {
s := fmt.Sprintf("address%d", i)
i++
newAddr, err := NewActorAddress([]byte(s))
if err != nil {
panic(err)
}
return newAddr
}
}

View File

@ -0,0 +1,71 @@
package chain
import (
"sort"
"sync"
"time"
"github.com/filecoin-project/lotus/chain/types"
"github.com/hashicorp/golang-lru"
peer "github.com/libp2p/go-libp2p-core/peer"
)
type blockReceiptTracker struct {
lk sync.Mutex
// using an LRU cache because i don't want to handle all the edge cases for
// manual cleanup and maintenance of a fixed size set
cache *lru.Cache
}
type peerSet struct {
peers map[peer.ID]time.Time
}
func newBlockReceiptTracker() *blockReceiptTracker {
c, _ := lru.New(512)
return &blockReceiptTracker{
cache: c,
}
}
func (brt *blockReceiptTracker) Add(p peer.ID, ts *types.TipSet) {
brt.lk.Lock()
defer brt.lk.Unlock()
val, ok := brt.cache.Get(ts.Key())
if !ok {
pset := &peerSet{
peers: map[peer.ID]time.Time{
p: time.Now(),
},
}
brt.cache.Add(ts.Key(), pset)
return
}
val.(*peerSet).peers[p] = time.Now()
}
func (brt *blockReceiptTracker) GetPeers(ts *types.TipSet) []peer.ID {
brt.lk.Lock()
defer brt.lk.Unlock()
val, ok := brt.cache.Get(ts.Key())
if !ok {
return nil
}
ps := val.(*peerSet)
out := make([]peer.ID, 0, len(ps.peers))
for p := range ps.peers {
out = append(out, p)
}
sort.Slice(out, func(i, j int) bool {
return ps.peers[out[i]].Before(ps.peers[out[j]])
})
return out
}

View File

@ -8,9 +8,9 @@ import (
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
@ -90,7 +90,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) {
var req BlockSyncRequest var req BlockSyncRequest
if err := cborutil.ReadCborRPC(bufio.NewReader(s), &req); err != nil { if err := cborutil.ReadCborRPC(bufio.NewReader(s), &req); err != nil {
log.Errorf("failed to read block sync request: %s", err) log.Warnf("failed to read block sync request: %s", err)
return return
} }
log.Infof("block sync request for: %s %d", req.Start, req.RequestLength) log.Infof("block sync request for: %s %d", req.Start, req.RequestLength)
@ -102,7 +102,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) {
} }
if err := cborutil.WriteCborRPC(s, resp); err != nil { if err := cborutil.WriteCborRPC(s, resp); err != nil {
log.Error("failed to write back response for handle stream: ", err) log.Warn("failed to write back response for handle stream: ", err)
return return
} }
} }
@ -124,7 +124,7 @@ func (bss *BlockSyncService) processRequest(ctx context.Context, req *BlockSyncR
trace.BoolAttribute("messages", opts.IncludeMessages), trace.BoolAttribute("messages", opts.IncludeMessages),
) )
chain, err := bss.collectChainSegment(req.Start, req.RequestLength, opts) chain, err := bss.collectChainSegment(types.NewTipSetKey(req.Start...), req.RequestLength, opts)
if err != nil { if err != nil {
log.Warn("encountered error while responding to block sync request: ", err) log.Warn("encountered error while responding to block sync request: ", err)
return &BlockSyncResponse{ return &BlockSyncResponse{
@ -139,7 +139,7 @@ func (bss *BlockSyncService) processRequest(ctx context.Context, req *BlockSyncR
}, nil }, nil
} }
func (bss *BlockSyncService) collectChainSegment(start []cid.Cid, length uint64, opts *BSOptions) ([]*BSTipSet, error) { func (bss *BlockSyncService) collectChainSegment(start types.TipSetKey, length uint64, opts *BSOptions) ([]*BSTipSet, error) {
var bstips []*BSTipSet var bstips []*BSTipSet
cur := start cur := start
for { for {

View File

@ -18,9 +18,9 @@ import (
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/peermgr" "github.com/filecoin-project/lotus/peermgr"
) )
@ -59,18 +59,18 @@ func (bs *BlockSync) processStatus(req *BlockSyncRequest, res *BlockSyncResponse
} }
} }
func (bs *BlockSync) GetBlocks(ctx context.Context, tipset []cid.Cid, count int) ([]*types.TipSet, error) { func (bs *BlockSync) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error) {
ctx, span := trace.StartSpan(ctx, "bsync.GetBlocks") ctx, span := trace.StartSpan(ctx, "bsync.GetBlocks")
defer span.End() defer span.End()
if span.IsRecordingEvents() { if span.IsRecordingEvents() {
span.AddAttributes( span.AddAttributes(
trace.StringAttribute("tipset", fmt.Sprint(tipset)), trace.StringAttribute("tipset", fmt.Sprint(tsk.Cids())),
trace.Int64Attribute("count", int64(count)), trace.Int64Attribute("count", int64(count)),
) )
} }
req := &BlockSyncRequest{ req := &BlockSyncRequest{
Start: tipset, Start: tsk.Cids(),
RequestLength: uint64(count), RequestLength: uint64(count),
Options: BSOptBlocks, Options: BSOptBlocks,
} }
@ -94,13 +94,20 @@ func (bs *BlockSync) GetBlocks(ctx context.Context, tipset []cid.Cid, count int)
res, err := bs.sendRequestToPeer(ctx, p, req) res, err := bs.sendRequestToPeer(ctx, p, req)
if err != nil { if err != nil {
oerr = err oerr = err
log.Warnf("BlockSync request failed for peer %s: %s", p.String(), err) if !xerrors.Is(err, inet.ErrNoConn) {
log.Warnf("BlockSync request failed for peer %s: %s", p.String(), err)
}
continue continue
} }
if res.Status == 0 { if res.Status == 0 {
resp, err := bs.processBlocksResponse(req, res)
if err != nil {
return nil, xerrors.Errorf("success response from peer failed to process: %w", err)
}
bs.syncPeers.logGlobalSuccess(time.Since(start)) bs.syncPeers.logGlobalSuccess(time.Since(start))
return bs.processBlocksResponse(req, res) bs.host.ConnManager().TagPeer(p, "bsync", 25)
return resp, nil
} }
oerr = bs.processStatus(req, res) oerr = bs.processStatus(req, res)
if oerr != nil { if oerr != nil {
@ -110,11 +117,11 @@ func (bs *BlockSync) GetBlocks(ctx context.Context, tipset []cid.Cid, count int)
return nil, xerrors.Errorf("GetBlocks failed with all peers: %w", oerr) return nil, xerrors.Errorf("GetBlocks failed with all peers: %w", oerr)
} }
func (bs *BlockSync) GetFullTipSet(ctx context.Context, p peer.ID, h []cid.Cid) (*store.FullTipSet, error) { func (bs *BlockSync) GetFullTipSet(ctx context.Context, p peer.ID, tsk types.TipSetKey) (*store.FullTipSet, error) {
// TODO: round robin through these peers on error // TODO: round robin through these peers on error
req := &BlockSyncRequest{ req := &BlockSyncRequest{
Start: h, Start: tsk.Cids(),
RequestLength: 1, RequestLength: 1,
Options: BSOptBlocks | BSOptMessages, Options: BSOptBlocks | BSOptMessages,
} }
@ -262,6 +269,10 @@ func (bs *BlockSync) sendRequestToPeer(ctx context.Context, p peer.ID, req *Bloc
} }
func (bs *BlockSync) processBlocksResponse(req *BlockSyncRequest, res *BlockSyncResponse) ([]*types.TipSet, error) { func (bs *BlockSync) processBlocksResponse(req *BlockSyncRequest, res *BlockSyncResponse) ([]*types.TipSet, error) {
if len(res.Chain) == 0 {
return nil, xerrors.Errorf("got no blocks in successful blocksync response")
}
cur, err := types.NewTipSet(res.Chain[0].Blocks) cur, err := types.NewTipSet(res.Chain[0].Blocks)
if err != nil { if err != nil {
return nil, err return nil, err
@ -275,7 +286,7 @@ func (bs *BlockSync) processBlocksResponse(req *BlockSyncRequest, res *BlockSync
return nil, err return nil, err
} }
if !types.CidArrsEqual(cur.Parents(), nts.Cids()) { if !types.CidArrsEqual(cur.Parents().Cids(), nts.Cids()) {
return nil, fmt.Errorf("parents of tipset[%d] were not tipset[%d]", bi-1, bi) return nil, fmt.Errorf("parents of tipset[%d] were not tipset[%d]", bi-1, bi)
} }

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
) )
@ -24,6 +24,10 @@ func (t *BlockSyncRequest) MarshalCBOR(w io.Writer) error {
} }
// t.Start ([]cid.Cid) (slice) // t.Start ([]cid.Cid) (slice)
if len(t.Start) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Start was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Start)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Start)))); err != nil {
return err return err
} }
@ -119,6 +123,10 @@ func (t *BlockSyncResponse) MarshalCBOR(w io.Writer) error {
} }
// t.Chain ([]*blocksync.BSTipSet) (slice) // t.Chain ([]*blocksync.BSTipSet) (slice)
if len(t.Chain) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Chain was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Chain)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Chain)))); err != nil {
return err return err
} }
@ -134,6 +142,10 @@ func (t *BlockSyncResponse) MarshalCBOR(w io.Writer) error {
} }
// t.Message (string) (string) // t.Message (string) (string)
if len(t.Message) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.Message was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Message)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Message)))); err != nil {
return err return err
} }
@ -218,6 +230,10 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
} }
// t.Blocks ([]*types.BlockHeader) (slice) // t.Blocks ([]*types.BlockHeader) (slice)
if len(t.Blocks) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Blocks was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Blocks)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Blocks)))); err != nil {
return err return err
} }
@ -228,6 +244,10 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
} }
// t.BlsMessages ([]*types.Message) (slice) // t.BlsMessages ([]*types.Message) (slice)
if len(t.BlsMessages) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.BlsMessages was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.BlsMessages)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.BlsMessages)))); err != nil {
return err return err
} }
@ -238,10 +258,18 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
} }
// t.BlsMsgIncludes ([][]uint64) (slice) // t.BlsMsgIncludes ([][]uint64) (slice)
if len(t.BlsMsgIncludes) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.BlsMsgIncludes was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.BlsMsgIncludes)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.BlsMsgIncludes)))); err != nil {
return err return err
} }
for _, v := range t.BlsMsgIncludes { for _, v := range t.BlsMsgIncludes {
if len(v) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field v was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(v)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(v)))); err != nil {
return err return err
} }
@ -253,6 +281,10 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
} }
// t.SecpkMessages ([]*types.SignedMessage) (slice) // t.SecpkMessages ([]*types.SignedMessage) (slice)
if len(t.SecpkMessages) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.SecpkMessages was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.SecpkMessages)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.SecpkMessages)))); err != nil {
return err return err
} }
@ -263,10 +295,18 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
} }
// t.SecpkMsgIncludes ([][]uint64) (slice) // t.SecpkMsgIncludes ([][]uint64) (slice)
if len(t.SecpkMsgIncludes) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.SecpkMsgIncludes was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.SecpkMsgIncludes)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.SecpkMsgIncludes)))); err != nil {
return err return err
} }
for _, v := range t.SecpkMsgIncludes { for _, v := range t.SecpkMsgIncludes {
if len(v) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field v was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(v)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(v)))); err != nil {
return err return err
} }

View File

@ -202,6 +202,10 @@ func (t *Response) MarshalCBOR(w io.Writer) error {
} }
// t.Message (string) (string) // t.Message (string) (string)
if len(t.Message) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.Message was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Message)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Message)))); err != nil {
return err return err
} }
@ -408,6 +412,10 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error {
} }
// t.MinerID (peer.ID) (string) // t.MinerID (peer.ID) (string)
if len(t.MinerID) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.MinerID was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.MinerID)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.MinerID)))); err != nil {
return err return err
} }
@ -539,6 +547,10 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error {
} }
// t.Miner (peer.ID) (string) // t.Miner (peer.ID) (string)
if len(t.Miner) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.Miner was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Miner)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Miner)))); err != nil {
return err return err
} }
@ -672,6 +684,10 @@ func (t *MinerDeal) MarshalCBOR(w io.Writer) error {
} }
// t.Client (peer.ID) (string) // t.Client (peer.ID) (string)
if len(t.Client) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.Client was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Client)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Client)))); err != nil {
return err return err
} }

View File

@ -10,17 +10,17 @@ import (
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/market" "github.com/filecoin-project/lotus/chain/market"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/statestore"
"github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/node/impl/full"
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/retrieval/discovery" "github.com/filecoin-project/lotus/retrieval/discovery"
@ -259,7 +259,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro
func (c *Client) QueryAsk(ctx context.Context, p peer.ID, a address.Address) (*types.SignedStorageAsk, error) { func (c *Client) QueryAsk(ctx context.Context, p peer.ID, a address.Address) (*types.SignedStorageAsk, error) {
s, err := c.h.NewStream(ctx, p, AskProtocolID) s, err := c.h.NewStream(ctx, p, AskProtocolID)
if err != nil { if err != nil {
return nil, err return nil, xerrors.Errorf("failed to open stream to miner: %w", err)
} }
req := &AskRequest{ req := &AskRequest{

View File

@ -6,12 +6,12 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
) )
type clientHandlerFunc func(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error) type clientHandlerFunc func(ctx context.Context, deal ClientDeal) (func(*ClientDeal), error)

View File

@ -5,6 +5,7 @@ import (
"context" "context"
"runtime" "runtime"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
files "github.com/ipfs/go-ipfs-files" files "github.com/ipfs/go-ipfs-files"
unixfile "github.com/ipfs/go-unixfs/file" unixfile "github.com/ipfs/go-unixfs/file"
@ -12,11 +13,11 @@ import (
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"golang.org/x/xerrors" "golang.org/x/xerrors"
cborutil "github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/lotus/datatransfer" "github.com/filecoin-project/lotus/datatransfer"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/padreader"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
"github.com/filecoin-project/lotus/lib/statestore"
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
) )

View File

@ -12,13 +12,13 @@ import (
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/datatransfer" "github.com/filecoin-project/lotus/datatransfer"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/statestore"
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/storage" "github.com/filecoin-project/lotus/storage"
"github.com/filecoin-project/lotus/storage/sectorblocks" "github.com/filecoin-project/lotus/storage/sectorblocks"

View File

@ -5,10 +5,10 @@ import (
"context" "context"
"time" "time"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
datastore "github.com/ipfs/go-datastore" datastore "github.com/ipfs/go-datastore"
inet "github.com/libp2p/go-libp2p-core/network" inet "github.com/libp2p/go-libp2p-core/network"
"golang.org/x/xerrors" "golang.org/x/xerrors"

View File

@ -10,11 +10,11 @@ import (
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/statestore"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
inet "github.com/libp2p/go-libp2p-core/network" inet "github.com/libp2p/go-libp2p-core/network"

View File

@ -13,13 +13,13 @@ import (
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/deals" "github.com/filecoin-project/lotus/chain/deals"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/statestore"
) )
var blockGenerator = blocksutil.NewBlockGenerator() var blockGenerator = blocksutil.NewBlockGenerator()

View File

@ -4,11 +4,11 @@ import (
"bytes" "bytes"
"errors" "errors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
) )

View File

@ -9,9 +9,9 @@ import (
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -13,8 +13,8 @@ import (
"github.com/multiformats/go-multihash" "github.com/multiformats/go-multihash"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -6,7 +6,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -11,6 +11,7 @@ import (
ffi "github.com/filecoin-project/filecoin-ffi" ffi "github.com/filecoin-project/filecoin-ffi"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/ipfs/go-blockservice" "github.com/ipfs/go-blockservice"
"github.com/ipfs/go-car" "github.com/ipfs/go-car"
offline "github.com/ipfs/go-ipfs-exchange-offline" offline "github.com/ipfs/go-ipfs-exchange-offline"
@ -19,16 +20,15 @@ import (
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed" "github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
"github.com/filecoin-project/lotus/genesis" "github.com/filecoin-project/lotus/genesis"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
block "github.com/ipfs/go-block-format" block "github.com/ipfs/go-block-format"

View File

@ -10,7 +10,7 @@ import (
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"

View File

@ -15,9 +15,9 @@ import (
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
actors "github.com/filecoin-project/lotus/chain/actors" actors "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"

View File

@ -6,8 +6,8 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/node/impl/full"

View File

@ -19,9 +19,9 @@ import (
"go.uber.org/multierr" "go.uber.org/multierr"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -109,7 +109,7 @@ type Provider interface {
StateGetActor(address.Address, *types.TipSet) (*types.Actor, error) StateGetActor(address.Address, *types.TipSet) (*types.Actor, error)
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
MessagesForTipset(*types.TipSet) ([]store.ChainMsg, error) MessagesForTipset(*types.TipSet) ([]store.ChainMsg, error)
LoadTipSet(cids []cid.Cid) (*types.TipSet, error) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
} }
type mpoolProvider struct { type mpoolProvider struct {
@ -146,8 +146,8 @@ func (mpp *mpoolProvider) MessagesForTipset(ts *types.TipSet) ([]store.ChainMsg,
return mpp.sm.ChainStore().MessagesForTipset(ts) return mpp.sm.ChainStore().MessagesForTipset(ts)
} }
func (mpp *mpoolProvider) LoadTipSet(cids []cid.Cid) (*types.TipSet, error) { func (mpp *mpoolProvider) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
return mpp.sm.ChainStore().LoadTipSet(cids) return mpp.sm.ChainStore().LoadTipSet(tsk)
} }
func New(api Provider, ds dtypes.MetadataDS) (*MessagePool, error) { func New(api Provider, ds dtypes.MetadataDS) (*MessagePool, error) {
@ -263,24 +263,24 @@ func (mp *MessagePool) addLocal(m *types.SignedMessage, msgb []byte) error {
return nil return nil
} }
func (mp *MessagePool) Push(m *types.SignedMessage) error { func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
msgb, err := m.Serialize() msgb, err := m.Serialize()
if err != nil { if err != nil {
return err return cid.Undef, err
} }
if err := mp.Add(m); err != nil { if err := mp.Add(m); err != nil {
return err return cid.Undef, err
} }
mp.lk.Lock() mp.lk.Lock()
if err := mp.addLocal(m, msgb); err != nil { if err := mp.addLocal(m, msgb); err != nil {
mp.lk.Unlock() mp.lk.Unlock()
return err return cid.Undef, err
} }
mp.lk.Unlock() mp.lk.Unlock()
return mp.api.PubSubPublish(msgTopic, msgb) return m.Cid(), mp.api.PubSubPublish(msgTopic, msgb)
} }
func (mp *MessagePool) Add(m *types.SignedMessage) error { func (mp *MessagePool) Add(m *types.SignedMessage) error {

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/types/mock"
@ -98,9 +98,9 @@ func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]store.ChainMsg,
return out, nil return out, nil
} }
func (tma *testMpoolApi) LoadTipSet(cids []cid.Cid) (*types.TipSet, error) { func (tma *testMpoolApi) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
for _, ts := range tma.tipsets { for _, ts := range tma.tipsets {
if types.CidArrsEqual(cids, ts.Cids()) { if types.CidArrsEqual(tsk.Cids(), ts.Cids()) {
return ts, nil return ts, nil
} }
} }

View File

@ -9,8 +9,8 @@ import (
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -3,8 +3,8 @@ package state
import ( import (
"testing" "testing"
address "github.com/filecoin-project/go-address"
actors "github.com/filecoin-project/lotus/chain/actors" actors "github.com/filecoin-project/lotus/chain/actors"
address "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
) )

View File

@ -0,0 +1,127 @@
package stmgr
import (
"context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-amt-ipld"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-hamt-ipld"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
)
func (sm *StateManager) forkNoPowerEPS(ctx context.Context, pstate cid.Cid) (cid.Cid, error) {
cst := hamt.CSTFromBstore(sm.cs.Blockstore())
st, err := state.LoadStateTree(cst, pstate)
if err != nil {
return cid.Undef, xerrors.Errorf("loading parent state tree: %w", err)
}
if err := st.MutateActor(actors.StoragePowerAddress, func(spa *types.Actor) error {
var head actors.StoragePowerState
if err := cst.Get(ctx, spa.Head, &head); err != nil {
return xerrors.Errorf("reading StoragePower state: %w", err)
}
buckets, err := amt.LoadAMT(amt.WrapBlockstore(sm.cs.Blockstore()), head.ProvingBuckets)
if err != nil {
return xerrors.Errorf("opening proving buckets AMT: %w", err)
}
fixedBuckets := map[uint64]map[address.Address]struct{}{}
if err := buckets.ForEach(func(bucketId uint64, ent *typegen.Deferred) error {
var bcid cid.Cid
if err := cbor.DecodeInto(ent.Raw, &bcid); err != nil {
return xerrors.Errorf("decoding bucket cid: %w", err)
}
bucket, err := hamt.LoadNode(ctx, cst, bcid)
if err != nil {
return xerrors.Errorf("loading bucket hamt: %w", err)
}
return bucket.ForEach(ctx, func(abytes string, _ interface{}) error {
addr, err := address.NewFromBytes([]byte(abytes))
if err != nil {
return xerrors.Errorf("parsing address in proving bucket: %w", err)
}
// now find the correct bucket
miner, err := st.GetActor(addr)
if err != nil {
return xerrors.Errorf("getting miner %s: %w", addr, err)
}
var minerHead actors.StorageMinerActorState
if err := cst.Get(ctx, miner.Head, &minerHead); err != nil {
return xerrors.Errorf("reading miner %s state: %w", addr, err)
}
correctBucket := minerHead.ElectionPeriodStart % build.SlashablePowerDelay
if correctBucket != bucketId {
log.Warnf("miner %s was in wrong proving bucket %d, putting in %d (eps: %d)", addr, bucketId, correctBucket, minerHead.ElectionPeriodStart)
}
if _, ok := fixedBuckets[correctBucket]; !ok {
fixedBuckets[correctBucket] = map[address.Address]struct{}{}
}
fixedBuckets[correctBucket][addr] = struct{}{}
return nil
})
}); err != nil {
return err
}
// /////
// Write fixed buckets
fixed := amt.NewAMT(amt.WrapBlockstore(sm.cs.Blockstore()))
for bucketId, addrss := range fixedBuckets {
bucket := hamt.NewNode(cst)
for addr := range addrss {
if err := bucket.Set(ctx, string(addr.Bytes()), actors.CborNull); err != nil {
return xerrors.Errorf("setting address in bucket: %w", err)
}
}
if err := bucket.Flush(ctx); err != nil {
return xerrors.Errorf("flushing bucket amt: %w", err)
}
bcid, err := cst.Put(context.TODO(), bucket)
if err != nil {
return xerrors.Errorf("put bucket: %w", err)
}
if err := fixed.Set(bucketId, bcid); err != nil {
return xerrors.Errorf("set bucket: %w", err)
}
}
head.ProvingBuckets, err = fixed.Flush()
if err != nil {
return xerrors.Errorf("flushing bucket amt: %w", err)
}
spa.Head, err = cst.Put(ctx, &head)
if err != nil {
return xerrors.Errorf("putting actor head: %w", err)
}
return nil
}); err != nil {
return cid.Undef, err
}
return st.Flush()
}

25
chain/stmgr/forks.go Normal file
View File

@ -0,0 +1,25 @@
package stmgr
import (
"context"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build"
)
func (sm *StateManager) handleStateForks(ctx context.Context, pstate cid.Cid, height, parentH uint64) (_ cid.Cid, err error) {
for i := parentH; i < height; i++ {
switch i {
case build.ForkNoPowerEPSUpdates:
pstate, err = sm.forkNoPowerEPS(ctx, pstate)
if err != nil {
return cid.Undef, xerrors.Errorf("executing state fork in epoch %d: %w", i, err)
}
log.Infof("forkNoPowerEPS state: %s", pstate)
}
}
return pstate, nil
}

View File

@ -5,9 +5,9 @@ import (
"fmt" "fmt"
"sync" "sync"
"github.com/filecoin-project/go-address"
amt "github.com/filecoin-project/go-amt-ipld" amt "github.com/filecoin-project/go-amt-ipld"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -120,6 +120,17 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
} }
pstate := blks[0].ParentStateRoot pstate := blks[0].ParentStateRoot
if len(blks[0].Parents) > 0 { // don't support forks on genesis
parent, err := sm.cs.GetBlock(blks[0].Parents[0])
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("getting parent block: %w", err)
}
pstate, err = sm.handleStateForks(ctx, blks[0].ParentStateRoot, blks[0].Height, parent.Height)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
}
}
cids := make([]cid.Cid, len(blks)) cids := make([]cid.Cid, len(blks))
for i, v := range blks { for i, v := range blks {

View File

@ -4,12 +4,13 @@ import (
"context" "context"
ffi "github.com/filecoin-project/filecoin-ffi" ffi "github.com/filecoin-project/filecoin-ffi"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
amt "github.com/filecoin-project/go-amt-ipld" amt "github.com/filecoin-project/go-amt-ipld"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
@ -270,6 +271,21 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *ty
return &ocd, nil return &ocd, nil
} }
func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([]address.Address, error) {
var state actors.StoragePowerState
if _, err := sm.LoadActorState(ctx, actors.StoragePowerAddress, &state, ts); err != nil {
return nil, err
}
cst := hamt.CSTFromBstore(sm.ChainStore().Blockstore())
miners, err := actors.MinerSetList(ctx, cst, state.Miners)
if err != nil {
return nil, err
}
return miners, nil
}
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.ChainSectorInfo, error) { func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.ChainSectorInfo, error) {
blks := amt.WrapBlockstore(bs) blks := amt.WrapBlockstore(bs)
a, err := amt.LoadAMT(blks, ssc) a, err := amt.LoadAMT(blks, ssc)

View File

@ -7,8 +7,8 @@ import (
"encoding/json" "encoding/json"
"sync" "sync"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"go.opencensus.io/trace" "go.opencensus.io/trace"
@ -50,16 +50,19 @@ type ChainStore struct {
headChangeNotifs []func(rev, app []*types.TipSet) error headChangeNotifs []func(rev, app []*types.TipSet) error
mmCache *lru.ARCCache mmCache *lru.ARCCache
tsCache *lru.ARCCache
} }
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore { func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore {
c, _ := lru.NewARC(2048) c, _ := lru.NewARC(2048)
tsc, _ := lru.NewARC(4096)
cs := &ChainStore{ cs := &ChainStore{
bs: bs, bs: bs,
ds: ds, ds: ds,
bestTips: pubsub.New(64), bestTips: pubsub.New(64),
tipsets: make(map[uint64][]cid.Cid), tipsets: make(map[uint64][]cid.Cid),
mmCache: c, mmCache: c,
tsCache: tsc,
} }
cs.reorgCh = cs.reorgWorker(context.TODO()) cs.reorgCh = cs.reorgWorker(context.TODO())
@ -107,7 +110,7 @@ func (cs *ChainStore) Load() error {
return xerrors.Errorf("failed to unmarshal stored chain head: %w", err) return xerrors.Errorf("failed to unmarshal stored chain head: %w", err)
} }
ts, err := cs.LoadTipSet(tscids) ts, err := cs.LoadTipSet(types.NewTipSetKey(tscids...))
if err != nil { if err != nil {
return xerrors.Errorf("loading tipset: %w", err) return xerrors.Errorf("loading tipset: %w", err)
} }
@ -336,9 +339,14 @@ func (cs *ChainStore) GetBlock(c cid.Cid) (*types.BlockHeader, error) {
return types.DecodeBlock(sb.RawData()) return types.DecodeBlock(sb.RawData())
} }
func (cs *ChainStore) LoadTipSet(cids []cid.Cid) (*types.TipSet, error) { func (cs *ChainStore) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
v, ok := cs.tsCache.Get(tsk)
if ok {
return v.(*types.TipSet), nil
}
var blks []*types.BlockHeader var blks []*types.BlockHeader
for _, c := range cids { for _, c := range tsk.Cids() {
b, err := cs.GetBlock(c) b, err := cs.GetBlock(c)
if err != nil { if err != nil {
return nil, xerrors.Errorf("get block %s: %w", c, err) return nil, xerrors.Errorf("get block %s: %w", c, err)
@ -347,7 +355,14 @@ func (cs *ChainStore) LoadTipSet(cids []cid.Cid) (*types.TipSet, error) {
blks = append(blks, b) blks = append(blks, b)
} }
return types.NewTipSet(blks) ts, err := types.NewTipSet(blks)
if err != nil {
return nil, err
}
cs.tsCache.Add(tsk, ts)
return ts, nil
} }
// returns true if 'a' is an ancestor of 'b' // returns true if 'a' is an ancestor of 'b'
@ -817,7 +832,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round i
span.AddAttributes(trace.Int64Attribute("round", round)) span.AddAttributes(trace.Int64Attribute("round", round))
for { for {
nts, err := cs.LoadTipSet(blks) nts, err := cs.LoadTipSet(types.NewTipSetKey(blks...))
if err != nil { if err != nil {
return nil, err return nil, err
} }

68
chain/store/store_test.go Normal file
View File

@ -0,0 +1,68 @@
package store_test
import (
"context"
"testing"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/repo"
blockstore "github.com/ipfs/go-ipfs-blockstore"
)
func init() {
build.SectorSizes = []uint64{1024}
build.MinimumMinerPower = 1024
}
func BenchmarkGetRandomness(b *testing.B) {
cg, err := gen.NewGenerator()
if err != nil {
b.Fatal(err)
}
var last *types.TipSet
for i := 0; i < 2000; i++ {
ts, err := cg.NextTipSet()
if err != nil {
b.Fatal(err)
}
last = ts.TipSet.TipSet()
}
r, err := cg.YieldRepo()
if err != nil {
b.Fatal(err)
}
lr, err := r.Lock(repo.FullNode)
if err != nil {
b.Fatal(err)
}
bds, err := lr.Datastore("/blocks")
if err != nil {
b.Fatal(err)
}
mds, err := lr.Datastore("/metadata")
if err != nil {
b.Fatal(err)
}
bs := blockstore.NewBlockstore(bds)
cs := store.NewChainStore(bs, mds)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := cs.GetRandomness(context.TODO(), last.Cids(), 500)
if err != nil {
b.Fatal(err)
}
}
}

View File

@ -5,6 +5,7 @@ import (
"time" "time"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
connmgr "github.com/libp2p/go-libp2p-core/connmgr"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain"
@ -14,7 +15,7 @@ import (
var log = logging.Logger("sub") var log = logging.Logger("sub")
func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *chain.Syncer) { func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *chain.Syncer, cmgr connmgr.ConnManager) {
for { for {
msg, err := bsub.Next(ctx) msg, err := bsub.Next(ctx)
if err != nil { if err != nil {
@ -54,11 +55,14 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha
if delay := time.Now().Unix() - int64(blk.Header.Timestamp); delay > 5 { if delay := time.Now().Unix() - int64(blk.Header.Timestamp); delay > 5 {
log.Warnf("Received block with large delay %d from miner %s", delay, blk.Header.Miner) log.Warnf("Received block with large delay %d from miner %s", delay, blk.Header.Miner)
} }
s.InformNewBlock(msg.GetFrom(), &types.FullBlock{
if s.InformNewBlock(msg.ReceivedFrom, &types.FullBlock{
Header: blk.Header, Header: blk.Header,
BlsMessages: bmsgs, BlsMessages: bmsgs,
SecpkMessages: smsgs, SecpkMessages: smsgs,
}) }) {
cmgr.TagPeer(msg.ReceivedFrom, "blkprop", 5)
}
}() }()
} }
} }

View File

@ -6,34 +6,37 @@ import (
"crypto/sha256" "crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"sync"
"time" "time"
"github.com/Gurpartap/async" "github.com/Gurpartap/async"
bls "github.com/filecoin-project/filecoin-ffi" bls "github.com/filecoin-project/filecoin-ffi"
amt "github.com/filecoin-project/go-amt-ipld" amt "github.com/filecoin-project/go-amt-ipld"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore" dstore "github.com/ipfs/go-datastore"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore" bstore "github.com/ipfs/go-ipfs-blockstore"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/libp2p/go-libp2p-core/connmgr"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"github.com/whyrusleeping/pubsub" "github.com/whyrusleeping/pubsub"
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/blocksync" "github.com/filecoin-project/lotus/chain/blocksync"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
) )
var log = logging.Logger("chain") var log = logging.Logger("chain")
@ -41,8 +44,6 @@ var log = logging.Logger("chain")
var LocalIncoming = "incoming" var LocalIncoming = "incoming"
type Syncer struct { type Syncer struct {
// The heaviest known tipset in the network.
// The interface for accessing and putting tipsets into local storage // The interface for accessing and putting tipsets into local storage
store *store.ChainStore store *store.ChainStore
@ -62,10 +63,14 @@ type Syncer struct {
syncmgr *SyncManager syncmgr *SyncManager
connmgr connmgr.ConnManager
incoming *pubsub.PubSub incoming *pubsub.PubSub
receiptTracker *blockReceiptTracker
} }
func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, self peer.ID) (*Syncer, error) { func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID) (*Syncer, error) {
gen, err := sm.ChainStore().GetGenesis() gen, err := sm.ChainStore().GetGenesis()
if err != nil { if err != nil {
return nil, err return nil, err
@ -77,12 +82,14 @@ func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, self peer.ID)
} }
s := &Syncer{ s := &Syncer{
bad: NewBadBlockCache(), bad: NewBadBlockCache(),
Genesis: gent, Genesis: gent,
Bsync: bsync, Bsync: bsync,
store: sm.ChainStore(), store: sm.ChainStore(),
sm: sm, sm: sm,
self: self, self: self,
receiptTracker: newBlockReceiptTracker(),
connmgr: connmgr,
incoming: pubsub.New(50), incoming: pubsub.New(50),
} }
@ -102,17 +109,17 @@ func (syncer *Syncer) Stop() {
// InformNewHead informs the syncer about a new potential tipset // InformNewHead informs the syncer about a new potential tipset
// This should be called when connecting to new peers, and additionally // This should be called when connecting to new peers, and additionally
// when receiving new blocks from the network // when receiving new blocks from the network
func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) { func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
ctx := context.Background() ctx := context.Background()
if fts == nil { if fts == nil {
log.Errorf("got nil tipset in InformNewHead") log.Errorf("got nil tipset in InformNewHead")
return return false
} }
for _, b := range fts.Blocks { for _, b := range fts.Blocks {
if err := syncer.ValidateMsgMeta(b); err != nil { if err := syncer.ValidateMsgMeta(b); err != nil {
log.Warnf("invalid block received: %s", err) log.Warnf("invalid block received: %s", err)
return return false
} }
} }
@ -124,16 +131,17 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
if err := syncer.Sync(ctx, fts.TipSet()); err != nil { if err := syncer.Sync(ctx, fts.TipSet()); err != nil {
log.Errorf("failed to sync our own block %s: %+v", fts.TipSet().Cids(), err) log.Errorf("failed to sync our own block %s: %+v", fts.TipSet().Cids(), err)
return false
} }
return return true
} }
// TODO: IMPORTANT(GARBAGE) this needs to be put in the 'temporary' side of // TODO: IMPORTANT(GARBAGE) this needs to be put in the 'temporary' side of
// the blockstore // the blockstore
if err := syncer.store.PersistBlockHeaders(fts.TipSet().Blocks()...); err != nil { if err := syncer.store.PersistBlockHeaders(fts.TipSet().Blocks()...); err != nil {
log.Warn("failed to persist incoming block header: ", err) log.Warn("failed to persist incoming block header: ", err)
return return false
} }
syncer.Bsync.AddPeer(from) syncer.Bsync.AddPeer(from)
@ -145,11 +153,12 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
for _, blk := range fts.TipSet().Blocks() { for _, blk := range fts.TipSet().Blocks() {
miners = append(miners, blk.Miner.String()) miners = append(miners, blk.Miner.String())
} }
log.Warnf("incoming tipset from %s does not appear to be better than our best chain, ignoring for now", miners) log.Infof("incoming tipset from %s does not appear to be better than our best chain, ignoring for now", miners)
return return false
} }
syncer.syncmgr.SetPeerHead(ctx, from, fts.TipSet()) syncer.syncmgr.SetPeerHead(ctx, from, fts.TipSet())
return true
} }
func (syncer *Syncer) IncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) { func (syncer *Syncer) IncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) {
@ -231,12 +240,12 @@ func (syncer *Syncer) ChainStore() *store.ChainStore {
return syncer.store return syncer.store
} }
func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) { func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) bool {
// TODO: search for other blocks that could form a tipset with this block // TODO: search for other blocks that could form a tipset with this block
// and then send that tipset to InformNewHead // and then send that tipset to InformNewHead
fts := &store.FullTipSet{Blocks: []*types.FullBlock{blk}} fts := &store.FullTipSet{Blocks: []*types.FullBlock{blk}}
syncer.InformNewHead(from, fts) return syncer.InformNewHead(from, fts)
} }
func copyBlockstore(from, to bstore.Blockstore) error { func copyBlockstore(from, to bstore.Blockstore) error {
@ -329,16 +338,16 @@ func computeMsgMeta(bs amt.Blocks, bmsgCids, smsgCids []cbg.CBORMarshaler) (cid.
return mrcid, nil return mrcid, nil
} }
func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, cids []cid.Cid) (*store.FullTipSet, error) { func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, tsk types.TipSetKey) (*store.FullTipSet, error) {
if fts, err := syncer.tryLoadFullTipSet(cids); err == nil { if fts, err := syncer.tryLoadFullTipSet(tsk); err == nil {
return fts, nil return fts, nil
} }
return syncer.Bsync.GetFullTipSet(ctx, p, cids) return syncer.Bsync.GetFullTipSet(ctx, p, tsk)
} }
func (syncer *Syncer) tryLoadFullTipSet(cids []cid.Cid) (*store.FullTipSet, error) { func (syncer *Syncer) tryLoadFullTipSet(tsk types.TipSetKey) (*store.FullTipSet, error) {
ts, err := syncer.store.LoadTipSet(cids) ts, err := syncer.store.LoadTipSet(tsk)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -398,6 +407,15 @@ func (syncer *Syncer) Sync(ctx context.Context, maybeHead *types.TipSet) error {
return xerrors.Errorf("failed to put synced tipset to chainstore: %w", err) return xerrors.Errorf("failed to put synced tipset to chainstore: %w", err)
} }
peers := syncer.receiptTracker.GetPeers(maybeHead)
if len(peers) > 0 {
syncer.connmgr.TagPeer(peers[0], "new-block", 40)
for _, p := range peers[1:] {
syncer.connmgr.TagPeer(p, "new-block", 25)
}
}
return nil return nil
} }
@ -409,6 +427,8 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
ctx, span := trace.StartSpan(ctx, "validateTipSet") ctx, span := trace.StartSpan(ctx, "validateTipSet")
defer span.End() defer span.End()
span.AddAttributes(trace.Int64Attribute("height", int64(fts.TipSet().Height())))
ts := fts.TipSet() ts := fts.TipSet()
if ts.Equals(syncer.Genesis) { if ts.Equals(syncer.Genesis) {
return nil return nil
@ -469,7 +489,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
h := b.Header h := b.Header
baseTs, err := syncer.store.LoadTipSet(h.Parents) baseTs, err := syncer.store.LoadTipSet(types.NewTipSetKey(h.Parents...))
if err != nil { if err != nil {
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err) return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
} }
@ -480,7 +500,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
} }
if h.Timestamp > uint64(time.Now().Unix()+build.AllowableClockDrift) { if h.Timestamp > uint64(time.Now().Unix()+build.AllowableClockDrift) {
return xerrors.Errorf("block was from the future") return xerrors.Errorf("block was from the future: %w", ErrTemporal)
} }
if h.Timestamp > uint64(time.Now().Unix()) { if h.Timestamp > uint64(time.Now().Unix()) {
log.Warn("Got block from the future, but within threshold", h.Timestamp, time.Now().Unix()) log.Warn("Got block from the future, but within threshold", h.Timestamp, time.Now().Unix())
@ -676,6 +696,26 @@ func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.Bloc
} }
func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock, baseTs *types.TipSet) error { func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock, baseTs *types.TipSet) error {
{
var sigCids []cid.Cid // this is what we get for people not wanting the marshalcbor method on the cid type
var pubks []bls.PublicKey
for _, m := range b.BlsMessages {
sigCids = append(sigCids, m.Cid())
pubk, err := syncer.sm.GetBlsPublicKey(ctx, m.From, baseTs)
if err != nil {
return xerrors.Errorf("failed to load bls public to validate block: %w", err)
}
pubks = append(pubks, pubk)
}
if err := syncer.verifyBlsAggregate(ctx, b.Header.BLSAggregate, sigCids, pubks); err != nil {
return xerrors.Errorf("bls aggregate signature was invalid: %w", err)
}
}
nonces := make(map[address.Address]uint64) nonces := make(map[address.Address]uint64)
balances := make(map[address.Address]types.BigInt) balances := make(map[address.Address]types.BigInt)
@ -719,28 +759,14 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
bs := amt.WrapBlockstore(syncer.store.Blockstore()) bs := amt.WrapBlockstore(syncer.store.Blockstore())
var blsCids []cbg.CBORMarshaler var blsCids []cbg.CBORMarshaler
var sigCids []cid.Cid // this is what we get for people not wanting the marshalcbor method on the cid type
var pubks []bls.PublicKey
for i, m := range b.BlsMessages { for i, m := range b.BlsMessages {
if err := checkMsg(m); err != nil { if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err) return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
} }
sigCids = append(sigCids, m.Cid())
c := cbg.CborCid(m.Cid()) c := cbg.CborCid(m.Cid())
blsCids = append(blsCids, &c) blsCids = append(blsCids, &c)
pubk, err := syncer.sm.GetBlsPublicKey(ctx, m.From, baseTs)
if err != nil {
return xerrors.Errorf("failed to load bls public to validate block: %w", err)
}
pubks = append(pubks, pubk)
}
if err := syncer.verifyBlsAggregate(ctx, b.Header.BLSAggregate, sigCids, pubks); err != nil {
return xerrors.Errorf("bls aggregate signature was invalid: %w", err)
} }
var secpkCids []cbg.CBORMarshaler var secpkCids []cbg.CBORMarshaler
@ -794,10 +820,19 @@ func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig types.Signatur
trace.Int64Attribute("msgCount", int64(len(msgs))), trace.Int64Attribute("msgCount", int64(len(msgs))),
) )
var digests []bls.Digest var wg sync.WaitGroup
for _, c := range msgs {
digests = append(digests, bls.Hash(bls.Message(c.Bytes()))) 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)
} }
wg.Wait()
var bsig bls.Signature var bsig bls.Signature
copy(bsig[:], sig.Data) copy(bsig[:], sig.Data)
@ -828,7 +863,7 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
trace.Int64Attribute("toHeight", int64(to.Height())), trace.Int64Attribute("toHeight", int64(to.Height())),
) )
for _, pcid := range from.Parents() { for _, pcid := range from.Parents().Cids() {
if syncer.bad.Has(pcid) { if syncer.bad.Has(pcid) {
for _, b := range from.Cids() { for _, b := range from.Cids() {
syncer.bad.Add(b) syncer.bad.Add(b)
@ -850,7 +885,7 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
loop: loop:
for blockSet[len(blockSet)-1].Height() > untilHeight { for blockSet[len(blockSet)-1].Height() > untilHeight {
for _, bc := range at { for _, bc := range at.Cids() {
if syncer.bad.Has(bc) { if syncer.bad.Has(bc) {
for _, b := range acceptedBlocks { for _, b := range acceptedBlocks {
syncer.bad.Add(b) syncer.bad.Add(b)
@ -863,7 +898,7 @@ loop:
// If, for some reason, we have a suffix of the chain locally, handle that here // If, for some reason, we have a suffix of the chain locally, handle that here
ts, err := syncer.store.LoadTipSet(at) ts, err := syncer.store.LoadTipSet(at)
if err == nil { if err == nil {
acceptedBlocks = append(acceptedBlocks, at...) acceptedBlocks = append(acceptedBlocks, at.Cids()...)
blockSet = append(blockSet, ts) blockSet = append(blockSet, ts)
at = ts.Parents() at = ts.Parents()
@ -910,16 +945,16 @@ loop:
blockSet = append(blockSet, b) blockSet = append(blockSet, b)
} }
acceptedBlocks = append(acceptedBlocks, at...) acceptedBlocks = append(acceptedBlocks, at.Cids()...)
ss.SetHeight(blks[len(blks)-1].Height()) ss.SetHeight(blks[len(blks)-1].Height())
at = blks[len(blks)-1].Parents() at = blks[len(blks)-1].Parents()
} }
// We have now ascertained that this is *not* a 'fast forward' // We have now ascertained that this is *not* a 'fast forward'
if !types.CidArrsEqual(blockSet[len(blockSet)-1].Parents(), to.Cids()) { if !types.CidArrsEqual(blockSet[len(blockSet)-1].Parents().Cids(), to.Cids()) {
last := blockSet[len(blockSet)-1] last := blockSet[len(blockSet)-1]
if types.CidArrsEqual(last.Parents(), to.Parents()) { if last.Parents() == to.Parents() {
// common case: receiving a block thats potentially part of the same tipset as our best block // common case: receiving a block thats potentially part of the same tipset as our best block
return blockSet, nil return blockSet, nil
} }
@ -1002,6 +1037,8 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
ctx, span := trace.StartSpan(ctx, "iterFullTipsets") ctx, span := trace.StartSpan(ctx, "iterFullTipsets")
defer span.End() defer span.End()
span.AddAttributes(trace.Int64Attribute("num_headers", int64(len(headers))))
windowSize := 200 windowSize := 200
for i := len(headers) - 1; i >= 0; { for i := len(headers) - 1; i >= 0; {
fts, err := syncer.store.TryFillTipSet(headers[i]) fts, err := syncer.store.TryFillTipSet(headers[i])
@ -1144,3 +1181,7 @@ func (syncer *Syncer) State() []SyncerState {
} }
return out return out
} }
func (syncer *Syncer) MarkBad(blk cid.Cid) {
syncer.bad.Add(blk)
}

View File

@ -197,10 +197,10 @@ func (stb *syncTargetBucket) sameChainAs(ts *types.TipSet) bool {
if ts.Equals(t) { if ts.Equals(t) {
return true return true
} }
if types.CidArrsEqual(ts.Cids(), t.Parents()) { if ts.Key() == t.Parents() {
return true return true
} }
if types.CidArrsEqual(ts.Parents(), t.Cids()) { if ts.Parents() == t.Key() {
return true return true
} }
} }
@ -293,7 +293,7 @@ func (sm *SyncManager) scheduleIncoming(ts *types.TipSet) {
break break
} }
if types.CidArrsEqual(ts.Parents(), acts.Cids()) { if ts.Parents() == acts.Key() {
// sync this next, after that sync process finishes // sync this next, after that sync process finishes
relatedToActiveSync = true relatedToActiveSync = true
} }

View File

@ -12,9 +12,9 @@ import (
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"

View File

@ -1,7 +1,7 @@
package types package types
import ( import (
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
) )

View File

@ -124,6 +124,22 @@ func (bi *BigInt) UnmarshalJSON(b []byte) error {
return nil return nil
} }
var sizeUnits = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"}
func (bi BigInt) SizeStr() string {
r := new(big.Rat).SetInt(bi.Int)
den := big.NewRat(1, 1024)
var i int
for f, _ := r.Float64(); f >= 1024 && i+1 < len(sizeUnits); f, _ = r.Float64() {
i++
r = r.Mul(r, den)
}
f, _ := r.Float64()
return fmt.Sprintf("%.3g %s", f, sizeUnits[i])
}
func (bi *BigInt) Scan(value interface{}) error { func (bi *BigInt) Scan(value interface{}) error {
switch value := value.(type) { switch value := value.(type) {
case string: case string:

View File

@ -2,7 +2,10 @@ package types
import ( import (
"bytes" "bytes"
"math/big"
"testing" "testing"
"github.com/stretchr/testify/assert"
) )
func TestBigIntSerializationRoundTrip(t *testing.T) { func TestBigIntSerializationRoundTrip(t *testing.T) {
@ -49,3 +52,29 @@ func TestFilRoundTrip(t *testing.T) {
} }
} }
} }
func TestSizeStr(t *testing.T) {
cases := []struct {
in uint64
out string
}{
{0, "0 B"},
{1, "1 B"},
{1024, "1 KiB"},
{2000, "1.95 KiB"},
{5 << 20, "5 MiB"},
{11 << 60, "11 EiB"},
}
for _, c := range cases {
assert.Equal(t, c.out, NewInt(c.in).SizeStr(), "input %+v, produced wrong result", c)
}
}
func TestSizeStrBig(t *testing.T) {
ZiB := big.NewInt(50000)
ZiB = ZiB.Lsh(ZiB, 70)
assert.Equal(t, "5e+04 ZiB", BigInt{Int: ZiB}.SizeStr(), "inout %+v, produced wrong result", ZiB)
}

View File

@ -156,6 +156,10 @@ func (bf BitField) MarshalCBOR(w io.Writer) error {
return err return err
} }
if len(rle) > 8192 {
return xerrors.Errorf("encoded bitfield was too large (%d)", len(rle))
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(rle)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(rle)))); err != nil {
return err return err
} }

View File

@ -5,6 +5,8 @@ import (
"context" "context"
"math/big" "math/big"
"github.com/filecoin-project/go-sectorbuilder"
block "github.com/ipfs/go-block-format" block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/minio/sha256-simd" "github.com/minio/sha256-simd"
@ -12,8 +14,9 @@ import (
"go.opencensus.io/trace" "go.opencensus.io/trace"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
) )
type Ticket struct { type Ticket struct {
@ -176,7 +179,7 @@ const sha256bits = 256
func IsTicketWinner(partialTicket []byte, ssizeI uint64, snum uint64, totpow BigInt) bool { func IsTicketWinner(partialTicket []byte, ssizeI uint64, snum uint64, totpow BigInt) bool {
ssize := NewInt(ssizeI) ssize := NewInt(ssizeI)
ssampled := ElectionPostChallengeCount(snum) ssampled := ElectionPostChallengeCount(snum, 0) // TODO: faults in epost?
/* /*
Need to check that Need to check that
(h(vrfout) + 1) / (max(h) + 1) <= e * sectorSize / totalPower (h(vrfout) + 1) / (max(h) + 1) <= e * sectorSize / totalPower
@ -213,12 +216,8 @@ func IsTicketWinner(partialTicket []byte, ssizeI uint64, snum uint64, totpow Big
return lhs.Cmp(rhs) < 0 return lhs.Cmp(rhs) < 0
} }
func ElectionPostChallengeCount(sectors uint64) uint64 { func ElectionPostChallengeCount(sectors uint64, faults int) uint64 {
if sectors == 0 { return sectorbuilder.ElectionPostChallengeCount(sectors, faults)
return 0
}
// ceil(sectors / build.SectorChallengeRatioDiv)
return (sectors-1)/build.SectorChallengeRatioDiv + 1
} }
func (t *Ticket) Equals(ot *Ticket) bool { func (t *Ticket) Equals(ot *Ticket) bool {

View File

@ -6,7 +6,7 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
) )

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"math" "math"
"github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
) )
@ -39,6 +39,10 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
} }
// t.Parents ([]cid.Cid) (slice) // t.Parents ([]cid.Cid) (slice)
if len(t.Parents) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Parents was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Parents)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Parents)))); err != nil {
return err return err
} }
@ -281,6 +285,10 @@ func (t *Ticket) MarshalCBOR(w io.Writer) error {
} }
// t.VRFProof ([]uint8) (slice) // t.VRFProof ([]uint8) (slice)
if len(t.VRFProof) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.VRFProof was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.VRFProof)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.VRFProof)))); err != nil {
return err return err
} }
@ -335,6 +343,10 @@ func (t *EPostProof) MarshalCBOR(w io.Writer) error {
} }
// t.Proof ([]uint8) (slice) // t.Proof ([]uint8) (slice)
if len(t.Proof) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Proof was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
return err return err
} }
@ -343,6 +355,10 @@ func (t *EPostProof) MarshalCBOR(w io.Writer) error {
} }
// t.PostRand ([]uint8) (slice) // t.PostRand ([]uint8) (slice)
if len(t.PostRand) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.PostRand was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PostRand)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PostRand)))); err != nil {
return err return err
} }
@ -351,6 +367,10 @@ func (t *EPostProof) MarshalCBOR(w io.Writer) error {
} }
// t.Candidates ([]types.EPostTicket) (slice) // t.Candidates ([]types.EPostTicket) (slice)
if len(t.Candidates) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Candidates was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil {
return err return err
} }
@ -451,6 +471,10 @@ func (t *EPostTicket) MarshalCBOR(w io.Writer) error {
} }
// t.Partial ([]uint8) (slice) // t.Partial ([]uint8) (slice)
if len(t.Partial) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Partial was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Partial)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Partial)))); err != nil {
return err return err
} }
@ -570,6 +594,10 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
} }
// t.Params ([]uint8) (slice) // t.Params ([]uint8) (slice)
if len(t.Params) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Params was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil {
return err return err
} }
@ -817,6 +845,10 @@ func (t *SignedVoucher) MarshalCBOR(w io.Writer) error {
} }
// t.SecretPreimage ([]uint8) (slice) // t.SecretPreimage ([]uint8) (slice)
if len(t.SecretPreimage) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.SecretPreimage was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SecretPreimage)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SecretPreimage)))); err != nil {
return err return err
} }
@ -850,6 +882,10 @@ func (t *SignedVoucher) MarshalCBOR(w io.Writer) error {
} }
// t.Merges ([]types.Merge) (slice) // t.Merges ([]types.Merge) (slice)
if len(t.Merges) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Merges was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Merges)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Merges)))); err != nil {
return err return err
} }
@ -1039,6 +1075,10 @@ func (t *ModVerifyParams) MarshalCBOR(w io.Writer) error {
} }
// t.Data ([]uint8) (slice) // t.Data ([]uint8) (slice)
if len(t.Data) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Data was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Data)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Data)))); err != nil {
return err return err
} }
@ -1270,6 +1310,10 @@ func (t *MessageReceipt) MarshalCBOR(w io.Writer) error {
} }
// t.Return ([]uint8) (slice) // t.Return ([]uint8) (slice)
if len(t.Return) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Return was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Return)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Return)))); err != nil {
return err return err
} }
@ -1356,6 +1400,10 @@ func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
} }
// t.BlsMessages ([]cid.Cid) (slice) // t.BlsMessages ([]cid.Cid) (slice)
if len(t.BlsMessages) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.BlsMessages was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.BlsMessages)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.BlsMessages)))); err != nil {
return err return err
} }
@ -1366,6 +1414,10 @@ func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
} }
// t.SecpkMessages ([]cid.Cid) (slice) // t.SecpkMessages ([]cid.Cid) (slice)
if len(t.SecpkMessages) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.SecpkMessages was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.SecpkMessages)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.SecpkMessages)))); err != nil {
return err return err
} }
@ -1676,6 +1728,10 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error {
} }
// t.Cids ([]cid.Cid) (slice) // t.Cids ([]cid.Cid) (slice)
if len(t.Cids) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Cids was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Cids)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Cids)))); err != nil {
return err return err
} }
@ -1686,6 +1742,10 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error {
} }
// t.Blocks ([]*types.BlockHeader) (slice) // t.Blocks ([]*types.BlockHeader) (slice)
if len(t.Blocks) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Blocks was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Blocks)))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Blocks)))); err != nil {
return err return err
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/multiformats/go-multihash" "github.com/multiformats/go-multihash"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
) )
type Message struct { type Message struct {

View File

@ -4,7 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"

View File

@ -6,8 +6,8 @@ import (
"fmt" "fmt"
bls "github.com/filecoin-project/filecoin-ffi" bls "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/lib/crypto" "github.com/filecoin-project/go-crypto"
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"
) )

View File

@ -136,8 +136,8 @@ func (ts *TipSet) Height() uint64 {
return ts.height return ts.height
} }
func (ts *TipSet) Parents() []cid.Cid { func (ts *TipSet) Parents() TipSetKey {
return ts.blks[0].Parents return NewTipSetKey(ts.blks[0].Parents...)
} }
func (ts *TipSet) Blocks() []*BlockHeader { func (ts *TipSet) Blocks() []*BlockHeader {

View File

@ -4,7 +4,7 @@ import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
) )
func blsaddr(n int64) address.Address { func blsaddr(n int64) address.Address {

View File

@ -3,9 +3,9 @@ package types
import ( import (
"context" "context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-amt-ipld" "github.com/filecoin-project/go-amt-ipld"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"

View File

@ -4,8 +4,8 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
cborrpc "github.com/filecoin-project/lotus/lib/cborutil" cborrpc "github.com/filecoin-project/go-cbor-util"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
) )

View File

@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"testing" "testing"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -7,7 +7,7 @@ import (
vstate "github.com/filecoin-project/chain-validation/pkg/state" vstate "github.com/filecoin-project/chain-validation/pkg/state"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types" vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
) )

View File

@ -2,7 +2,6 @@ package validation
import ( import (
"context" "context"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -11,8 +10,8 @@ import (
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address" vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types" vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
@ -83,5 +82,15 @@ var methods = []uint64{
vchain.StorageMinerGetWorkerAddr: actors.MAMethods.GetWorkerAddr, vchain.StorageMinerGetWorkerAddr: actors.MAMethods.GetWorkerAddr,
vchain.StorageMinerGetPeerID: actors.MAMethods.GetPeerID, vchain.StorageMinerGetPeerID: actors.MAMethods.GetPeerID,
vchain.StorageMinerGetSectorSize: actors.MAMethods.GetSectorSize, vchain.StorageMinerGetSectorSize: actors.MAMethods.GetSectorSize,
vchain.MultiSigConstructor: actors.MultiSigMethods.MultiSigConstructor,
vchain.MultiSigPropose: actors.MultiSigMethods.Propose,
vchain.MultiSigApprove: actors.MultiSigMethods.Approve,
vchain.MultiSigCancel: actors.MultiSigMethods.Cancel,
vchain.MultiSigClearCompleted: actors.MultiSigMethods.ClearCompleted,
vchain.MultiSigAddSigner: actors.MultiSigMethods.AddSigner,
vchain.MultiSigRemoveSigner: actors.MultiSigMethods.RemoveSigner,
vchain.MultiSigSwapSigner: actors.MultiSigMethods.SwapSigner,
vchain.MultiSigChangeRequirement: actors.MultiSigMethods.ChangeRequirement,
// More to follow... // More to follow...
} }

View File

@ -12,8 +12,8 @@ import (
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address" vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types" vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
) )

View File

@ -18,14 +18,14 @@ import (
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address" vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types" vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-crypto"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/lib/crypto"
) )
type StateWrapper struct { type StateWrapper struct {

View File

@ -8,9 +8,9 @@ import (
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore" bstore "github.com/ipfs/go-ipfs-blockstore"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )

View File

@ -26,3 +26,10 @@ func TestValueTransfer(t *testing.T) {
suites.AccountValueTransferFromUnknownToKnownAccount(t, factory, 0) suites.AccountValueTransferFromUnknownToKnownAccount(t, factory, 0)
suites.AccountValueTransferFromUnknownToUnknownAccount(t, factory, 0) suites.AccountValueTransferFromUnknownToUnknownAccount(t, factory, 0)
} }
func TestMultiSig(t *testing.T) {
factory := validation.NewFactories()
suites.MultiSigActorConstructor(t, factory)
suites.MultiSigActorProposeApprove(t, factory)
suites.MultiSigActorProposeCancel(t, factory)
}

View File

@ -15,10 +15,10 @@ import (
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/bufbstore" "github.com/filecoin-project/lotus/lib/bufbstore"
@ -86,10 +86,7 @@ func (vmc *VMContext) Sys() *types.VMSyscalls {
func (vmc *VMContext) Put(i cbg.CBORMarshaler) (cid.Cid, aerrors.ActorError) { func (vmc *VMContext) Put(i cbg.CBORMarshaler) (cid.Cid, aerrors.ActorError) {
c, err := vmc.cst.Put(context.TODO(), i) c, err := vmc.cst.Put(context.TODO(), i)
if err != nil { if err != nil {
if aerr := vmc.ChargeGas(0); aerr != nil { return cid.Undef, aerrors.HandleExternalError(err, fmt.Sprintf("putting object %T", i))
return cid.Undef, aerrors.Absorb(err, outOfGasErrCode, "Put out of gas")
}
return cid.Undef, aerrors.Escalate(err, fmt.Sprintf("putting object %T", i))
} }
return c, nil return c, nil
} }
@ -97,10 +94,7 @@ func (vmc *VMContext) Put(i cbg.CBORMarshaler) (cid.Cid, aerrors.ActorError) {
func (vmc *VMContext) Get(c cid.Cid, out cbg.CBORUnmarshaler) aerrors.ActorError { func (vmc *VMContext) Get(c cid.Cid, out cbg.CBORUnmarshaler) aerrors.ActorError {
err := vmc.cst.Get(context.TODO(), c, out) err := vmc.cst.Get(context.TODO(), c, out)
if err != nil { if err != nil {
if aerr := vmc.ChargeGas(0); aerr != nil { return aerrors.HandleExternalError(err, "getting cid")
return aerrors.Absorb(err, outOfGasErrCode, "Get out of gas")
}
return aerrors.Escalate(err, "getting cid")
} }
return nil return nil
} }
@ -467,7 +461,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
ret, actorErr, vmctx := vm.send(ctx, msg, nil, msgGasCost) ret, actorErr, vmctx := vm.send(ctx, msg, nil, msgGasCost)
if aerrors.IsFatal(actorErr) { if aerrors.IsFatal(actorErr) {
return nil, xerrors.Errorf("fatal error: %w", 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)
} }
if actorErr != nil { if actorErr != nil {
log.Warnf("[from=%s,to=%s,n=%d,m=%d,h=%d] Send actor error: %+v", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr) log.Warnf("[from=%s,to=%s,n=%d,m=%d,h=%d] Send actor error: %+v", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr)

View File

@ -13,9 +13,9 @@ import (
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-crypto"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/crypto"
) )
var log = logging.Logger("wallet") var log = logging.Logger("wallet")

View File

@ -28,7 +28,7 @@ var authCreateAdminToken = &cli.Command{
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
napi, closer, err := GetFullNodeAPI(cctx) napi, closer, err := GetAPI(cctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -25,6 +25,7 @@ var chainCmd = &cli.Command{
chainGetMsgCmd, chainGetMsgCmd,
chainSetHeadCmd, chainSetHeadCmd,
chainListCmd, chainListCmd,
chainGetCmd,
}, },
} }
@ -218,6 +219,10 @@ var chainSetHeadCmd = &cli.Command{
Name: "genesis", Name: "genesis",
Usage: "reset head to genesis", Usage: "reset head to genesis",
}, },
&cli.Uint64Flag{
Name: "epoch",
Usage: "reset head to given epoch",
},
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx) api, closer, err := GetFullNodeAPI(cctx)
@ -227,25 +232,23 @@ var chainSetHeadCmd = &cli.Command{
defer closer() defer closer()
ctx := ReqContext(cctx) ctx := ReqContext(cctx)
gen := cctx.Bool("genesis") var ts *types.TipSet
if !cctx.Args().Present() && !gen { if cctx.Bool("genesis") {
return fmt.Errorf("must pass cids for tipset to set as head") ts, err = api.ChainGetGenesis(ctx)
}
if ts == nil && cctx.IsSet("epoch") {
ts, err = api.ChainGetTipSetByHeight(ctx, cctx.Uint64("epoch"), nil)
}
if ts == nil {
ts, err = parseTipSet(api, ctx, cctx.Args().Slice())
}
if err != nil {
return err
} }
var ts *types.TipSet if ts == nil {
if gen { return fmt.Errorf("must pass cids for tipset to set as head")
gents, err := api.ChainGetGenesis(ctx)
if err != nil {
return err
}
ts = gents
} else {
parsedts, err := parseTipSet(api, ctx, cctx.Args().Slice())
if err != nil {
return err
}
ts = parsedts
} }
if err := api.ChainSetHead(ctx, ts); err != nil { if err := api.ChainSetHead(ctx, ts); err != nil {
@ -319,7 +322,7 @@ var chainListCmd = &cli.Command{
break break
} }
head, err = api.ChainGetTipSet(ctx, types.NewTipSetKey(head.Parents()...)) head, err = api.ChainGetTipSet(ctx, head.Parents())
if err != nil { if err != nil {
return err return err
} }
@ -334,6 +337,41 @@ var chainListCmd = &cli.Command{
}, },
} }
var chainGetCmd = &cli.Command{
Name: "get",
Usage: "Get chain DAG node by path",
Description: `Get ipld node under a specified path:
lotus chain get /ipfs/[cid]/some/path
Note:
You can use special path elements to traverse through some data structures:
- /ipfs/[cid]/@H:elem - get 'elem' from hamt
- /ipfs/[cid]/@Ha:t01 - get element under Addr(t01).Bytes
- /ipfs/[cid]/@A:10 - get 10th amt element
`,
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
nd, err := api.ChainGetNode(ctx, cctx.Args().First())
if err != nil {
return err
}
b, err := json.MarshalIndent(nd, "", "\t")
if err != nil {
return err
}
fmt.Println(string(b))
return nil
},
}
func printTipSet(format string, ts *types.TipSet) { func printTipSet(format string, ts *types.TipSet) {
format = strings.ReplaceAll(format, "<height>", fmt.Sprint(ts.Height())) format = strings.ReplaceAll(format, "<height>", fmt.Sprint(ts.Height()))
format = strings.ReplaceAll(format, "<time>", time.Unix(int64(ts.MinTimestamp()), 0).Format(time.Stamp)) format = strings.ReplaceAll(format, "<time>", time.Unix(int64(ts.MinTimestamp()), 0).Format(time.Stamp))

Some files were not shown because too many files have changed in this diff Show More