Merge remote-tracking branch 'origin/master' into feat/chainwatch-pg
This commit is contained in:
commit
ab922ed1ba
@ -37,14 +37,13 @@ commands:
|
||||
- restore_cache:
|
||||
name: Restore parameters cache
|
||||
keys:
|
||||
- 'v20-1k-lotus-params-{{ checksum "build/proof-params/parameters.json" }}-{{ checksum "build/paramfetch.go" }}'
|
||||
- 'v20-1k-lotus-params-{{ checksum "build/proof-params/parameters.json" }}-'
|
||||
- 'v20-1k-lotus-params'
|
||||
paths:
|
||||
- /var/tmp/filecoin-proof-parameters/
|
||||
- run: ./lotus fetch-params --proving-params 1024
|
||||
- save_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:
|
||||
- /var/tmp/filecoin-proof-parameters/
|
||||
|
||||
@ -157,7 +156,7 @@ jobs:
|
||||
test-short:
|
||||
<<: *test
|
||||
|
||||
build_macos:
|
||||
build-macos:
|
||||
description: build darwin lotus binary
|
||||
macos:
|
||||
xcode: "10.0.0"
|
||||
@ -187,23 +186,20 @@ jobs:
|
||||
chmod +x $HOME/.bin/jq
|
||||
- restore_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
|
||||
- go/mod-download
|
||||
- run:
|
||||
command: make build
|
||||
command: make buildall
|
||||
no_output_timeout: 30m
|
||||
- store_artifacts:
|
||||
path: lotus
|
||||
- store_artifacts:
|
||||
path: lotus-storage-miner
|
||||
- save_cache:
|
||||
name: save go mod and cargo cache
|
||||
key: v1-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.mod" }}
|
||||
name: save cargo cache
|
||||
key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
|
||||
paths:
|
||||
- "~/go/pkg"
|
||||
- "~/go/src/github.com"
|
||||
- "~/go/src/golang.org"
|
||||
- "~/.rustup"
|
||||
- "~/.cargo"
|
||||
|
||||
@ -262,7 +258,4 @@ workflows:
|
||||
go-test-flags: "--timeout 10m --short"
|
||||
- mod-tidy-check
|
||||
- build-all
|
||||
- build_macos:
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- build-macos
|
||||
|
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal 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
1
.gitignore
vendored
@ -12,6 +12,7 @@
|
||||
/lotuspond/front/build
|
||||
/cmd/lotus-townhall/townhall/node_modules
|
||||
/cmd/lotus-townhall/townhall/build
|
||||
extern/filecoin-ffi/rust/target
|
||||
**/*.h
|
||||
**/*.a
|
||||
**/*.pc
|
||||
|
@ -4,10 +4,9 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
)
|
||||
|
||||
type Permission = string
|
||||
@ -40,7 +39,7 @@ type Version struct {
|
||||
// this api
|
||||
//
|
||||
// See APIVersion in build/version.go
|
||||
APIVersion uint32
|
||||
APIVersion build.Version
|
||||
|
||||
// TODO: git commit / os / genesis cid?
|
||||
|
||||
@ -49,6 +48,5 @@ type Version struct {
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
vM, vm, vp := build.VersionInts(v.APIVersion)
|
||||
return fmt.Sprintf("%s+api%d.%d.%d", v.Version, vM, vm, vp)
|
||||
return fmt.Sprintf("%s+api%s", v.Version, v.APIVersion.String())
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
"github.com/ipfs/go-filestore"
|
||||
"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/address"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
@ -35,15 +35,18 @@ type FullNode interface {
|
||||
ChainSetHead(context.Context, *types.TipSet) error
|
||||
ChainGetGenesis(context.Context) (*types.TipSet, 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
|
||||
SyncState(context.Context) (*SyncState, error)
|
||||
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
||||
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
|
||||
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
|
||||
// messages
|
||||
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
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
|
||||
@ -73,7 +76,7 @@ type FullNode interface {
|
||||
|
||||
// ClientImport imports file under the specified path into filestore
|
||||
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)
|
||||
ClientListDeals(ctx context.Context) ([]DealInfo, 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)
|
||||
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)
|
||||
StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error)
|
||||
|
||||
StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)
|
||||
|
@ -3,8 +3,8 @@ package api
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-sectorbuilder"
|
||||
)
|
||||
|
||||
// alias because cbor-gen doesn't like non-alias types
|
||||
|
@ -3,15 +3,15 @@ package apistruct
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/types"
|
||||
)
|
||||
@ -53,13 +53,16 @@ type FullNodeStruct struct {
|
||||
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
||||
ChainGetGenesis func(context.Context) (*types.TipSet, 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"`
|
||||
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
||||
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"`
|
||||
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"`
|
||||
MpoolGetNonce func(context.Context, address.Address) (uint64, 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"`
|
||||
WalletImport func(context.Context, *types.KeyInfo) (address.Address, 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"`
|
||||
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"`
|
||||
ClientFindData func(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
|
||||
ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"`
|
||||
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
|
||||
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
|
||||
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, path string) error `perm:"admin"`
|
||||
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"`
|
||||
ClientImport func(ctx context.Context, path string) (cid.Cid, error) `perm:"admin"`
|
||||
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
|
||||
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"`
|
||||
ClientFindData func(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
|
||||
ClientStartDeal func(ctx context.Context, 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"`
|
||||
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
|
||||
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"`
|
||||
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
StateReadState func(context.Context, *types.Actor, *types.TipSet) (*api.ActorState, 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"`
|
||||
StateListMiners 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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, 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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
StateReadState func(context.Context, *types.Actor, *types.TipSet) (*api.ActorState, 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"`
|
||||
StateListMiners 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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
|
||||
@ -208,8 +212,8 @@ func (c *FullNodeStruct) ClientFindData(ctx context.Context, root cid.Cid) ([]ap
|
||||
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) {
|
||||
return c.Internal.ClientStartDeal(ctx, data, miner, price, blocksDuration)
|
||||
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, addr, miner, price, blocksDuration)
|
||||
}
|
||||
func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*api.DealInfo, error) {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@ -343,6 +347,14 @@ func (c *FullNodeStruct) ChainTipSetWeight(ctx context.Context, ts *types.TipSet
|
||||
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) {
|
||||
return c.Internal.SyncState(ctx)
|
||||
}
|
||||
@ -355,6 +367,10 @@ func (c *FullNodeStruct) SyncIncomingBlocks(ctx context.Context) (<-chan *types.
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
return c.Internal.MarketEnsureAvailable(ctx, addr, amt)
|
||||
}
|
||||
|
@ -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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ func (ts *testSuite) testVersion(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v.Version != build.Version {
|
||||
if v.Version != build.BuildVersion {
|
||||
t.Error("Version didn't work properly")
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
package build
|
||||
|
||||
const ForkCCM = 1750
|
||||
const ForkNoPowerEPSUpdates = 16450
|
||||
|
@ -1,6 +1,12 @@
|
||||
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 {
|
||||
builtinGen, err := rice.FindBox("genesis")
|
||||
|
@ -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, ¶ms); 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
|
||||
}
|
@ -31,7 +31,7 @@ const PaymentChannelClosingDelay = 6 * 60 * 60 / BlockDelay // six hours
|
||||
// Consensus / Network
|
||||
|
||||
// Seconds
|
||||
const AllowableClockDrift = BlockDelay * 2
|
||||
const AllowableClockDrift = 1
|
||||
|
||||
// Epochs
|
||||
const ForkLengthThreshold = Finality
|
||||
@ -56,11 +56,6 @@ const SealRandomnessLookback = Finality
|
||||
// Epochs
|
||||
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
|
||||
|
||||
// 1 / n
|
||||
const SectorChallengeRatioDiv = 25
|
||||
|
||||
const MaxFallbackPostChallengeCount = 10
|
||||
|
||||
// /////
|
||||
// Mining
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -1,34 +1,44 @@
|
||||
package build
|
||||
|
||||
import "fmt"
|
||||
|
||||
var CurrentCommit string
|
||||
|
||||
// Version is the local build version, set by build system
|
||||
const Version = "0.1.1"
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "0.1.5"
|
||||
|
||||
var UserVersion = Version + CurrentCommit
|
||||
var UserVersion = BuildVersion + CurrentCommit
|
||||
|
||||
// APIVersion is a hex semver version of the rpc api exposed
|
||||
//
|
||||
// M M P
|
||||
// A I A
|
||||
// J N T
|
||||
// O O C
|
||||
// R R H
|
||||
// |\vv/|
|
||||
// vv vv
|
||||
const APIVersion = 0x000101
|
||||
type Version uint32
|
||||
|
||||
func newVer(major, minor, patch uint8) Version {
|
||||
return Version(uint32(major)<<16 | uint32(minor)<<8 | uint32(patch))
|
||||
}
|
||||
|
||||
// Ints returns (major, minor, patch) versions
|
||||
func (ve Version) Ints() (uint32, uint32, uint32) {
|
||||
v := uint32(ve)
|
||||
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 (
|
||||
MajorMask = 0xff0000
|
||||
MinorMask = 0xffff00
|
||||
PatchMask = 0xffffff
|
||||
majorMask = 0xff0000
|
||||
minorMask = 0xffff00
|
||||
patchMask = 0xffffff
|
||||
|
||||
MajorOnlyMask = 0xff0000
|
||||
MinorOnlyMask = 0x00ff00
|
||||
PatchOnlyMask = 0x0000ff
|
||||
majorOnlyMask = 0xff0000
|
||||
minorOnlyMask = 0x00ff00
|
||||
patchOnlyMask = 0x0000ff
|
||||
)
|
||||
|
||||
// VersionInts returns (major, minor, patch) versions
|
||||
func VersionInts(version uint32) (uint32, uint32, uint32) {
|
||||
return (version & MajorOnlyMask) >> 16, (version & MinorOnlyMask) >> 8, version & PatchOnlyMask
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package actors
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
@ -8,11 +8,11 @@ import (
|
||||
|
||||
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/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -140,7 +140,10 @@ func (sma StorageMinerActor) Exports() []interface{} {
|
||||
return []interface{}{
|
||||
1: sma.StorageMinerConstructor,
|
||||
2: sma.PreCommitSector,
|
||||
3: sma.ProveCommitSector,
|
||||
3: withUpdates(
|
||||
update{start: 0, method: sma.ProveCommitSectorV0},
|
||||
update{start: build.ForkNoPowerEPSUpdates, method: sma.ProveCommitSectorV1},
|
||||
),
|
||||
4: sma.SubmitFallbackPoSt,
|
||||
//5: sma.SlashStorageFault,
|
||||
//6: sma.GetCurrentProvingSet,
|
||||
@ -155,7 +158,10 @@ func (sma StorageMinerActor) Exports() []interface{} {
|
||||
//15: sma.ChangeWorker,
|
||||
16: sma.IsSlashed,
|
||||
17: sma.CheckMiner,
|
||||
18: sma.DeclareFaults,
|
||||
18: withUpdates(
|
||||
update{start: 0, method: sma.DeclareFaultsV0},
|
||||
update{start: build.ForkNoPowerEPSUpdates, method: sma.DeclareFaultsV1},
|
||||
),
|
||||
19: sma.SlashConsensusFault,
|
||||
20: sma.SubmitElectionPoSt,
|
||||
}
|
||||
@ -238,7 +244,7 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon
|
||||
}
|
||||
|
||||
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
|
||||
@ -291,7 +297,7 @@ type SectorProveCommitInfo struct {
|
||||
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()
|
||||
oldstate, self, err := loadState(vmctx)
|
||||
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)
|
||||
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 {
|
||||
@ -508,7 +621,7 @@ func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VM
|
||||
}
|
||||
|
||||
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 {
|
||||
// TODO: study PoST errors
|
||||
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")
|
||||
}
|
||||
|
||||
if err := ssr.BatchDelete(ids); err != nil {
|
||||
return cid.Undef, aerrors.HandleExternalError(err, "failed to delete from sector set")
|
||||
for _, id := range ids {
|
||||
if err := ssr.Delete(id); err != nil {
|
||||
log.Warnf("failed to delete sector %d from set: %s", id, err)
|
||||
}
|
||||
}
|
||||
|
||||
ncid, err := ssr.Flush()
|
||||
@ -808,7 +923,7 @@ type DeclareFaultsParams struct {
|
||||
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)
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
@ -824,7 +939,42 @@ func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMConte
|
||||
self.LastFaultSubmission = vmctx.BlockHeight()
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
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 {
|
||||
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
|
||||
|
||||
var mi MinerInfo
|
||||
@ -953,9 +1178,9 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro
|
||||
|
||||
if !(oldPower.IsZero() && newPower.IsZero()) {
|
||||
enc, err := SerializeParams(&UpdateStorageParams{
|
||||
Delta: delta,
|
||||
NextProvingPeriodEnd: vmctx.BlockHeight() + build.SlashablePowerDelay,
|
||||
PreviousProvingPeriodEnd: prevSlashingDeadline,
|
||||
Delta: delta,
|
||||
NextSlashDeadline: vmctx.BlockHeight() + build.SlashablePowerDelay,
|
||||
PreviousSlashDeadline: prevSlashingDeadline,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -963,8 +1188,10 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro
|
||||
|
||||
_, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc)
|
||||
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)
|
||||
@ -974,7 +1201,6 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro
|
||||
|
||||
self.Sectors = ncid
|
||||
self.ProvingSet = ncid
|
||||
self.ElectionPeriodStart = vmctx.BlockHeight()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -6,13 +6,13 @@ import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-sectorbuilder"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"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/types"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -52,6 +52,71 @@ func TestMinerCommitSectors(t *testing.T) {
|
||||
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) {
|
||||
t.Helper()
|
||||
s := sectorbuilder.UserBytesForSectorSize(1024)
|
||||
|
@ -3,8 +3,8 @@ package actors
|
||||
import (
|
||||
"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/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
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/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
)
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/minio/blake2b-simd"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"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/wallet"
|
||||
)
|
||||
|
@ -5,18 +5,19 @@ import (
|
||||
"context"
|
||||
"sort"
|
||||
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
"github.com/ipfs/go-cid"
|
||||
"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/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/cborutil"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
)
|
||||
|
||||
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) {
|
||||
ctx, span := trace.StartSpan(ctx, "GetMarketBalances")
|
||||
defer span.End()
|
||||
|
||||
nd, err := hamt.LoadNode(ctx, store, rcid)
|
||||
if err != nil {
|
||||
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 {
|
||||
ctx, span := trace.StartSpan(vmctx.Context(), "validateDeal")
|
||||
defer span.End()
|
||||
|
||||
if vmctx.BlockHeight() > deal.ProposalExpiration {
|
||||
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)
|
||||
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 {
|
||||
return aerrors.Wrap(aerr, "getting client, and provider balances")
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@ -267,9 +267,9 @@ func shouldSlash(block1, block2 *types.BlockHeader) bool {
|
||||
}
|
||||
|
||||
type UpdateStorageParams struct {
|
||||
Delta types.BigInt
|
||||
NextProvingPeriodEnd uint64
|
||||
PreviousProvingPeriodEnd uint64
|
||||
Delta types.BigInt
|
||||
NextSlashDeadline uint64
|
||||
PreviousSlashDeadline uint64
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
previousBucket := params.PreviousProvingPeriodEnd % build.SlashablePowerDelay
|
||||
nextBucket := params.NextProvingPeriodEnd % build.SlashablePowerDelay
|
||||
previousBucket := params.PreviousSlashDeadline % 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)
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
if params.PreviousProvingPeriodEnd != 0 { // delete from previous bucket
|
||||
if params.PreviousSlashDeadline != 0 { // delete from previous bucket
|
||||
err := deleteMinerFromBucket(vmctx, buckets, previousBucket)
|
||||
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")
|
||||
}
|
||||
|
||||
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 {
|
||||
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{}
|
||||
|
||||
var cborNull = &cbgNull{}
|
||||
var CborNull = &cbgNull{}
|
||||
|
||||
func (cbgNull) MarshalCBOR(w io.Writer) error {
|
||||
n, err := w.Write(cbg.CborNull)
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
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/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
|
@ -1,7 +1,7 @@
|
||||
package actors
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
|
||||
"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/address"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
@ -1,8 +1,8 @@
|
||||
package actors
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
)
|
||||
|
||||
func NewIDAddress(id uint64) (address.Address, ActorError) {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
"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{
|
||||
fatal: true,
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -94,6 +94,10 @@ func (t *ExecParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -220,6 +224,10 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
|
||||
for _, k := range keys {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -481,6 +489,10 @@ func (t *StorageMinerConstructorParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -561,6 +573,10 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -574,6 +590,10 @@ func (t *SectorPreCommitInfo) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -749,6 +769,10 @@ func (t *MinerInfo) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -829,6 +853,10 @@ func (t *SubmitFallbackPoStParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -837,6 +865,10 @@ func (t *SubmitFallbackPoStParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -920,6 +952,10 @@ func (t *PaymentVerifyParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -928,6 +964,10 @@ func (t *PaymentVerifyParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -999,6 +1039,10 @@ func (t *UpdatePeerIDParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1089,6 +1133,10 @@ func (t *MultiSigActorState) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1124,6 +1172,10 @@ func (t *MultiSigActorState) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1266,6 +1318,10 @@ func (t *MultiSigConstructorParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1377,6 +1433,10 @@ func (t *MultiSigProposeParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1629,6 +1689,10 @@ func (t *MTransaction) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1637,6 +1701,10 @@ func (t *MTransaction) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1999,6 +2067,10 @@ func (t *PaymentChannelActorState) MarshalCBOR(w io.Writer) error {
|
||||
for _, k := range keys {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -2271,6 +2343,10 @@ func (t *PCAUpdateChannelStateParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -2279,6 +2355,10 @@ func (t *PCAUpdateChannelStateParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -2381,6 +2461,10 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -2613,6 +2697,10 @@ func (t *CreateStorageMinerParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -2778,13 +2866,13 @@ func (t *UpdateStorageParams) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.NextProvingPeriodEnd (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextProvingPeriodEnd))); err != nil {
|
||||
// t.NextSlashDeadline (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextSlashDeadline))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.PreviousProvingPeriodEnd (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PreviousProvingPeriodEnd))); err != nil {
|
||||
// t.PreviousSlashDeadline (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PreviousSlashDeadline))); err != nil {
|
||||
return err
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
@ -2823,8 +2911,8 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error {
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.NextProvingPeriodEnd = uint64(extra)
|
||||
// t.PreviousProvingPeriodEnd (uint64) (uint64)
|
||||
t.NextSlashDeadline = uint64(extra)
|
||||
// t.PreviousSlashDeadline (uint64) (uint64)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
@ -2833,7 +2921,7 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error {
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.PreviousProvingPeriodEnd = uint64(extra)
|
||||
t.PreviousSlashDeadline = uint64(extra)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3223,6 +3311,10 @@ func (t *StorageDealProposal) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3404,6 +3496,10 @@ func (t *PublishStorageDealsParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3470,6 +3566,10 @@ func (t *PublishStorageDealResponse) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3540,6 +3640,10 @@ func (t *ActivateStorageDealsParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3610,6 +3714,10 @@ func (t *ProcessStorageDealsPaymentParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3680,6 +3788,10 @@ func (t *OnChainDeal) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3850,6 +3962,10 @@ func (t *ComputeDataCommitmentParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3935,6 +4051,10 @@ func (t *SectorProveCommitInfo) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -3948,6 +4068,10 @@ func (t *SectorProveCommitInfo) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
|
46
chain/actors/forks.go
Normal file
46
chain/actors/forks.go
Normal 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())
|
||||
}
|
||||
}
|
@ -14,8 +14,8 @@ import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"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/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)))
|
||||
}
|
@ -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)
|
@ -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
|
||||
}
|
||||
}
|
71
chain/block_receipt_tracker.go
Normal file
71
chain/block_receipt_tracker.go
Normal 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
|
||||
}
|
@ -8,9 +8,9 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-cbor-util"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/cborutil"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
@ -90,7 +90,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) {
|
||||
|
||||
var req BlockSyncRequest
|
||||
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
|
||||
}
|
||||
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 {
|
||||
log.Error("failed to write back response for handle stream: ", err)
|
||||
log.Warn("failed to write back response for handle stream: ", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -124,7 +124,7 @@ func (bss *BlockSyncService) processRequest(ctx context.Context, req *BlockSyncR
|
||||
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 {
|
||||
log.Warn("encountered error while responding to block sync request: ", err)
|
||||
return &BlockSyncResponse{
|
||||
@ -139,7 +139,7 @@ func (bss *BlockSyncService) processRequest(ctx context.Context, req *BlockSyncR
|
||||
}, 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
|
||||
cur := start
|
||||
for {
|
||||
|
@ -18,9 +18,9 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-cbor-util"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"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/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")
|
||||
defer span.End()
|
||||
if span.IsRecordingEvents() {
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("tipset", fmt.Sprint(tipset)),
|
||||
trace.StringAttribute("tipset", fmt.Sprint(tsk.Cids())),
|
||||
trace.Int64Attribute("count", int64(count)),
|
||||
)
|
||||
}
|
||||
|
||||
req := &BlockSyncRequest{
|
||||
Start: tipset,
|
||||
Start: tsk.Cids(),
|
||||
RequestLength: uint64(count),
|
||||
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)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
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))
|
||||
return bs.processBlocksResponse(req, res)
|
||||
bs.host.ConnManager().TagPeer(p, "bsync", 25)
|
||||
return resp, nil
|
||||
}
|
||||
oerr = bs.processStatus(req, res)
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
req := &BlockSyncRequest{
|
||||
Start: h,
|
||||
Start: tsk.Cids(),
|
||||
RequestLength: 1,
|
||||
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) {
|
||||
if len(res.Chain) == 0 {
|
||||
return nil, xerrors.Errorf("got no blocks in successful blocksync response")
|
||||
}
|
||||
|
||||
cur, err := types.NewTipSet(res.Chain[0].Blocks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -275,7 +286,7 @@ func (bs *BlockSync) processBlocksResponse(req *BlockSyncRequest, res *BlockSync
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
@ -24,6 +24,10 @@ func (t *BlockSyncRequest) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -119,6 +123,10 @@ func (t *BlockSyncResponse) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -134,6 +142,10 @@ func (t *BlockSyncResponse) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -218,6 +230,10 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -228,6 +244,10 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -238,10 +258,18 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -253,6 +281,10 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -263,10 +295,18 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -202,6 +202,10 @@ func (t *Response) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -408,6 +412,10 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -539,6 +547,10 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -672,6 +684,10 @@ func (t *MinerDeal) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
|
@ -10,17 +10,17 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"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/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/market"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"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/modules/dtypes"
|
||||
"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) {
|
||||
s, err := c.h.NewStream(ctx, p, AskProtocolID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, xerrors.Errorf("failed to open stream to miner: %w", err)
|
||||
}
|
||||
|
||||
req := &AskRequest{
|
||||
|
@ -6,12 +6,12 @@ import (
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-cbor-util"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"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)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"runtime"
|
||||
|
||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||
"github.com/ipfs/go-cid"
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
unixfile "github.com/ipfs/go-unixfs/file"
|
||||
@ -12,11 +13,11 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"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/lib/cborutil"
|
||||
"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"
|
||||
)
|
||||
|
||||
|
@ -12,13 +12,13 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"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/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"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/storage"
|
||||
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
||||
|
@ -5,10 +5,10 @@ import (
|
||||
"context"
|
||||
"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/types"
|
||||
"github.com/filecoin-project/lotus/lib/cborutil"
|
||||
datastore "github.com/ipfs/go-datastore"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
"golang.org/x/xerrors"
|
||||
|
@ -10,11 +10,11 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"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/address"
|
||||
"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"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
|
@ -13,13 +13,13 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
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/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/deals"
|
||||
"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()
|
||||
|
@ -4,11 +4,11 @@ import (
|
||||
"bytes"
|
||||
"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/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/cborutil"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
logging "github.com/ipfs/go-log"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/types"
|
||||
)
|
||||
|
@ -13,8 +13,8 @@ import (
|
||||
"github.com/multiformats/go-multihash"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
|
||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-car"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
@ -19,16 +20,15 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
|
||||
block "github.com/ipfs/go-block-format"
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"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/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
@ -15,9 +15,9 @@ import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
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/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"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/types"
|
||||
"github.com/filecoin-project/lotus/node/impl/full"
|
||||
|
@ -19,9 +19,9 @@ import (
|
||||
"go.uber.org/multierr"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -109,7 +109,7 @@ type Provider interface {
|
||||
StateGetActor(address.Address, *types.TipSet) (*types.Actor, error)
|
||||
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
|
||||
MessagesForTipset(*types.TipSet) ([]store.ChainMsg, error)
|
||||
LoadTipSet(cids []cid.Cid) (*types.TipSet, error)
|
||||
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
||||
}
|
||||
|
||||
type mpoolProvider struct {
|
||||
@ -146,8 +146,8 @@ func (mpp *mpoolProvider) MessagesForTipset(ts *types.TipSet) ([]store.ChainMsg,
|
||||
return mpp.sm.ChainStore().MessagesForTipset(ts)
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) LoadTipSet(cids []cid.Cid) (*types.TipSet, error) {
|
||||
return mpp.sm.ChainStore().LoadTipSet(cids)
|
||||
func (mpp *mpoolProvider) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return mpp.sm.ChainStore().LoadTipSet(tsk)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (mp *MessagePool) Push(m *types.SignedMessage) error {
|
||||
func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
|
||||
msgb, err := m.Serialize()
|
||||
if err != nil {
|
||||
return err
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
if err := mp.Add(m); err != nil {
|
||||
return err
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
mp.lk.Lock()
|
||||
if err := mp.addLocal(m, msgb); err != nil {
|
||||
mp.lk.Unlock()
|
||||
return err
|
||||
return cid.Undef, err
|
||||
}
|
||||
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 {
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"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/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/mock"
|
||||
@ -98,9 +98,9 @@ func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]store.ChainMsg,
|
||||
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 {
|
||||
if types.CidArrsEqual(cids, ts.Cids()) {
|
||||
if types.CidArrsEqual(tsk.Cids(), ts.Cids()) {
|
||||
return ts, nil
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
logging "github.com/ipfs/go-log"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
@ -3,8 +3,8 @@ package state
|
||||
import (
|
||||
"testing"
|
||||
|
||||
address "github.com/filecoin-project/go-address"
|
||||
actors "github.com/filecoin-project/lotus/chain/actors"
|
||||
address "github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
)
|
||||
|
127
chain/stmgr/fork_no_p_eps.go
Normal file
127
chain/stmgr/fork_no_p_eps.go
Normal 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
25
chain/stmgr/forks.go
Normal 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
|
||||
}
|
@ -5,9 +5,9 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
amt "github.com/filecoin-project/go-amt-ipld"
|
||||
"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/store"
|
||||
"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
|
||||
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))
|
||||
for i, v := range blks {
|
||||
|
@ -4,12 +4,13 @@ import (
|
||||
"context"
|
||||
|
||||
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/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
|
||||
amt "github.com/filecoin-project/go-amt-ipld"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
@ -270,6 +271,21 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *ty
|
||||
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) {
|
||||
blks := amt.WrapBlockstore(bs)
|
||||
a, err := amt.LoadAMT(blks, ssc)
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"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/vm"
|
||||
"go.opencensus.io/trace"
|
||||
@ -50,16 +50,19 @@ type ChainStore struct {
|
||||
headChangeNotifs []func(rev, app []*types.TipSet) error
|
||||
|
||||
mmCache *lru.ARCCache
|
||||
tsCache *lru.ARCCache
|
||||
}
|
||||
|
||||
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore {
|
||||
c, _ := lru.NewARC(2048)
|
||||
tsc, _ := lru.NewARC(4096)
|
||||
cs := &ChainStore{
|
||||
bs: bs,
|
||||
ds: ds,
|
||||
bestTips: pubsub.New(64),
|
||||
tipsets: make(map[uint64][]cid.Cid),
|
||||
mmCache: c,
|
||||
tsCache: tsc,
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
ts, err := cs.LoadTipSet(tscids)
|
||||
ts, err := cs.LoadTipSet(types.NewTipSetKey(tscids...))
|
||||
if err != nil {
|
||||
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())
|
||||
}
|
||||
|
||||
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
|
||||
for _, c := range cids {
|
||||
for _, c := range tsk.Cids() {
|
||||
b, err := cs.GetBlock(c)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
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'
|
||||
@ -817,7 +832,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round i
|
||||
span.AddAttributes(trace.Int64Attribute("round", round))
|
||||
|
||||
for {
|
||||
nts, err := cs.LoadTipSet(blks)
|
||||
nts, err := cs.LoadTipSet(types.NewTipSetKey(blks...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
68
chain/store/store_test.go
Normal file
68
chain/store/store_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
connmgr "github.com/libp2p/go-libp2p-core/connmgr"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
@ -14,7 +15,7 @@ import (
|
||||
|
||||
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 {
|
||||
msg, err := bsub.Next(ctx)
|
||||
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 {
|
||||
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,
|
||||
BlsMessages: bmsgs,
|
||||
SecpkMessages: smsgs,
|
||||
})
|
||||
}) {
|
||||
cmgr.TagPeer(msg.ReceivedFrom, "blkprop", 5)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
141
chain/sync.go
141
chain/sync.go
@ -6,34 +6,37 @@ import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Gurpartap/async"
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
amt "github.com/filecoin-project/go-amt-ipld"
|
||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/ipfs/go-cid"
|
||||
dstore "github.com/ipfs/go-datastore"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/libp2p/go-libp2p-core/connmgr"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"github.com/whyrusleeping/pubsub"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/blocksync"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
)
|
||||
|
||||
var log = logging.Logger("chain")
|
||||
@ -41,8 +44,6 @@ var log = logging.Logger("chain")
|
||||
var LocalIncoming = "incoming"
|
||||
|
||||
type Syncer struct {
|
||||
// The heaviest known tipset in the network.
|
||||
|
||||
// The interface for accessing and putting tipsets into local storage
|
||||
store *store.ChainStore
|
||||
|
||||
@ -62,10 +63,14 @@ type Syncer struct {
|
||||
|
||||
syncmgr *SyncManager
|
||||
|
||||
connmgr connmgr.ConnManager
|
||||
|
||||
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()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -77,12 +82,14 @@ func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, self peer.ID)
|
||||
}
|
||||
|
||||
s := &Syncer{
|
||||
bad: NewBadBlockCache(),
|
||||
Genesis: gent,
|
||||
Bsync: bsync,
|
||||
store: sm.ChainStore(),
|
||||
sm: sm,
|
||||
self: self,
|
||||
bad: NewBadBlockCache(),
|
||||
Genesis: gent,
|
||||
Bsync: bsync,
|
||||
store: sm.ChainStore(),
|
||||
sm: sm,
|
||||
self: self,
|
||||
receiptTracker: newBlockReceiptTracker(),
|
||||
connmgr: connmgr,
|
||||
|
||||
incoming: pubsub.New(50),
|
||||
}
|
||||
@ -102,17 +109,17 @@ func (syncer *Syncer) Stop() {
|
||||
// InformNewHead informs the syncer about a new potential tipset
|
||||
// This should be called when connecting to new peers, and additionally
|
||||
// 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()
|
||||
if fts == nil {
|
||||
log.Errorf("got nil tipset in InformNewHead")
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
for _, b := range fts.Blocks {
|
||||
if err := syncer.ValidateMsgMeta(b); err != nil {
|
||||
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 {
|
||||
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
|
||||
// the blockstore
|
||||
if err := syncer.store.PersistBlockHeaders(fts.TipSet().Blocks()...); err != nil {
|
||||
log.Warn("failed to persist incoming block header: ", err)
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
syncer.Bsync.AddPeer(from)
|
||||
@ -145,11 +153,12 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
|
||||
for _, blk := range fts.TipSet().Blocks() {
|
||||
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)
|
||||
return
|
||||
log.Infof("incoming tipset from %s does not appear to be better than our best chain, ignoring for now", miners)
|
||||
return false
|
||||
}
|
||||
|
||||
syncer.syncmgr.SetPeerHead(ctx, from, fts.TipSet())
|
||||
return true
|
||||
}
|
||||
|
||||
func (syncer *Syncer) IncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) {
|
||||
@ -231,12 +240,12 @@ func (syncer *Syncer) ChainStore() *store.ChainStore {
|
||||
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
|
||||
// and then send that tipset to InformNewHead
|
||||
|
||||
fts := &store.FullTipSet{Blocks: []*types.FullBlock{blk}}
|
||||
syncer.InformNewHead(from, fts)
|
||||
return syncer.InformNewHead(from, fts)
|
||||
}
|
||||
|
||||
func copyBlockstore(from, to bstore.Blockstore) error {
|
||||
@ -329,16 +338,16 @@ func computeMsgMeta(bs amt.Blocks, bmsgCids, smsgCids []cbg.CBORMarshaler) (cid.
|
||||
return mrcid, nil
|
||||
}
|
||||
|
||||
func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, cids []cid.Cid) (*store.FullTipSet, error) {
|
||||
if fts, err := syncer.tryLoadFullTipSet(cids); err == nil {
|
||||
func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, tsk types.TipSetKey) (*store.FullTipSet, error) {
|
||||
if fts, err := syncer.tryLoadFullTipSet(tsk); err == nil {
|
||||
return fts, nil
|
||||
}
|
||||
|
||||
return syncer.Bsync.GetFullTipSet(ctx, p, cids)
|
||||
return syncer.Bsync.GetFullTipSet(ctx, p, tsk)
|
||||
}
|
||||
|
||||
func (syncer *Syncer) tryLoadFullTipSet(cids []cid.Cid) (*store.FullTipSet, error) {
|
||||
ts, err := syncer.store.LoadTipSet(cids)
|
||||
func (syncer *Syncer) tryLoadFullTipSet(tsk types.TipSetKey) (*store.FullTipSet, error) {
|
||||
ts, err := syncer.store.LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -409,6 +427,8 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
|
||||
ctx, span := trace.StartSpan(ctx, "validateTipSet")
|
||||
defer span.End()
|
||||
|
||||
span.AddAttributes(trace.Int64Attribute("height", int64(fts.TipSet().Height())))
|
||||
|
||||
ts := fts.TipSet()
|
||||
if ts.Equals(syncer.Genesis) {
|
||||
return nil
|
||||
@ -469,7 +489,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
||||
|
||||
h := b.Header
|
||||
|
||||
baseTs, err := syncer.store.LoadTipSet(h.Parents)
|
||||
baseTs, err := syncer.store.LoadTipSet(types.NewTipSetKey(h.Parents...))
|
||||
if err != nil {
|
||||
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) {
|
||||
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()) {
|
||||
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 {
|
||||
{
|
||||
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)
|
||||
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())
|
||||
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 {
|
||||
if err := checkMsg(m); err != nil {
|
||||
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
|
||||
}
|
||||
|
||||
sigCids = append(sigCids, m.Cid())
|
||||
c := cbg.CborCid(m.Cid())
|
||||
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
|
||||
@ -794,10 +820,19 @@ func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig types.Signatur
|
||||
trace.Int64Attribute("msgCount", int64(len(msgs))),
|
||||
)
|
||||
|
||||
var digests []bls.Digest
|
||||
for _, c := range msgs {
|
||||
digests = append(digests, bls.Hash(bls.Message(c.Bytes())))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
digests := make([]bls.Digest, len(msgs))
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func(w int) {
|
||||
defer wg.Done()
|
||||
for j := 0; (j*10)+w < len(msgs); j++ {
|
||||
digests[j*10+w] = bls.Hash(bls.Message(msgs[j*10+w].Bytes()))
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
var bsig bls.Signature
|
||||
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())),
|
||||
)
|
||||
|
||||
for _, pcid := range from.Parents() {
|
||||
for _, pcid := range from.Parents().Cids() {
|
||||
if syncer.bad.Has(pcid) {
|
||||
for _, b := range from.Cids() {
|
||||
syncer.bad.Add(b)
|
||||
@ -850,7 +885,7 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
|
||||
|
||||
loop:
|
||||
for blockSet[len(blockSet)-1].Height() > untilHeight {
|
||||
for _, bc := range at {
|
||||
for _, bc := range at.Cids() {
|
||||
if syncer.bad.Has(bc) {
|
||||
for _, b := range acceptedBlocks {
|
||||
syncer.bad.Add(b)
|
||||
@ -863,7 +898,7 @@ loop:
|
||||
// If, for some reason, we have a suffix of the chain locally, handle that here
|
||||
ts, err := syncer.store.LoadTipSet(at)
|
||||
if err == nil {
|
||||
acceptedBlocks = append(acceptedBlocks, at...)
|
||||
acceptedBlocks = append(acceptedBlocks, at.Cids()...)
|
||||
|
||||
blockSet = append(blockSet, ts)
|
||||
at = ts.Parents()
|
||||
@ -910,16 +945,16 @@ loop:
|
||||
blockSet = append(blockSet, b)
|
||||
}
|
||||
|
||||
acceptedBlocks = append(acceptedBlocks, at...)
|
||||
acceptedBlocks = append(acceptedBlocks, at.Cids()...)
|
||||
|
||||
ss.SetHeight(blks[len(blks)-1].Height())
|
||||
at = blks[len(blks)-1].Parents()
|
||||
}
|
||||
|
||||
// We have now ascertained that this is *not* a 'fast forward'
|
||||
if !types.CidArrsEqual(blockSet[len(blockSet)-1].Parents(), to.Cids()) {
|
||||
if !types.CidArrsEqual(blockSet[len(blockSet)-1].Parents().Cids(), to.Cids()) {
|
||||
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
|
||||
return blockSet, nil
|
||||
}
|
||||
@ -1002,6 +1037,8 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
|
||||
ctx, span := trace.StartSpan(ctx, "iterFullTipsets")
|
||||
defer span.End()
|
||||
|
||||
span.AddAttributes(trace.Int64Attribute("num_headers", int64(len(headers))))
|
||||
|
||||
windowSize := 200
|
||||
for i := len(headers) - 1; i >= 0; {
|
||||
fts, err := syncer.store.TryFillTipSet(headers[i])
|
||||
@ -1144,3 +1181,7 @@ func (syncer *Syncer) State() []SyncerState {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (syncer *Syncer) MarkBad(blk cid.Cid) {
|
||||
syncer.bad.Add(blk)
|
||||
}
|
||||
|
@ -197,10 +197,10 @@ func (stb *syncTargetBucket) sameChainAs(ts *types.TipSet) bool {
|
||||
if ts.Equals(t) {
|
||||
return true
|
||||
}
|
||||
if types.CidArrsEqual(ts.Cids(), t.Parents()) {
|
||||
if ts.Key() == t.Parents() {
|
||||
return true
|
||||
}
|
||||
if types.CidArrsEqual(ts.Parents(), t.Cids()) {
|
||||
if ts.Parents() == t.Key() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -293,7 +293,7 @@ func (sm *SyncManager) scheduleIncoming(ts *types.TipSet) {
|
||||
break
|
||||
}
|
||||
|
||||
if types.CidArrsEqual(ts.Parents(), acts.Cids()) {
|
||||
if ts.Parents() == acts.Key() {
|
||||
// sync this next, after that sync process finishes
|
||||
relatedToActiveSync = true
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ import (
|
||||
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
@ -1,7 +1,7 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
)
|
||||
|
||||
|
@ -124,6 +124,22 @@ func (bi *BigInt) UnmarshalJSON(b []byte) error {
|
||||
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 {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
|
@ -2,7 +2,10 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
}
|
||||
|
@ -156,6 +156,10 @@ func (bf BitField) MarshalCBOR(w io.Writer) error {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/filecoin-project/go-sectorbuilder"
|
||||
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/minio/sha256-simd"
|
||||
@ -12,8 +14,9 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
)
|
||||
|
||||
type Ticket struct {
|
||||
@ -176,7 +179,7 @@ const sha256bits = 256
|
||||
|
||||
func IsTicketWinner(partialTicket []byte, ssizeI uint64, snum uint64, totpow BigInt) bool {
|
||||
ssize := NewInt(ssizeI)
|
||||
ssampled := ElectionPostChallengeCount(snum)
|
||||
ssampled := ElectionPostChallengeCount(snum, 0) // TODO: faults in epost?
|
||||
/*
|
||||
Need to check that
|
||||
(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
|
||||
}
|
||||
|
||||
func ElectionPostChallengeCount(sectors uint64) uint64 {
|
||||
if sectors == 0 {
|
||||
return 0
|
||||
}
|
||||
// ceil(sectors / build.SectorChallengeRatioDiv)
|
||||
return (sectors-1)/build.SectorChallengeRatioDiv + 1
|
||||
func ElectionPostChallengeCount(sectors uint64, faults int) uint64 {
|
||||
return sectorbuilder.ElectionPostChallengeCount(sectors, faults)
|
||||
}
|
||||
|
||||
func (t *Ticket) Equals(ot *Ticket) bool {
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
@ -39,6 +39,10 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -281,6 +285,10 @@ func (t *Ticket) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -335,6 +343,10 @@ func (t *EPostProof) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -343,6 +355,10 @@ func (t *EPostProof) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -351,6 +367,10 @@ func (t *EPostProof) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -451,6 +471,10 @@ func (t *EPostTicket) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -570,6 +594,10 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -817,6 +845,10 @@ func (t *SignedVoucher) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -850,6 +882,10 @@ func (t *SignedVoucher) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1039,6 +1075,10 @@ func (t *ModVerifyParams) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1270,6 +1310,10 @@ func (t *MessageReceipt) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1356,6 +1400,10 @@ func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1366,6 +1414,10 @@ func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1676,6 +1728,10 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -1686,6 +1742,10 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multihash"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"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/wallet"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/lib/crypto"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-crypto"
|
||||
"github.com/minio/blake2b-simd"
|
||||
)
|
||||
|
||||
|
@ -136,8 +136,8 @@ func (ts *TipSet) Height() uint64 {
|
||||
return ts.height
|
||||
}
|
||||
|
||||
func (ts *TipSet) Parents() []cid.Cid {
|
||||
return ts.blks[0].Parents
|
||||
func (ts *TipSet) Parents() TipSetKey {
|
||||
return NewTipSetKey(ts.blks[0].Parents...)
|
||||
}
|
||||
|
||||
func (ts *TipSet) Blocks() []*BlockHeader {
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
)
|
||||
|
||||
func blsaddr(n int64) address.Address {
|
||||
|
@ -3,9 +3,9 @@ package types
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
@ -4,8 +4,8 @@ import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
cborrpc "github.com/filecoin-project/lotus/lib/cborutil"
|
||||
"github.com/filecoin-project/go-address"
|
||||
cborrpc "github.com/filecoin-project/go-cbor-util"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
)
|
||||
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
vstate "github.com/filecoin-project/chain-validation/pkg/state"
|
||||
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/vm"
|
||||
)
|
||||
|
@ -2,7 +2,6 @@ package validation
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -11,8 +10,8 @@ import (
|
||||
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
|
||||
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/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@ -83,5 +82,15 @@ var methods = []uint64{
|
||||
vchain.StorageMinerGetWorkerAddr: actors.MAMethods.GetWorkerAddr,
|
||||
vchain.StorageMinerGetPeerID: actors.MAMethods.GetPeerID,
|
||||
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...
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ import (
|
||||
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
|
||||
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/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
)
|
||||
|
@ -18,14 +18,14 @@ import (
|
||||
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
|
||||
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/address"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/lotus/lib/crypto"
|
||||
)
|
||||
|
||||
type StateWrapper struct {
|
||||
|
@ -8,9 +8,9 @@ import (
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
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/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
@ -26,3 +26,10 @@ func TestValueTransfer(t *testing.T) {
|
||||
suites.AccountValueTransferFromUnknownToKnownAccount(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)
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"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) {
|
||||
c, err := vmc.cst.Put(context.TODO(), i)
|
||||
if err != nil {
|
||||
if aerr := vmc.ChargeGas(0); aerr != nil {
|
||||
return cid.Undef, aerrors.Absorb(err, outOfGasErrCode, "Put out of gas")
|
||||
}
|
||||
return cid.Undef, aerrors.Escalate(err, fmt.Sprintf("putting object %T", i))
|
||||
return cid.Undef, aerrors.HandleExternalError(err, fmt.Sprintf("putting object %T", i))
|
||||
}
|
||||
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 {
|
||||
err := vmc.cst.Get(context.TODO(), c, out)
|
||||
if err != nil {
|
||||
if aerr := vmc.ChargeGas(0); aerr != nil {
|
||||
return aerrors.Absorb(err, outOfGasErrCode, "Get out of gas")
|
||||
}
|
||||
return aerrors.Escalate(err, "getting cid")
|
||||
return aerrors.HandleExternalError(err, "getting cid")
|
||||
}
|
||||
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)
|
||||
|
||||
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 {
|
||||
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)
|
||||
|
@ -13,9 +13,9 @@ import (
|
||||
"github.com/minio/blake2b-simd"
|
||||
"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/lib/crypto"
|
||||
)
|
||||
|
||||
var log = logging.Logger("wallet")
|
||||
|
@ -28,7 +28,7 @@ var authCreateAdminToken = &cli.Command{
|
||||
},
|
||||
|
||||
Action: func(cctx *cli.Context) error {
|
||||
napi, closer, err := GetFullNodeAPI(cctx)
|
||||
napi, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
72
cli/chain.go
72
cli/chain.go
@ -25,6 +25,7 @@ var chainCmd = &cli.Command{
|
||||
chainGetMsgCmd,
|
||||
chainSetHeadCmd,
|
||||
chainListCmd,
|
||||
chainGetCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@ -218,6 +219,10 @@ var chainSetHeadCmd = &cli.Command{
|
||||
Name: "genesis",
|
||||
Usage: "reset head to genesis",
|
||||
},
|
||||
&cli.Uint64Flag{
|
||||
Name: "epoch",
|
||||
Usage: "reset head to given epoch",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
@ -227,25 +232,23 @@ var chainSetHeadCmd = &cli.Command{
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
gen := cctx.Bool("genesis")
|
||||
var ts *types.TipSet
|
||||
|
||||
if !cctx.Args().Present() && !gen {
|
||||
return fmt.Errorf("must pass cids for tipset to set as head")
|
||||
if cctx.Bool("genesis") {
|
||||
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 gen {
|
||||
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 ts == nil {
|
||||
return fmt.Errorf("must pass cids for tipset to set as head")
|
||||
}
|
||||
|
||||
if err := api.ChainSetHead(ctx, ts); err != nil {
|
||||
@ -319,7 +322,7 @@ var chainListCmd = &cli.Command{
|
||||
break
|
||||
}
|
||||
|
||||
head, err = api.ChainGetTipSet(ctx, types.NewTipSetKey(head.Parents()...))
|
||||
head, err = api.ChainGetTipSet(ctx, head.Parents())
|
||||
if err != nil {
|
||||
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) {
|
||||
format = strings.ReplaceAll(format, "<height>", fmt.Sprint(ts.Height()))
|
||||
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
Loading…
Reference in New Issue
Block a user