Merge remote-tracking branch 'origin/master' into asr/msig-set-locked
This commit is contained in:
commit
a19023fada
@ -254,6 +254,25 @@ jobs:
|
||||
path: /tmp/test-reports
|
||||
- store_artifacts:
|
||||
path: /tmp/test-artifacts/conformance-coverage.html
|
||||
build-lotus-soup:
|
||||
description: |
|
||||
Compile `lotus-soup` Testground test plan using the current version of Lotus.
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: cd extern/oni && git submodule sync
|
||||
- run: cd extern/oni && git submodule update --init
|
||||
- run: cd extern/filecoin-ffi && make
|
||||
- run:
|
||||
name: "replace lotus, filecoin-ffi, blst and fil-blst deps"
|
||||
command: cd extern/oni/lotus-soup && go mod edit -replace github.com/filecoin-project/lotus=../../../ && go mod edit -replace github.com/filecoin-project/filecoin-ffi=../../filecoin-ffi && go mod edit -replace github.com/supranational/blst=../../fil-blst/blst && go mod edit -replace github.com/filecoin-project/fil-blst=../../fil-blst
|
||||
- run:
|
||||
name: "build lotus-soup testplan"
|
||||
command: pushd extern/oni/lotus-soup && go build -tags=testground .
|
||||
|
||||
|
||||
build-macos:
|
||||
description: build darwin lotus binary
|
||||
@ -428,6 +447,7 @@ workflows:
|
||||
test-suite-name: conformance-bleeding-edge
|
||||
packages: "./conformance"
|
||||
vectors-branch: master
|
||||
- build-lotus-soup
|
||||
- build-debug
|
||||
- build-all:
|
||||
requires:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,6 +11,7 @@
|
||||
/lotus-stats
|
||||
/lotus-bench
|
||||
/lotus-gateway
|
||||
/lotus-pcr
|
||||
/bench.json
|
||||
/lotuspond/front/node_modules
|
||||
/lotuspond/front/build
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -11,3 +11,6 @@
|
||||
[submodule "extern/fil-blst"]
|
||||
path = extern/fil-blst
|
||||
url = https://github.com/filecoin-project/fil-blst.git
|
||||
[submodule "extern/oni"]
|
||||
path = extern/oni
|
||||
url = https://github.com/filecoin-project/oni
|
||||
|
59
CHANGELOG.md
59
CHANGELOG.md
@ -1,5 +1,64 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 0.7.2 / 2020-09-23
|
||||
|
||||
This optional release of Lotus introduces a major refactor around how a Lotus node interacts with code from the specs-actors repo. We now use interfaces to read the state of actors, which is required to be able to reason about different versions of actors code at the same time.
|
||||
|
||||
Additionally, this release introduces various improvements to the sync process, as well as changes to better the overall UX experience.
|
||||
|
||||
## Changes
|
||||
|
||||
#### Core Lotus
|
||||
|
||||
- Network upgrade support (https://github.com/filecoin-project/lotus/pull/3781)
|
||||
- Upgrade markets to `v0.6.2` (https://github.com/filecoin-project/lotus/pull/3974)
|
||||
- Validate chain sync response indices when fetching messages (https://github.com/filecoin-project/lotus/pull/3939)
|
||||
- Add height diff to sync wait (https://github.com/filecoin-project/lotus/pull/3926)
|
||||
- Replace Requires with Wants (https://github.com/filecoin-project/lotus/pull/3898)
|
||||
- Update state diffing for market actor (https://github.com/filecoin-project/lotus/pull/3889)
|
||||
- Parallel fetch for sync (https://github.com/filecoin-project/lotus/pull/3887)
|
||||
- Fix SectorState (https://github.com/filecoin-project/lotus/pull/3881)
|
||||
|
||||
#### User Experience
|
||||
|
||||
- Add basic deal stats api server for spacerace slingshot (https://github.com/filecoin-project/lotus/pull/3963)
|
||||
- When doing `sectors update-state`, show a list of existing states if user inputs an invalid one (https://github.com/filecoin-project/lotus/pull/3944)
|
||||
- Fix `lotus-miner storage find` error (https://github.com/filecoin-project/lotus/pull/3927)
|
||||
- Log shutdown method for lotus daemon and miner (https://github.com/filecoin-project/lotus/pull/3925)
|
||||
- Update build and setup instruction link (https://github.com/filecoin-project/lotus/pull/3919)
|
||||
- Add an option to hide removed sectors from `sectors list` output (https://github.com/filecoin-project/lotus/pull/3903)
|
||||
|
||||
#### Testing and validation
|
||||
|
||||
- Add init.State#Remove() for testing (https://github.com/filecoin-project/lotus/pull/3971)
|
||||
- lotus-shed: add consensus check command (https://github.com/filecoin-project/lotus/pull/3933)
|
||||
- Add keyinfo verify and jwt token command to lotus-shed (https://github.com/filecoin-project/lotus/pull/3914)
|
||||
- Fix conformance gen (https://github.com/filecoin-project/lotus/pull/3892)
|
||||
|
||||
# 0.7.1 / 2020-09-17
|
||||
|
||||
This optional release of Lotus introduces some critical fixes to the window PoSt process. It also upgrades some core dependencies, and introduces many improvements to the mining process, deal-making cycle, and overall User Experience.
|
||||
|
||||
## Changes
|
||||
|
||||
#### Some notable improvements:
|
||||
|
||||
- Correctly construct params for `SubmitWindowedPoSt` messages (https://github.com/filecoin-project/lotus/pull/3909)
|
||||
- Skip sectors correctly for Window PoSt (https://github.com/filecoin-project/lotus/pull/3839)
|
||||
- Split window PoST submission into multiple messages (https://github.com/filecoin-project/lotus/pull/3689)
|
||||
- Improve journal coverage (https://github.com/filecoin-project/lotus/pull/2455)
|
||||
- Allow retrievals while sealing (https://github.com/filecoin-project/lotus/pull/3778)
|
||||
- Don't prune locally published messages (https://github.com/filecoin-project/lotus/pull/3772)
|
||||
- Add get-ask, set-ask retrieval commands (https://github.com/filecoin-project/lotus/pull/3886)
|
||||
- Consistently name winning and window post in logs (https://github.com/filecoin-project/lotus/pull/3873))
|
||||
- Add auto flag to mpool replace (https://github.com/filecoin-project/lotus/pull/3752))
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- Upgrade markets to `v0.6.1` (https://github.com/filecoin-project/lotus/pull/3906)
|
||||
- Upgrade specs-actors to `v0.9.10` (https://github.com/filecoin-project/lotus/pull/3846)
|
||||
- Upgrade badger (https://github.com/filecoin-project/lotus/pull/3739)
|
||||
|
||||
# 0.7.0 / 2020-09-10
|
||||
|
||||
This consensus-breaking release of Lotus is designed to test a network upgrade on the space race testnet. The changes that break consensus are:
|
||||
|
@ -18,7 +18,7 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more
|
||||
|
||||
## Building & Documentation
|
||||
|
||||
For instructions on how to build lotus from source, please visit [https://lotu.sh](https://lotu.sh) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation).
|
||||
For instructions on how to build lotus from source, please visit [Lotus build and setup instruction](https://docs.filecoin.io/get-started/lotus/installation/#minimal-requirements) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation).
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
@ -5,9 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -20,12 +18,13 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
@ -77,6 +76,9 @@ type FullNode interface {
|
||||
// blockstore and returns raw bytes.
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
|
||||
// ChainDeleteObj deletes node referenced by the given CID
|
||||
ChainDeleteObj(context.Context, cid.Cid) error
|
||||
|
||||
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
|
||||
@ -231,7 +233,7 @@ type FullNode interface {
|
||||
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
||||
// WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid.
|
||||
// The address does not have to be in the wallet.
|
||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) bool
|
||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error)
|
||||
// WalletDefaultAddress returns the address marked as default in the wallet.
|
||||
WalletDefaultAddress(context.Context) (address.Address, error)
|
||||
// WalletSetDefault marks the given address as as the default one.
|
||||
@ -314,22 +316,20 @@ type FullNode interface {
|
||||
// StateNetworkName returns the name of the network the node is synced to
|
||||
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||
// StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included.
|
||||
// If the filterOut boolean is set to true, any sectors in the filter are excluded.
|
||||
// If false, only those sectors in the filter are included.
|
||||
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
||||
// StateMinerActiveSectors returns info about sectors that a given miner is actively proving.
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
||||
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
|
||||
// and returns the deadline-related calculations.
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
||||
// StateMinerPower returns the power of the indicated miner
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
// StateMinerInfo returns info about the indicated miner
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (MinerInfo, error)
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
|
||||
// StateMinerDeadlines returns all the proving deadlines for the given miner
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error)
|
||||
// StateMinerPartitions loads miner partitions for the specified miner/deadline
|
||||
StateMinerPartitions(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error)
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]Deadline, error)
|
||||
// StateMinerPartitions returns all partitions in the specified deadline
|
||||
StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]Partition, error)
|
||||
// StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
||||
// StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset
|
||||
@ -349,9 +349,9 @@ type FullNode interface {
|
||||
// expiration epoch
|
||||
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
// StateSectorExpiration returns epoch at which given sector will expire
|
||||
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*SectorExpiration, error)
|
||||
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error)
|
||||
// StateSectorPartition finds deadline/partition with the specified sector
|
||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*SectorLocation, error)
|
||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error)
|
||||
// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
|
||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||
// StateMsgGasCost searches for a message in the chain, and returns details of the messages gas costs, including the penalty and miner tip
|
||||
@ -388,13 +388,15 @@ type FullNode interface {
|
||||
// StateVerifiedClientStatus returns the data cap for the given address.
|
||||
// Returns nil if there is no entry in the data cap table for the
|
||||
// address.
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*verifreg.DataCap, error)
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
// StateDealProviderCollateralBounds returns the min and max collateral a storage provider
|
||||
// can issue. It takes the deal size and verified status as parameters.
|
||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
||||
|
||||
// StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
||||
// StateNetworkVersion returns the network version at the given tipset
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
|
||||
// MethodGroup: Msig
|
||||
// The Msig methods are used to interact with multisig wallets on the
|
||||
@ -476,21 +478,12 @@ type FileRef struct {
|
||||
}
|
||||
|
||||
type MinerSectors struct {
|
||||
Sectors uint64
|
||||
Active uint64
|
||||
}
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
// non-zero if sector is faulty, epoch at which it will be permanently
|
||||
// removed if it doesn't recover
|
||||
Early abi.ChainEpoch
|
||||
}
|
||||
|
||||
type SectorLocation struct {
|
||||
Deadline uint64
|
||||
Partition uint64
|
||||
// Live sectors that should be proven.
|
||||
Live uint64
|
||||
// Sectors actively contributing to power.
|
||||
Active uint64
|
||||
// Sectors with failed proofs.
|
||||
Faulty uint64
|
||||
}
|
||||
|
||||
type ImportRes struct {
|
||||
@ -556,11 +549,6 @@ type Message struct {
|
||||
Message *types.Message
|
||||
}
|
||||
|
||||
type ChainSectorInfo struct {
|
||||
Info miner.SectorOnChainInfo
|
||||
ID abi.SectorNumber
|
||||
}
|
||||
|
||||
type ActorState struct {
|
||||
Balance types.BigInt
|
||||
State interface{}
|
||||
@ -632,8 +620,9 @@ type VoucherCreateResult struct {
|
||||
}
|
||||
|
||||
type MinerPower struct {
|
||||
MinerPower power.Claim
|
||||
TotalPower power.Claim
|
||||
MinerPower power.Claim
|
||||
TotalPower power.Claim
|
||||
HasMinPower bool
|
||||
}
|
||||
|
||||
type QueryOffer struct {
|
||||
@ -736,6 +725,8 @@ type ActiveSync struct {
|
||||
|
||||
type SyncState struct {
|
||||
ActiveSyncs []ActiveSync
|
||||
|
||||
VMApplied uint64
|
||||
}
|
||||
|
||||
type SyncStateStage int
|
||||
@ -802,7 +793,7 @@ type CirculatingSupply struct {
|
||||
type MiningBaseInfo struct {
|
||||
MinerPower types.BigInt
|
||||
NetworkPower types.BigInt
|
||||
Sectors []proof.SectorInfo
|
||||
Sectors []builtin.SectorInfo
|
||||
WorkerKey address.Address
|
||||
SectorSize abi.SectorSize
|
||||
PrevBeaconEntry types.BeaconEntry
|
||||
@ -819,7 +810,7 @@ type BlockTemplate struct {
|
||||
Messages []*types.SignedMessage
|
||||
Epoch abi.ChainEpoch
|
||||
Timestamp uint64
|
||||
WinningPoStProof []proof.PoStProof
|
||||
WinningPoStProof []builtin.PoStProof
|
||||
}
|
||||
|
||||
type DataSize struct {
|
||||
@ -843,6 +834,18 @@ const (
|
||||
MsigCancel
|
||||
)
|
||||
|
||||
type Deadline struct {
|
||||
PostSubmissions bitfield.BitField
|
||||
}
|
||||
|
||||
type Partition struct {
|
||||
AllSectors bitfield.BitField
|
||||
FaultySectors bitfield.BitField
|
||||
RecoveringSectors bitfield.BitField
|
||||
LiveSectors bitfield.BitField
|
||||
ActiveSectors bitfield.BitField
|
||||
}
|
||||
|
||||
type Fault struct {
|
||||
Miner address.Address
|
||||
Epoch abi.ChainEpoch
|
||||
|
@ -71,7 +71,7 @@ type StorageMiner interface {
|
||||
stores.SectorIndex
|
||||
|
||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
|
||||
MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
MarketListDeals(ctx context.Context) ([]MarketDeal, error)
|
||||
MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error)
|
||||
MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error)
|
||||
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
|
||||
@ -83,7 +83,7 @@ type StorageMiner interface {
|
||||
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
||||
|
||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||
DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
DealsList(ctx context.Context) ([]MarketDeal, error)
|
||||
DealsConsiderOnlineStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOnlineStorageDeals(context.Context, bool) error
|
||||
DealsConsiderOnlineRetrievalDeals(context.Context) (bool, error)
|
||||
|
@ -1,12 +1,16 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func goCmd() string {
|
||||
@ -32,3 +36,68 @@ func TestDoesntDependOnFFI(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReturnTypes(t *testing.T) {
|
||||
errType := reflect.TypeOf(new(error)).Elem()
|
||||
bareIface := reflect.TypeOf(new(interface{})).Elem()
|
||||
jmarsh := reflect.TypeOf(new(json.Marshaler)).Elem()
|
||||
|
||||
tst := func(api interface{}) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
ra := reflect.TypeOf(api).Elem()
|
||||
for i := 0; i < ra.NumMethod(); i++ {
|
||||
m := ra.Method(i)
|
||||
switch m.Type.NumOut() {
|
||||
case 1: // if 1 return value, it must be an error
|
||||
require.Equal(t, errType, m.Type.Out(0), m.Name)
|
||||
|
||||
case 2: // if 2 return values, first cant be an interface/function, second must be an error
|
||||
seen := map[reflect.Type]struct{}{}
|
||||
todo := []reflect.Type{m.Type.Out(0)}
|
||||
for len(todo) > 0 {
|
||||
typ := todo[len(todo)-1]
|
||||
todo = todo[:len(todo)-1]
|
||||
|
||||
if _, ok := seen[typ]; ok {
|
||||
continue
|
||||
}
|
||||
seen[typ] = struct{}{}
|
||||
|
||||
if typ.Kind() == reflect.Interface && typ != bareIface && !typ.Implements(jmarsh) {
|
||||
t.Error("methods can't return interfaces", m.Name)
|
||||
}
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Ptr:
|
||||
fallthrough
|
||||
case reflect.Array:
|
||||
fallthrough
|
||||
case reflect.Slice:
|
||||
fallthrough
|
||||
case reflect.Chan:
|
||||
todo = append(todo, typ.Elem())
|
||||
case reflect.Map:
|
||||
todo = append(todo, typ.Elem())
|
||||
todo = append(todo, typ.Key())
|
||||
case reflect.Struct:
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
todo = append(todo, typ.Field(i).Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require.NotEqual(t, reflect.Func.String(), m.Type.Out(0).Kind().String(), m.Name)
|
||||
require.Equal(t, errType, m.Type.Out(1), m.Name)
|
||||
|
||||
default:
|
||||
t.Error("methods can only have 1 or 2 return values", m.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("common", tst(new(Common)))
|
||||
t.Run("full", tst(new(FullNode)))
|
||||
t.Run("miner", tst(new(StorageMiner)))
|
||||
t.Run("worker", tst(new(WorkerAPI)))
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
stnetwork "github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
@ -23,18 +23,18 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
@ -87,6 +87,7 @@ type FullNodeStruct struct {
|
||||
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
|
||||
ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
||||
ChainDeleteObj func(context.Context, cid.Cid) error `perm:"admin"`
|
||||
ChainHasObj func(context.Context, cid.Cid) (bool, error) `perm:"read"`
|
||||
ChainStatObj func(context.Context, cid.Cid, cid.Cid) (api.ObjStat, error) `perm:"read"`
|
||||
ChainSetHead func(context.Context, types.TipSetKey) error `perm:"admin"`
|
||||
@ -134,7 +135,7 @@ type FullNodeStruct struct {
|
||||
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
||||
WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"`
|
||||
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
||||
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) bool `perm:"read"`
|
||||
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) `perm:"read"`
|
||||
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
|
||||
WalletSetDefault func(context.Context, address.Address) error `perm:"admin"`
|
||||
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
@ -162,13 +163,13 @@ type FullNodeStruct struct {
|
||||
ClientRetrieveTryRestartInsufficientFunds func(ctx context.Context, paymentChannel address.Address) error `perm:"write"`
|
||||
|
||||
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
|
||||
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
|
||||
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error) `perm:"read"`
|
||||
StateMinerPartitions func(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error) `perm:"read"`
|
||||
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) `perm:"read"`
|
||||
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]api.Deadline, error) `perm:"read"`
|
||||
StateMinerPartitions func(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]api.Partition, error) `perm:"read"`
|
||||
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
StateAllMinerFaults func(context.Context, abi.ChainEpoch, types.TipSetKey) ([]*api.Fault, error) `perm:"read"`
|
||||
StateMinerRecoveries func(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
@ -177,8 +178,8 @@ type FullNodeStruct struct {
|
||||
StateMinerAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateSectorPreCommitInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
|
||||
StateSectorGetInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateSectorExpiration func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*api.SectorExpiration, error) `perm:"read"`
|
||||
StateSectorPartition func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*api.SectorLocation, error) `perm:"read"`
|
||||
StateSectorExpiration func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"`
|
||||
StateSectorPartition func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorLocation, error) `perm:"read"`
|
||||
StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) `perm:"read"`
|
||||
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
@ -199,9 +200,10 @@ type FullNodeStruct struct {
|
||||
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
|
||||
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*verifreg.DataCap, error) `perm:"read"`
|
||||
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
|
||||
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||
StateNetworkVersion func(context.Context, types.TipSetKey) (stnetwork.Version, error) `perm:"read"`
|
||||
|
||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigGetVested func(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
@ -252,7 +254,7 @@ type StorageMinerStruct struct {
|
||||
MiningBase func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"`
|
||||
MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
MarketListDeals func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
|
||||
MarketListRetrievalDeals func(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"`
|
||||
MarketGetDealUpdates func(ctx context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"`
|
||||
MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"`
|
||||
@ -297,7 +299,7 @@ type StorageMinerStruct struct {
|
||||
StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"`
|
||||
|
||||
DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"`
|
||||
DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
|
||||
DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
@ -605,7 +607,7 @@ func (c *FullNodeStruct) WalletSignMessage(ctx context.Context, k address.Addres
|
||||
return c.Internal.WalletSignMessage(ctx, k, msg)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) bool {
|
||||
func (c *FullNodeStruct) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) {
|
||||
return c.Internal.WalletVerify(ctx, k, msg, sig)
|
||||
}
|
||||
|
||||
@ -661,6 +663,10 @@ func (c *FullNodeStruct) ChainReadObj(ctx context.Context, obj cid.Cid) ([]byte,
|
||||
return c.Internal.ChainReadObj(ctx, obj)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainDeleteObj(ctx context.Context, obj cid.Cid) error {
|
||||
return c.Internal.ChainDeleteObj(ctx, obj)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainHasObj(ctx context.Context, o cid.Cid) (bool, error) {
|
||||
return c.Internal.ChainHasObj(ctx, o)
|
||||
}
|
||||
@ -733,11 +739,11 @@ func (c *FullNodeStruct) StateNetworkName(ctx context.Context) (dtypes.NetworkNa
|
||||
return c.Internal.StateNetworkName(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, filter *bitfield.BitField, filterOut bool, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
return c.Internal.StateMinerSectors(ctx, addr, filter, filterOut, tsk)
|
||||
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*miner.SectorOnChainInfo, error) {
|
||||
return c.Internal.StateMinerSectors(ctx, addr, sectorNos, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*miner.SectorOnChainInfo, error) {
|
||||
return c.Internal.StateMinerActiveSectors(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
@ -749,15 +755,15 @@ func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address,
|
||||
return c.Internal.StateMinerPower(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error) {
|
||||
func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
|
||||
return c.Internal.StateMinerInfo(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]*miner.Deadline, error) {
|
||||
return c.Internal.StateMinerDeadlines(ctx, m, tsk)
|
||||
func (c *FullNodeStruct) StateMinerDeadlines(ctx context.Context, actor address.Address, tsk types.TipSetKey) ([]api.Deadline, error) {
|
||||
return c.Internal.StateMinerDeadlines(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]*miner.Partition, error) {
|
||||
func (c *FullNodeStruct) StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]api.Partition, error) {
|
||||
return c.Internal.StateMinerPartitions(ctx, m, dlIdx, tsk)
|
||||
}
|
||||
|
||||
@ -793,11 +799,11 @@ func (c *FullNodeStruct) StateSectorGetInfo(ctx context.Context, maddr address.A
|
||||
return c.Internal.StateSectorGetInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSectorExpiration(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*api.SectorExpiration, error) {
|
||||
func (c *FullNodeStruct) StateSectorExpiration(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorExpiration, error) {
|
||||
return c.Internal.StateSectorExpiration(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*api.SectorLocation, error) {
|
||||
func (c *FullNodeStruct) StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) {
|
||||
return c.Internal.StateSectorPartition(ctx, maddr, sectorNumber, tok)
|
||||
}
|
||||
|
||||
@ -877,7 +883,7 @@ func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch
|
||||
return c.Internal.StateCompute(ctx, height, msgs, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*verifreg.DataCap, error) {
|
||||
func (c *FullNodeStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) {
|
||||
return c.Internal.StateVerifiedClientStatus(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
@ -889,6 +895,10 @@ func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.T
|
||||
return c.Internal.StateCirculatingSupply(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
|
||||
return c.Internal.StateNetworkVersion(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.Address, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.MsigGetAvailableBalance(ctx, a, tsk)
|
||||
}
|
||||
@ -1137,7 +1147,7 @@ func (c *StorageMinerStruct) MarketImportDealData(ctx context.Context, propcid c
|
||||
return c.Internal.MarketImportDealData(ctx, propcid, path)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error) {
|
||||
func (c *StorageMinerStruct) MarketListDeals(ctx context.Context) ([]api.MarketDeal, error) {
|
||||
return c.Internal.MarketListDeals(ctx)
|
||||
}
|
||||
|
||||
@ -1181,7 +1191,7 @@ func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid ci
|
||||
return c.Internal.DealsImportData(ctx, dealPropCid, file)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) {
|
||||
func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]api.MarketDeal, error) {
|
||||
return c.Internal.DealsList(ctx)
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,7 @@ func init() {
|
||||
addExample(retrievalmarket.ClientEventDealAccepted)
|
||||
addExample(retrievalmarket.DealStatusNew)
|
||||
addExample(network.ReachabilityPublic)
|
||||
addExample(build.NewestNetworkVersion)
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: exampleValue(reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
|
@ -85,6 +85,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
{
|
||||
exp, err := client.StateSectorExpiration(ctx, maddr, CC, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, exp)
|
||||
require.Greater(t, 50000, int(exp.OnTime))
|
||||
}
|
||||
{
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -159,7 +158,7 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
|
||||
break
|
||||
}
|
||||
|
||||
@ -186,12 +185,14 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(parts), 0)
|
||||
|
||||
n, err := parts[0].Sectors.Count()
|
||||
secs := parts[0].AllSectors
|
||||
require.NoError(t, err)
|
||||
n, err := secs.Count()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), n)
|
||||
|
||||
// Drop the partition
|
||||
err = parts[0].Sectors.ForEach(func(sid uint64) error {
|
||||
err = secs.ForEach(func(sid uint64) error {
|
||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sid),
|
||||
@ -208,15 +209,17 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(parts), 0)
|
||||
|
||||
n, err := parts[0].Sectors.Count()
|
||||
secs := parts[0].AllSectors
|
||||
require.NoError(t, err)
|
||||
n, err := secs.Count()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), n)
|
||||
|
||||
// Drop the sector
|
||||
sn, err := parts[0].Sectors.First()
|
||||
sn, err := secs.First()
|
||||
require.NoError(t, err)
|
||||
|
||||
all, err := parts[0].Sectors.All(2)
|
||||
all, err := secs.All(2)
|
||||
require.NoError(t, err)
|
||||
fmt.Println("the sectors", all)
|
||||
|
||||
@ -238,7 +241,7 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
|
||||
break
|
||||
}
|
||||
|
||||
@ -268,7 +271,7 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
||||
break
|
||||
}
|
||||
|
||||
|
44
api/types.go
44
api/types.go
@ -4,11 +4,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -49,48 +47,6 @@ type PubsubScore struct {
|
||||
Score *pubsub.PeerScoreSnapshot
|
||||
}
|
||||
|
||||
type MinerInfo struct {
|
||||
Owner address.Address // Must be an ID-address.
|
||||
Worker address.Address // Must be an ID-address.
|
||||
NewWorker address.Address // Must be an ID-address.
|
||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId *peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
SealProofType abi.RegisteredSealProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
}
|
||||
|
||||
func NewApiMinerInfo(info *miner.MinerInfo) MinerInfo {
|
||||
var pid *peer.ID
|
||||
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
||||
pid = &peerID
|
||||
}
|
||||
|
||||
mi := MinerInfo{
|
||||
Owner: info.Owner,
|
||||
Worker: info.Worker,
|
||||
ControlAddresses: info.ControlAddresses,
|
||||
|
||||
NewWorker: address.Undef,
|
||||
WorkerChangeEpoch: -1,
|
||||
|
||||
PeerId: pid,
|
||||
Multiaddrs: info.Multiaddrs,
|
||||
SealProofType: info.SealProofType,
|
||||
SectorSize: info.SectorSize,
|
||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi
|
||||
}
|
||||
|
||||
type MessageSendSpec struct {
|
||||
MaxFee abi.TokenAmount
|
||||
}
|
||||
|
@ -4,10 +4,8 @@ package build
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
const UpgradeBreezeHeight = -1
|
||||
@ -20,11 +18,9 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
}
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
@ -6,14 +6,14 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
func DefaultSectorSize() abi.SectorSize {
|
||||
szs := make([]abi.SectorSize, 0, len(miner.SupportedProofTypes))
|
||||
for spt := range miner.SupportedProofTypes {
|
||||
szs := make([]abi.SectorSize, 0, len(miner0.SupportedProofTypes))
|
||||
for spt := range miner0.SupportedProofTypes {
|
||||
ss, err := spt.SectorSize()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
)
|
||||
|
||||
// /////
|
||||
@ -23,6 +23,7 @@ const UnixfsLinksPerLevel = 1024
|
||||
|
||||
const AllowableClockDriftSecs = uint64(1)
|
||||
const NewestNetworkVersion = network.Version2
|
||||
const ActorUpgradeNetworkVersion = network.Version3
|
||||
|
||||
// Epochs
|
||||
const ForkLengthThreshold = Finality
|
||||
@ -31,7 +32,7 @@ const ForkLengthThreshold = Finality
|
||||
var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
|
||||
|
||||
// Epochs
|
||||
const Finality = miner.ChainFinality
|
||||
const Finality = miner0.ChainFinality
|
||||
const MessageConfidence = uint64(5)
|
||||
|
||||
// constants for Weight calculation
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -32,7 +32,7 @@ var (
|
||||
|
||||
AllowableClockDriftSecs = uint64(1)
|
||||
|
||||
Finality = miner.ChainFinality
|
||||
Finality = miner0.ChainFinality
|
||||
ForkLengthThreshold = Finality
|
||||
|
||||
SlashablePowerDelay = 20
|
||||
@ -80,5 +80,6 @@ var (
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
NewestNetworkVersion = network.Version2
|
||||
NewestNetworkVersion = network.Version2
|
||||
ActorUpgradeNetworkVersion = network.Version3
|
||||
)
|
||||
|
@ -6,10 +6,9 @@ package build
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
@ -23,13 +22,13 @@ const BreezeGasTampingDuration = 120
|
||||
const UpgradeSmokeHeight = 51000
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(10 << 40)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
|
||||
}
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
||||
policy.SetSupportedProofTypes(
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
)
|
||||
}
|
||||
|
||||
const BlockDelaySecs = uint64(builtin.EpochDurationSeconds)
|
||||
const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds)
|
||||
|
||||
const PropagationDelaySecs = uint64(6)
|
||||
|
@ -29,7 +29,7 @@ func buildType() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "0.7.0"
|
||||
const BuildVersion = "0.7.2"
|
||||
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
@ -83,9 +83,9 @@ func VersionForType(nodeType NodeType) (Version, error) {
|
||||
|
||||
// semver versions of the rpc api exposed
|
||||
var (
|
||||
FullAPIVersion = newVer(0, 14, 0)
|
||||
MinerAPIVersion = newVer(0, 14, 0)
|
||||
WorkerAPIVersion = newVer(0, 14, 0)
|
||||
FullAPIVersion = newVer(0, 16, 0)
|
||||
MinerAPIVersion = newVer(0, 15, 0)
|
||||
WorkerAPIVersion = newVer(0, 15, 0)
|
||||
)
|
||||
|
||||
//nolint:varcheck,deadcode
|
||||
|
65
chain/actors/adt/adt.go
Normal file
65
chain/actors/adt/adt.go
Normal file
@ -0,0 +1,65 @@
|
||||
package adt
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
type Map interface {
|
||||
Root() (cid.Cid, error)
|
||||
|
||||
Put(k abi.Keyer, v cbor.Marshaler) error
|
||||
Get(k abi.Keyer, v cbor.Unmarshaler) (bool, error)
|
||||
Delete(k abi.Keyer) error
|
||||
|
||||
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
||||
}
|
||||
|
||||
func AsMap(store Store, root cid.Cid, version builtin.Version) (Map, error) {
|
||||
switch version {
|
||||
case builtin.Version0:
|
||||
return adt0.AsMap(store, root)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
func NewMap(store Store, version builtin.Version) (Map, error) {
|
||||
switch version {
|
||||
case builtin.Version0:
|
||||
return adt0.MakeEmptyMap(store), nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
type Array interface {
|
||||
Root() (cid.Cid, error)
|
||||
|
||||
Set(idx uint64, v cbor.Marshaler) error
|
||||
Get(idx uint64, v cbor.Unmarshaler) (bool, error)
|
||||
Delete(idx uint64) error
|
||||
Length() uint64
|
||||
|
||||
ForEach(v cbor.Unmarshaler, fn func(idx int64) error) error
|
||||
}
|
||||
|
||||
func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) {
|
||||
switch builtin.VersionForNetwork(version) {
|
||||
case builtin.Version0:
|
||||
return adt0.AsArray(store, root)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
func NewArray(store Store, version builtin.Version) (Array, error) {
|
||||
switch version {
|
||||
case builtin.Version0:
|
||||
return adt0.MakeEmptyArray(store), nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
package state
|
||||
package adt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
@ -27,7 +26,8 @@ type AdtArrayDiff interface {
|
||||
// - All values that exist in curArr nnd not in prevArr are passed to adtArrayDiff.Add()
|
||||
// - All values that exist in preArr and in curArr are passed to AdtArrayDiff.Modify()
|
||||
// - It is the responsibility of AdtArrayDiff.Modify() to determine if the values it was passed have been modified.
|
||||
func DiffAdtArray(preArr, curArr *adt.Array, out AdtArrayDiff) error {
|
||||
func DiffAdtArray(preArr, curArr Array, out AdtArrayDiff) error {
|
||||
notNew := make(map[int64]struct{}, curArr.Length())
|
||||
prevVal := new(typegen.Deferred)
|
||||
if err := preArr.ForEach(prevVal, func(i int64) error {
|
||||
curVal := new(typegen.Deferred)
|
||||
@ -48,14 +48,17 @@ func DiffAdtArray(preArr, curArr *adt.Array, out AdtArrayDiff) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return curArr.Delete(uint64(i))
|
||||
notNew[i] = struct{}{}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
curVal := new(typegen.Deferred)
|
||||
return curArr.ForEach(curVal, func(i int64) error {
|
||||
if _, ok := notNew[i]; ok {
|
||||
return nil
|
||||
}
|
||||
return out.Add(uint64(i), curVal)
|
||||
})
|
||||
}
|
||||
@ -76,7 +79,8 @@ type AdtMapDiff interface {
|
||||
Remove(key string, val *typegen.Deferred) error
|
||||
}
|
||||
|
||||
func DiffAdtMap(preMap, curMap *adt.Map, out AdtMapDiff) error {
|
||||
func DiffAdtMap(preMap, curMap Map, out AdtMapDiff) error {
|
||||
notNew := make(map[string]struct{})
|
||||
prevVal := new(typegen.Deferred)
|
||||
if err := preMap.ForEach(prevVal, func(key string) error {
|
||||
curVal := new(typegen.Deferred)
|
||||
@ -102,14 +106,17 @@ func DiffAdtMap(preMap, curMap *adt.Map, out AdtMapDiff) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return curMap.Delete(k)
|
||||
notNew[key] = struct{}{}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
curVal := new(typegen.Deferred)
|
||||
return curMap.ForEach(curVal, func(key string) error {
|
||||
if _, ok := notNew[key]; ok {
|
||||
return nil
|
||||
}
|
||||
return out.Add(key, curVal)
|
||||
})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package state
|
||||
package adt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
)
|
||||
@ -22,8 +22,8 @@ func TestDiffAdtArray(t *testing.T) {
|
||||
ctxstoreA := newContextStore()
|
||||
ctxstoreB := newContextStore()
|
||||
|
||||
arrA := adt.MakeEmptyArray(ctxstoreA)
|
||||
arrB := adt.MakeEmptyArray(ctxstoreB)
|
||||
arrA := adt0.MakeEmptyArray(ctxstoreA)
|
||||
arrB := adt0.MakeEmptyArray(ctxstoreB)
|
||||
|
||||
require.NoError(t, arrA.Set(0, runtime.CBORBytes([]byte{0}))) // delete
|
||||
|
||||
@ -76,8 +76,8 @@ func TestDiffAdtMap(t *testing.T) {
|
||||
ctxstoreA := newContextStore()
|
||||
ctxstoreB := newContextStore()
|
||||
|
||||
mapA := adt.MakeEmptyMap(ctxstoreA)
|
||||
mapB := adt.MakeEmptyMap(ctxstoreB)
|
||||
mapA := adt0.MakeEmptyMap(ctxstoreA)
|
||||
mapB := adt0.MakeEmptyMap(ctxstoreB)
|
||||
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(0), runtime.CBORBytes([]byte{0}))) // delete
|
||||
|
||||
@ -292,12 +292,9 @@ func (t *TestDiffArray) Remove(key uint64, val *typegen.Deferred) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newContextStore() *contextStore {
|
||||
func newContextStore() Store {
|
||||
ctx := context.Background()
|
||||
bs := bstore.NewTemporarySync()
|
||||
store := cbornode.NewCborStore(bs)
|
||||
return &contextStore{
|
||||
ctx: ctx,
|
||||
cst: store,
|
||||
}
|
||||
return WrapStore(ctx, store)
|
||||
}
|
17
chain/actors/adt/store.go
Normal file
17
chain/actors/adt/store.go
Normal file
@ -0,0 +1,17 @@
|
||||
package adt
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
adt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
Context() context.Context
|
||||
cbor.IpldStore
|
||||
}
|
||||
|
||||
func WrapStore(ctx context.Context, store cbor.IpldStore) Store {
|
||||
return adt.WrapStore(ctx, store)
|
||||
}
|
29
chain/actors/builtin/README.md
Normal file
29
chain/actors/builtin/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Actors
|
||||
|
||||
This package contains shims for abstracting over different actor versions.
|
||||
|
||||
## Design
|
||||
|
||||
Shims in this package follow a few common design principles.
|
||||
|
||||
### Structure Agnostic
|
||||
|
||||
Shims interfaces defined in this package should (ideally) not change even if the
|
||||
structure of the underlying data changes. For example:
|
||||
|
||||
* All shims store an internal "store" object. That way, state can be moved into
|
||||
a separate object without needing to add a store to the function signature.
|
||||
* All functions must return an error, even if unused for now.
|
||||
|
||||
### Minimal
|
||||
|
||||
These interfaces should be expanded only as necessary to reduce maintenance burden.
|
||||
|
||||
### Queries, not field assessors.
|
||||
|
||||
When possible, functions should query the state instead of simply acting as
|
||||
field assessors. These queries are more likely to remain stable across
|
||||
specs-actor upgrades than specific state fields.
|
||||
|
||||
Note: there is a trade-off here. Avoid implementing _complicated_ query logic
|
||||
inside these shims, as it will need to be replicated in every shim.
|
31
chain/actors/builtin/account/account.go
Normal file
31
chain/actors/builtin/account/account.go
Normal file
@ -0,0 +1,31 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.AccountActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
PubkeyAddress() (address.Address, error)
|
||||
}
|
18
chain/actors/builtin/account/v0.go
Normal file
18
chain/actors/builtin/account/v0.go
Normal file
@ -0,0 +1,18 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
account.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
43
chain/actors/builtin/builtin.go
Normal file
43
chain/actors/builtin/builtin.go
Normal file
@ -0,0 +1,43 @@
|
||||
package builtin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
)
|
||||
|
||||
type Version int
|
||||
|
||||
const (
|
||||
Version0 = iota
|
||||
)
|
||||
|
||||
// Converts a network version into a specs-actors version.
|
||||
func VersionForNetwork(version network.Version) Version {
|
||||
switch version {
|
||||
case network.Version0, network.Version1, network.Version2:
|
||||
return Version0
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Why does actors have 2 different versions of this?
|
||||
type SectorInfo = proof0.SectorInfo
|
||||
type PoStProof = proof0.PoStProof
|
||||
type FilterEstimate = smoothing0.FilterEstimate
|
||||
|
||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
||||
return (FilterEstimate)(v0)
|
||||
}
|
||||
|
||||
// Doesn't change between actors v0 and v1
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||
}
|
44
chain/actors/builtin/init/init.go
Normal file
44
chain/actors/builtin/init/init.go
Normal file
@ -0,0 +1,44 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
var Address = builtin0.InitActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.InitActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
ResolveAddress(address address.Address) (address.Address, bool, error)
|
||||
MapAddressToNewID(address address.Address) (address.Address, error)
|
||||
NetworkName() (dtypes.NetworkName, error)
|
||||
|
||||
ForEachActor(func(id abi.ActorID, address address.Address) error) error
|
||||
|
||||
// Remove exists to support tooling that manipulates state for testing.
|
||||
// It should not be used in production code, as init actor entries are
|
||||
// immutable.
|
||||
Remove(addrs ...address.Address) error
|
||||
}
|
67
chain/actors/builtin/init/v0.go
Normal file
67
chain/actors/builtin/init/v0.go
Normal file
@ -0,0 +1,67 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
init_.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
||||
return s.State.ResolveAddress(s.store, address)
|
||||
}
|
||||
|
||||
func (s *state0) MapAddressToNewID(address address.Address) (address.Address, error) {
|
||||
return s.State.MapAddressToNewID(s.store, address)
|
||||
}
|
||||
|
||||
func (s *state0) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
|
||||
addrs, err := adt0.AsMap(s.store, s.State.AddressMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var actorID cbg.CborInt
|
||||
return addrs.ForEach(&actorID, func(key string) error {
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(abi.ActorID(actorID), addr)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state0) NetworkName() (dtypes.NetworkName, error) {
|
||||
return dtypes.NetworkName(s.State.NetworkName), nil
|
||||
}
|
||||
|
||||
func (s *state0) Remove(addrs ...address.Address) (err error) {
|
||||
m, err := adt0.AsMap(s.store, s.State.AddressMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if err = m.Delete(abi.AddrKey(addr)); err != nil {
|
||||
return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err)
|
||||
}
|
||||
}
|
||||
amr, err := m.Root()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get address map root: %w", err)
|
||||
}
|
||||
s.State.AddressMap = amr
|
||||
return nil
|
||||
}
|
91
chain/actors/builtin/market/diff.go
Normal file
91
chain/actors/builtin/market/diff.go
Normal file
@ -0,0 +1,91 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
func DiffDealProposals(pre, cur DealProposals) (*DealProposalChanges, error) {
|
||||
results := new(DealProposalChanges)
|
||||
if err := adt.DiffAdtArray(pre.array(), cur.array(), &marketProposalsDiffer{results, pre, cur}); err != nil {
|
||||
return nil, fmt.Errorf("diffing deal states: %w", err)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type marketProposalsDiffer struct {
|
||||
Results *DealProposalChanges
|
||||
pre, cur DealProposals
|
||||
}
|
||||
|
||||
func (d *marketProposalsDiffer) Add(key uint64, val *cbg.Deferred) error {
|
||||
dp, err := d.cur.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Added = append(d.Results.Added, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketProposalsDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
||||
// short circuit, DealProposals are static
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketProposalsDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
||||
dp, err := d.pre.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Removed = append(d.Results.Removed, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
func DiffDealStates(pre, cur DealStates) (*DealStateChanges, error) {
|
||||
results := new(DealStateChanges)
|
||||
if err := adt.DiffAdtArray(pre.array(), cur.array(), &marketStatesDiffer{results, pre, cur}); err != nil {
|
||||
return nil, fmt.Errorf("diffing deal states: %w", err)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type marketStatesDiffer struct {
|
||||
Results *DealStateChanges
|
||||
pre, cur DealStates
|
||||
}
|
||||
|
||||
func (d *marketStatesDiffer) Add(key uint64, val *cbg.Deferred) error {
|
||||
ds, err := d.cur.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Added = append(d.Results.Added, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketStatesDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
||||
dsFrom, err := d.pre.decode(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dsTo, err := d.cur.decode(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if *dsFrom != *dsTo {
|
||||
d.Results.Modified = append(d.Results.Modified, DealStateChange{abi.DealID(key), dsFrom, dsTo})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketStatesDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
||||
ds, err := d.pre.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Removed = append(d.Results.Removed, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
129
chain/actors/builtin/market/market.go
Normal file
129
chain/actors/builtin/market/market.go
Normal file
@ -0,0 +1,129 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var Address = builtin0.StorageMarketActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.StorageMarketActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
BalancesChanged(State) (bool, error)
|
||||
EscrowTable() (BalanceTable, error)
|
||||
LockedTable() (BalanceTable, error)
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
StatesChanged(State) (bool, error)
|
||||
States() (DealStates, error)
|
||||
ProposalsChanged(State) (bool, error)
|
||||
Proposals() (DealProposals, error)
|
||||
VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error)
|
||||
}
|
||||
|
||||
type BalanceTable interface {
|
||||
ForEach(cb func(address.Address, abi.TokenAmount) error) error
|
||||
Get(key address.Address) (abi.TokenAmount, error)
|
||||
}
|
||||
|
||||
type DealStates interface {
|
||||
ForEach(cb func(id abi.DealID, ds DealState) error) error
|
||||
Get(id abi.DealID) (*DealState, bool, error)
|
||||
|
||||
array() adt.Array
|
||||
decode(*cbg.Deferred) (*DealState, error)
|
||||
}
|
||||
|
||||
type DealProposals interface {
|
||||
ForEach(cb func(id abi.DealID, dp DealProposal) error) error
|
||||
Get(id abi.DealID) (*DealProposal, bool, error)
|
||||
|
||||
array() adt.Array
|
||||
decode(*cbg.Deferred) (*DealProposal, error)
|
||||
}
|
||||
|
||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
||||
|
||||
type ClientDealProposal = market0.ClientDealProposal
|
||||
|
||||
type DealState struct {
|
||||
SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector
|
||||
LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated
|
||||
SlashEpoch abi.ChainEpoch // -1 if deal never slashed
|
||||
}
|
||||
|
||||
type DealProposal struct {
|
||||
PieceCID cid.Cid
|
||||
PieceSize abi.PaddedPieceSize
|
||||
VerifiedDeal bool
|
||||
Client address.Address
|
||||
Provider address.Address
|
||||
Label string
|
||||
StartEpoch abi.ChainEpoch
|
||||
EndEpoch abi.ChainEpoch
|
||||
StoragePricePerEpoch abi.TokenAmount
|
||||
ProviderCollateral abi.TokenAmount
|
||||
ClientCollateral abi.TokenAmount
|
||||
}
|
||||
|
||||
type DealStateChanges struct {
|
||||
Added []DealIDState
|
||||
Modified []DealStateChange
|
||||
Removed []DealIDState
|
||||
}
|
||||
|
||||
type DealIDState struct {
|
||||
ID abi.DealID
|
||||
Deal DealState
|
||||
}
|
||||
|
||||
// DealStateChange is a change in deal state from -> to
|
||||
type DealStateChange struct {
|
||||
ID abi.DealID
|
||||
From *DealState
|
||||
To *DealState
|
||||
}
|
||||
|
||||
type DealProposalChanges struct {
|
||||
Added []ProposalIDState
|
||||
Removed []ProposalIDState
|
||||
}
|
||||
|
||||
type ProposalIDState struct {
|
||||
ID abi.DealID
|
||||
Proposal DealProposal
|
||||
}
|
||||
|
||||
func EmptyDealState() *DealState {
|
||||
return &DealState{
|
||||
SectorStartEpoch: -1,
|
||||
SlashEpoch: -1,
|
||||
LastUpdatedEpoch: -1,
|
||||
}
|
||||
}
|
192
chain/actors/builtin/market/v0.go
Normal file
192
chain/actors/builtin/market/v0.go
Normal file
@ -0,0 +1,192 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
market.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) TotalLocked() (abi.TokenAmount, error) {
|
||||
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
||||
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
||||
return fml, nil
|
||||
}
|
||||
|
||||
func (s *state0) BalancesChanged(otherState State) (bool, error) {
|
||||
otherState0, ok := otherState.(*state0)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.EscrowTable.Equals(otherState0.State.EscrowTable) || !s.State.LockedTable.Equals(otherState0.State.LockedTable), nil
|
||||
}
|
||||
|
||||
func (s *state0) StatesChanged(otherState State) (bool, error) {
|
||||
otherState0, ok := otherState.(*state0)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.States.Equals(otherState0.State.States), nil
|
||||
}
|
||||
|
||||
func (s *state0) States() (DealStates, error) {
|
||||
stateArray, err := adt0.AsArray(s.store, s.State.States)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dealStates0{stateArray}, nil
|
||||
}
|
||||
|
||||
func (s *state0) ProposalsChanged(otherState State) (bool, error) {
|
||||
otherState0, ok := otherState.(*state0)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Proposals.Equals(otherState0.State.Proposals), nil
|
||||
}
|
||||
|
||||
func (s *state0) Proposals() (DealProposals, error) {
|
||||
proposalArray, err := adt0.AsArray(s.store, s.State.Proposals)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dealProposals0{proposalArray}, nil
|
||||
}
|
||||
|
||||
func (s *state0) EscrowTable() (BalanceTable, error) {
|
||||
bt, err := adt0.AsBalanceTable(s.store, s.State.EscrowTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &balanceTable0{bt}, nil
|
||||
}
|
||||
|
||||
func (s *state0) LockedTable() (BalanceTable, error) {
|
||||
bt, err := adt0.AsBalanceTable(s.store, s.State.LockedTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &balanceTable0{bt}, nil
|
||||
}
|
||||
|
||||
func (s *state0) VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error) {
|
||||
return market.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||
}
|
||||
|
||||
type balanceTable0 struct {
|
||||
*adt0.BalanceTable
|
||||
}
|
||||
|
||||
func (bt *balanceTable0) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
|
||||
asMap := (*adt0.Map)(bt.BalanceTable)
|
||||
var ta abi.TokenAmount
|
||||
return asMap.ForEach(&ta, func(key string) error {
|
||||
a, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(a, ta)
|
||||
})
|
||||
}
|
||||
|
||||
type dealStates0 struct {
|
||||
adt.Array
|
||||
}
|
||||
|
||||
func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||
var deal0 market.DealState
|
||||
found, err := s.Array.Get(uint64(dealID), &deal0)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
deal := fromV0DealState(deal0)
|
||||
return &deal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealStates0) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||
var ds0 market.DealState
|
||||
return s.Array.ForEach(&ds0, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV0DealState(ds0))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealStates0) decode(val *cbg.Deferred) (*DealState, error) {
|
||||
var ds0 market.DealState
|
||||
if err := ds0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ds := fromV0DealState(ds0)
|
||||
return &ds, nil
|
||||
}
|
||||
|
||||
func (s *dealStates0) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV0DealState(v0 market.DealState) DealState {
|
||||
return (DealState)(v0)
|
||||
}
|
||||
|
||||
type dealProposals0 struct {
|
||||
adt.Array
|
||||
}
|
||||
|
||||
func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||
var proposal0 market.DealProposal
|
||||
found, err := s.Array.Get(uint64(dealID), &proposal0)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
proposal := fromV0DealProposal(proposal0)
|
||||
return &proposal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals0) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||
var dp0 market.DealProposal
|
||||
return s.Array.ForEach(&dp0, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV0DealProposal(dp0))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealProposals0) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||
var dp0 market.DealProposal
|
||||
if err := dp0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dp := fromV0DealProposal(dp0)
|
||||
return &dp, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals0) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV0DealProposal(v0 market.DealProposal) DealProposal {
|
||||
return (DealProposal)(v0)
|
||||
}
|
127
chain/actors/builtin/miner/diff.go
Normal file
127
chain/actors/builtin/miner/diff.go
Normal file
@ -0,0 +1,127 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
func DiffPreCommits(pre, cur State) (*PreCommitChanges, error) {
|
||||
results := new(PreCommitChanges)
|
||||
|
||||
prep, err := pre.precommits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curp, err := cur.precommits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = adt.DiffAdtMap(prep, curp, &preCommitDiffer{results, pre, cur})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type preCommitDiffer struct {
|
||||
Results *PreCommitChanges
|
||||
pre, after State
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) AsKey(key string) (abi.Keyer, error) {
|
||||
sector, err := abi.ParseUIntKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return abi.UIntKey(sector), nil
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) Add(key string, val *cbg.Deferred) error {
|
||||
sp, err := m.after.decodeSectorPreCommitOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Added = append(m.Results.Added, sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) Remove(key string, val *cbg.Deferred) error {
|
||||
sp, err := m.pre.decodeSectorPreCommitOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Removed = append(m.Results.Removed, sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func DiffSectors(pre, cur State) (*SectorChanges, error) {
|
||||
results := new(SectorChanges)
|
||||
|
||||
pres, err := pre.sectors()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curs, err := cur.sectors()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = adt.DiffAdtArray(pres, curs, §orDiffer{results, pre, cur})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type sectorDiffer struct {
|
||||
Results *SectorChanges
|
||||
pre, after State
|
||||
}
|
||||
|
||||
func (m *sectorDiffer) Add(key uint64, val *cbg.Deferred) error {
|
||||
si, err := m.after.decodeSectorOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Added = append(m.Results.Added, si)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *sectorDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
||||
siFrom, err := m.pre.decodeSectorOnChainInfo(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
siTo, err := m.after.decodeSectorOnChainInfo(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if siFrom.Expiration != siTo.Expiration {
|
||||
m.Results.Extended = append(m.Results.Extended, SectorExtensions{
|
||||
From: siFrom,
|
||||
To: siTo,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *sectorDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
||||
si, err := m.pre.decodeSectorOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Removed = append(m.Results.Removed, si)
|
||||
return nil
|
||||
}
|
169
chain/actors/builtin/miner/miner.go
Normal file
169
chain/actors/builtin/miner/miner.go
Normal file
@ -0,0 +1,169 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
// Unchanged between v0 and v1 actors
|
||||
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
||||
|
||||
const MinSectorExpiration = miner0.MinSectorExpiration
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.StorageMinerActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
// Total available balance to spend.
|
||||
AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error)
|
||||
// Funds that will vest by the given epoch.
|
||||
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
// Funds locked for various reasons.
|
||||
LockedFunds() (LockedFunds, error)
|
||||
|
||||
GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
|
||||
FindSector(abi.SectorNumber) (*SectorLocation, error)
|
||||
GetSectorExpiration(abi.SectorNumber) (*SectorExpiration, error)
|
||||
GetPrecommittedSector(abi.SectorNumber) (*SectorPreCommitOnChainInfo, error)
|
||||
LoadSectors(sectorNos *bitfield.BitField) ([]*SectorOnChainInfo, error)
|
||||
NumLiveSectors() (uint64, error)
|
||||
IsAllocated(abi.SectorNumber) (bool, error)
|
||||
|
||||
LoadDeadline(idx uint64) (Deadline, error)
|
||||
ForEachDeadline(cb func(idx uint64, dl Deadline) error) error
|
||||
NumDeadlines() (uint64, error)
|
||||
DeadlinesChanged(State) (bool, error)
|
||||
|
||||
Info() (MinerInfo, error)
|
||||
|
||||
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
|
||||
|
||||
// Diff helpers. Used by Diff* functions internally.
|
||||
sectors() (adt.Array, error)
|
||||
decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error)
|
||||
precommits() (adt.Map, error)
|
||||
decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error)
|
||||
}
|
||||
|
||||
type Deadline interface {
|
||||
LoadPartition(idx uint64) (Partition, error)
|
||||
ForEachPartition(cb func(idx uint64, part Partition) error) error
|
||||
PostSubmissions() (bitfield.BitField, error)
|
||||
|
||||
PartitionsChanged(Deadline) (bool, error)
|
||||
}
|
||||
|
||||
type Partition interface {
|
||||
AllSectors() (bitfield.BitField, error)
|
||||
FaultySectors() (bitfield.BitField, error)
|
||||
RecoveringSectors() (bitfield.BitField, error)
|
||||
LiveSectors() (bitfield.BitField, error)
|
||||
ActiveSectors() (bitfield.BitField, error)
|
||||
}
|
||||
|
||||
type SectorOnChainInfo struct {
|
||||
SectorNumber abi.SectorNumber
|
||||
SealProof abi.RegisteredSealProof
|
||||
SealedCID cid.Cid
|
||||
DealIDs []abi.DealID
|
||||
Activation abi.ChainEpoch
|
||||
Expiration abi.ChainEpoch
|
||||
DealWeight abi.DealWeight
|
||||
VerifiedDealWeight abi.DealWeight
|
||||
InitialPledge abi.TokenAmount
|
||||
ExpectedDayReward abi.TokenAmount
|
||||
ExpectedStoragePledge abi.TokenAmount
|
||||
}
|
||||
|
||||
type SectorPreCommitInfo = miner0.SectorPreCommitInfo
|
||||
|
||||
type SectorPreCommitOnChainInfo struct {
|
||||
Info SectorPreCommitInfo
|
||||
PreCommitDeposit abi.TokenAmount
|
||||
PreCommitEpoch abi.ChainEpoch
|
||||
DealWeight abi.DealWeight
|
||||
VerifiedDealWeight abi.DealWeight
|
||||
}
|
||||
|
||||
type PoStPartition = miner0.PoStPartition
|
||||
type RecoveryDeclaration = miner0.RecoveryDeclaration
|
||||
type FaultDeclaration = miner0.FaultDeclaration
|
||||
|
||||
// Params
|
||||
type DeclareFaultsParams = miner0.DeclareFaultsParams
|
||||
type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams
|
||||
type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams
|
||||
type ProveCommitSectorParams = miner0.ProveCommitSectorParams
|
||||
|
||||
type MinerInfo struct {
|
||||
Owner address.Address // Must be an ID-address.
|
||||
Worker address.Address // Must be an ID-address.
|
||||
NewWorker address.Address // Must be an ID-address.
|
||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId *peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
SealProofType abi.RegisteredSealProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
}
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
// non-zero if sector is faulty, epoch at which it will be permanently
|
||||
// removed if it doesn't recover
|
||||
Early abi.ChainEpoch
|
||||
}
|
||||
|
||||
type SectorLocation struct {
|
||||
Deadline uint64
|
||||
Partition uint64
|
||||
}
|
||||
|
||||
type SectorChanges struct {
|
||||
Added []SectorOnChainInfo
|
||||
Extended []SectorExtensions
|
||||
Removed []SectorOnChainInfo
|
||||
}
|
||||
|
||||
type SectorExtensions struct {
|
||||
From SectorOnChainInfo
|
||||
To SectorOnChainInfo
|
||||
}
|
||||
|
||||
type PreCommitChanges struct {
|
||||
Added []SectorPreCommitOnChainInfo
|
||||
Removed []SectorPreCommitOnChainInfo
|
||||
}
|
||||
|
||||
type LockedFunds struct {
|
||||
VestingFunds abi.TokenAmount
|
||||
InitialPledgeRequirement abi.TokenAmount
|
||||
PreCommitDeposits abi.TokenAmount
|
||||
}
|
28
chain/actors/builtin/miner/utils.go
Normal file
28
chain/actors/builtin/miner/utils.go
Normal file
@ -0,0 +1,28 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
)
|
||||
|
||||
func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error)) (bitfield.BitField, error) {
|
||||
var parts []bitfield.BitField
|
||||
|
||||
err := mas.ForEachDeadline(func(dlidx uint64, dl Deadline) error {
|
||||
return dl.ForEachPartition(func(partidx uint64, part Partition) error {
|
||||
s, err := sget(part)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting sector list (dl: %d, part %d): %w", dlidx, partidx, err)
|
||||
}
|
||||
|
||||
parts = append(parts, s)
|
||||
return nil
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return bitfield.BitField{}, err
|
||||
}
|
||||
|
||||
return bitfield.MultiMerge(parts...)
|
||||
}
|
374
chain/actors/builtin/miner/v0.go
Normal file
374
chain/actors/builtin/miner/v0.go
Normal file
@ -0,0 +1,374 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
miner0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type deadline0 struct {
|
||||
miner0.Deadline
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type partition0 struct {
|
||||
miner0.Partition
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return s.GetAvailableBalance(bal), nil
|
||||
}
|
||||
|
||||
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
return s.CheckVestedFunds(s.store, epoch)
|
||||
}
|
||||
|
||||
func (s *state0) LockedFunds() (LockedFunds, error) {
|
||||
return LockedFunds{
|
||||
VestingFunds: s.State.LockedFunds,
|
||||
InitialPledgeRequirement: s.State.InitialPledgeRequirement,
|
||||
PreCommitDeposits: s.State.PreCommitDeposits,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state0) InitialPledge() (abi.TokenAmount, error) {
|
||||
return s.State.InitialPledgeRequirement, nil
|
||||
}
|
||||
|
||||
func (s *state0) PreCommitDeposits() (abi.TokenAmount, error) {
|
||||
return s.State.PreCommitDeposits, nil
|
||||
}
|
||||
|
||||
func (s *state0) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
|
||||
info, ok, err := s.State.GetSector(s.store, num)
|
||||
if !ok || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := fromV0SectorOnChainInfo(*info)
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (s *state0) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
|
||||
dlIdx, partIdx, err := s.State.FindSector(s.store, num)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SectorLocation{
|
||||
Deadline: dlIdx,
|
||||
Partition: partIdx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state0) NumLiveSectors() (uint64, error) {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var total uint64
|
||||
if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner0.Deadline) error {
|
||||
total += dl.LiveSectors
|
||||
return nil
|
||||
}); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// GetSectorExpiration returns the effective expiration of the given sector.
|
||||
//
|
||||
// If the sector isn't found or has already been terminated, this method returns
|
||||
// nil and no error. If the sector does not expire early, the Early expiration
|
||||
// field is 0.
|
||||
func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// NOTE: this can be optimized significantly.
|
||||
// 1. If the sector is non-faulty, it will either expire on-time (can be
|
||||
// learned from the sector info), or in the next quantized expiration
|
||||
// epoch (i.e., the first element in the partition's expiration queue.
|
||||
// 2. If it's faulty, it will expire early within the first 14 entries
|
||||
// of the expiration queue.
|
||||
stopErr := errors.New("stop")
|
||||
out := SectorExpiration{}
|
||||
err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner0.Deadline) error {
|
||||
partitions, err := dl.PartitionsArray(s.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
quant := s.State.QuantSpecForDeadline(dlIdx)
|
||||
var part miner0.Partition
|
||||
return partitions.ForEach(&part, func(partIdx int64) error {
|
||||
if found, err := part.Sectors.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if !found {
|
||||
return nil
|
||||
}
|
||||
if found, err := part.Terminated.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if found {
|
||||
// already terminated
|
||||
return stopErr
|
||||
}
|
||||
|
||||
q, err := miner0.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var exp miner0.ExpirationSet
|
||||
return q.ForEach(&exp, func(epoch int64) error {
|
||||
if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if early {
|
||||
out.Early = abi.ChainEpoch(epoch)
|
||||
return nil
|
||||
}
|
||||
if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if onTime {
|
||||
out.OnTime = abi.ChainEpoch(epoch)
|
||||
return stopErr
|
||||
}
|
||||
return nil
|
||||
})
|
||||
})
|
||||
})
|
||||
if err == stopErr {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out.Early == 0 && out.OnTime == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (s *state0) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
|
||||
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
|
||||
if !ok || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := fromV0SectorPreCommitOnChainInfo(*info)
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (s *state0) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
|
||||
sectors, err := miner0.LoadSectors(s.store, s.State.Sectors)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If no sector numbers are specified, load all.
|
||||
if snos == nil {
|
||||
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
|
||||
var info0 miner0.SectorOnChainInfo
|
||||
if err := sectors.ForEach(&info0, func(_ int64) error {
|
||||
info := fromV0SectorOnChainInfo(info0)
|
||||
infos = append(infos, &info)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return infos, nil
|
||||
}
|
||||
|
||||
// Otherwise, load selected.
|
||||
infos0, err := sectors.Load(*snos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos := make([]*SectorOnChainInfo, len(infos0))
|
||||
for i, info0 := range infos0 {
|
||||
info := fromV0SectorOnChainInfo(*info0)
|
||||
infos[i] = &info
|
||||
}
|
||||
return infos, nil
|
||||
}
|
||||
|
||||
func (s *state0) IsAllocated(num abi.SectorNumber) (bool, error) {
|
||||
var allocatedSectors bitfield.BitField
|
||||
if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return allocatedSectors.IsSet(uint64(num))
|
||||
}
|
||||
|
||||
func (s *state0) LoadDeadline(idx uint64) (Deadline, error) {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dl, err := dls.LoadDeadline(s.store, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &deadline0{*dl, s.store}, nil
|
||||
}
|
||||
|
||||
func (s *state0) ForEachDeadline(cb func(uint64, Deadline) error) error {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dls.ForEach(s.store, func(i uint64, dl *miner0.Deadline) error {
|
||||
return cb(i, &deadline0{*dl, s.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state0) NumDeadlines() (uint64, error) {
|
||||
return miner0.WPoStPeriodDeadlines, nil
|
||||
}
|
||||
|
||||
func (s *state0) DeadlinesChanged(other State) (bool, error) {
|
||||
other0, ok := other.(*state0)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return s.State.Deadlines.Equals(other0.Deadlines), nil
|
||||
}
|
||||
|
||||
func (s *state0) Info() (MinerInfo, error) {
|
||||
info, err := s.State.GetInfo(s.store)
|
||||
if err != nil {
|
||||
return MinerInfo{}, err
|
||||
}
|
||||
|
||||
var pid *peer.ID
|
||||
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
||||
pid = &peerID
|
||||
}
|
||||
|
||||
mi := MinerInfo{
|
||||
Owner: info.Owner,
|
||||
Worker: info.Worker,
|
||||
ControlAddresses: info.ControlAddresses,
|
||||
|
||||
NewWorker: address.Undef,
|
||||
WorkerChangeEpoch: -1,
|
||||
|
||||
PeerId: pid,
|
||||
Multiaddrs: info.Multiaddrs,
|
||||
SealProofType: info.SealProofType,
|
||||
SectorSize: info.SectorSize,
|
||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi, nil
|
||||
}
|
||||
|
||||
func (s *state0) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
|
||||
return s.State.DeadlineInfo(epoch), nil
|
||||
}
|
||||
|
||||
func (s *state0) sectors() (adt.Array, error) {
|
||||
return adt0.AsArray(s.store, s.Sectors)
|
||||
}
|
||||
|
||||
func (s *state0) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
|
||||
var si miner0.SectorOnChainInfo
|
||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return SectorOnChainInfo{}, err
|
||||
}
|
||||
|
||||
return fromV0SectorOnChainInfo(si), nil
|
||||
}
|
||||
|
||||
func (s *state0) precommits() (adt.Map, error) {
|
||||
return adt0.AsMap(s.store, s.PreCommittedSectors)
|
||||
}
|
||||
|
||||
func (s *state0) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
|
||||
var sp miner0.SectorPreCommitOnChainInfo
|
||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return SectorPreCommitOnChainInfo{}, err
|
||||
}
|
||||
|
||||
return fromV0SectorPreCommitOnChainInfo(sp), nil
|
||||
}
|
||||
|
||||
func (d *deadline0) LoadPartition(idx uint64) (Partition, error) {
|
||||
p, err := d.Deadline.LoadPartition(d.store, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &partition0{*p, d.store}, nil
|
||||
}
|
||||
|
||||
func (d *deadline0) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||
ps, err := d.Deadline.PartitionsArray(d.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var part miner0.Partition
|
||||
return ps.ForEach(&part, func(i int64) error {
|
||||
return cb(uint64(i), &partition0{part, d.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
|
||||
other0, ok := other.(*deadline0)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
|
||||
}
|
||||
|
||||
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
|
||||
return d.Deadline.PostSubmissions, nil
|
||||
}
|
||||
|
||||
func (p *partition0) AllSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Sectors, nil
|
||||
}
|
||||
|
||||
func (p *partition0) FaultySectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Faults, nil
|
||||
}
|
||||
|
||||
func (p *partition0) RecoveringSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Recoveries, nil
|
||||
}
|
||||
|
||||
func fromV0SectorOnChainInfo(v0 miner0.SectorOnChainInfo) SectorOnChainInfo {
|
||||
return (SectorOnChainInfo)(v0)
|
||||
}
|
||||
|
||||
func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||
return (SectorPreCommitOnChainInfo)(v0)
|
||||
}
|
43
chain/actors/builtin/multisig/multisig.go
Normal file
43
chain/actors/builtin/multisig/multisig.go
Normal file
@ -0,0 +1,43 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.MultisigActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
StartEpoch() (abi.ChainEpoch, error)
|
||||
UnlockDuration() (abi.ChainEpoch, error)
|
||||
InitialBalance() (abi.TokenAmount, error)
|
||||
Threshold() (uint64, error)
|
||||
Signers() ([]address.Address, error)
|
||||
|
||||
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
||||
}
|
||||
|
||||
type Transaction = msig0.Transaction
|
59
chain/actors/builtin/multisig/v0.go
Normal file
59
chain/actors/builtin/multisig/v0.go
Normal file
@ -0,0 +1,59 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
msig0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
|
||||
}
|
||||
|
||||
func (s *state0) StartEpoch() (abi.ChainEpoch, error) {
|
||||
return s.State.StartEpoch, nil
|
||||
}
|
||||
|
||||
func (s *state0) UnlockDuration() (abi.ChainEpoch, error) {
|
||||
return s.State.UnlockDuration, nil
|
||||
}
|
||||
|
||||
func (s *state0) InitialBalance() (abi.TokenAmount, error) {
|
||||
return s.State.InitialBalance, nil
|
||||
}
|
||||
|
||||
func (s *state0) Threshold() (uint64, error) {
|
||||
return s.State.NumApprovalsThreshold, nil
|
||||
}
|
||||
|
||||
func (s *state0) Signers() ([]address.Address, error) {
|
||||
return s.State.Signers, nil
|
||||
}
|
||||
|
||||
func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
||||
arr, err := adt0.AsMap(s.store, s.State.PendingTxns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var out msig0.Transaction
|
||||
return arr.ForEach(&out, func(key string) error {
|
||||
txid, n := binary.Varint([]byte(key))
|
||||
if n <= 0 {
|
||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||
}
|
||||
return cb(txid, (Transaction)(out))
|
||||
})
|
||||
}
|
89
chain/actors/builtin/paych/mock/mock.go
Normal file
89
chain/actors/builtin/paych/mock/mock.go
Normal file
@ -0,0 +1,89 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
)
|
||||
|
||||
type mockState struct {
|
||||
from address.Address
|
||||
to address.Address
|
||||
settlingAt abi.ChainEpoch
|
||||
toSend abi.TokenAmount
|
||||
lanes map[uint64]paych.LaneState
|
||||
}
|
||||
|
||||
type mockLaneState struct {
|
||||
redeemed big.Int
|
||||
nonce uint64
|
||||
}
|
||||
|
||||
// NewMockPayChState constructs a state for a payment channel with the set fixed values
|
||||
// that satisfies the paych.State interface.
|
||||
func NewMockPayChState(from address.Address,
|
||||
to address.Address,
|
||||
settlingAt abi.ChainEpoch,
|
||||
toSend abi.TokenAmount,
|
||||
lanes map[uint64]paych.LaneState,
|
||||
) paych.State {
|
||||
return &mockState{from, to, settlingAt, toSend, lanes}
|
||||
}
|
||||
|
||||
// NewMockLaneState constructs a state for a payment channel lane with the set fixed values
|
||||
// that satisfies the paych.LaneState interface. Useful for populating lanes when
|
||||
// calling NewMockPayChState
|
||||
func NewMockLaneState(redeemed big.Int, nonce uint64) paych.LaneState {
|
||||
return &mockLaneState{redeemed, nonce}
|
||||
}
|
||||
|
||||
func (ms *mockState) MarshalCBOR(io.Writer) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// Channel owner, who has funded the actor
|
||||
func (ms *mockState) From() (address.Address, error) {
|
||||
return ms.from, nil
|
||||
}
|
||||
|
||||
// Recipient of payouts from channel
|
||||
func (ms *mockState) To() (address.Address, error) {
|
||||
return ms.to, nil
|
||||
}
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
func (ms *mockState) SettlingAt() (abi.ChainEpoch, error) {
|
||||
return ms.settlingAt, nil
|
||||
}
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
func (ms *mockState) ToSend() (abi.TokenAmount, error) {
|
||||
return ms.toSend, nil
|
||||
}
|
||||
|
||||
// Get total number of lanes
|
||||
func (ms *mockState) LaneCount() (uint64, error) {
|
||||
return uint64(len(ms.lanes)), nil
|
||||
}
|
||||
|
||||
// Iterate lane states
|
||||
func (ms *mockState) ForEachLaneState(cb func(idx uint64, dl paych.LaneState) error) error {
|
||||
var lastErr error
|
||||
for lane, state := range ms.lanes {
|
||||
if err := cb(lane, state); err != nil {
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func (mls *mockLaneState) Redeemed() (big.Int, error) {
|
||||
return mls.redeemed, nil
|
||||
}
|
||||
|
||||
func (mls *mockLaneState) Nonce() (uint64, error) {
|
||||
return mls.nonce, nil
|
||||
}
|
60
chain/actors/builtin/paych/paych.go
Normal file
60
chain/actors/builtin/paych/paych.go
Normal file
@ -0,0 +1,60 @@
|
||||
package paych
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
big "github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.PaymentChannelActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
// State is an abstract version of payment channel state that works across
|
||||
// versions
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
// Channel owner, who has funded the actor
|
||||
From() (address.Address, error)
|
||||
// Recipient of payouts from channel
|
||||
To() (address.Address, error)
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
SettlingAt() (abi.ChainEpoch, error)
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
ToSend() (abi.TokenAmount, error)
|
||||
|
||||
// Get total number of lanes
|
||||
LaneCount() (uint64, error)
|
||||
|
||||
// Iterate lane states
|
||||
ForEachLaneState(cb func(idx uint64, dl LaneState) error) error
|
||||
}
|
||||
|
||||
// LaneState is an abstract copy of the state of a single lane
|
||||
type LaneState interface {
|
||||
Redeemed() (big.Int, error)
|
||||
Nonce() (uint64, error)
|
||||
}
|
||||
|
||||
type SignedVoucher = paych0.SignedVoucher
|
||||
type ModVerifyParams = paych0.ModVerifyParams
|
91
chain/actors/builtin/paych/v0.go
Normal file
91
chain/actors/builtin/paych/v0.go
Normal file
@ -0,0 +1,91 @@
|
||||
package paych
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
big "github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
paych.State
|
||||
store adt.Store
|
||||
lsAmt *adt0.Array
|
||||
}
|
||||
|
||||
// Channel owner, who has funded the actor
|
||||
func (s *state0) From() (address.Address, error) {
|
||||
return s.State.From, nil
|
||||
}
|
||||
|
||||
// Recipient of payouts from channel
|
||||
func (s *state0) To() (address.Address, error) {
|
||||
return s.State.To, nil
|
||||
}
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
func (s *state0) SettlingAt() (abi.ChainEpoch, error) {
|
||||
return s.State.SettlingAt, nil
|
||||
}
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
func (s *state0) ToSend() (abi.TokenAmount, error) {
|
||||
return s.State.ToSend, nil
|
||||
}
|
||||
|
||||
func (s *state0) getOrLoadLsAmt() (*adt0.Array, error) {
|
||||
if s.lsAmt != nil {
|
||||
return s.lsAmt, nil
|
||||
}
|
||||
|
||||
// Get the lane state from the chain
|
||||
lsamt, err := adt0.AsArray(s.store, s.State.LaneStates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.lsAmt = lsamt
|
||||
return lsamt, nil
|
||||
}
|
||||
|
||||
// Get total number of lanes
|
||||
func (s *state0) LaneCount() (uint64, error) {
|
||||
lsamt, err := s.getOrLoadLsAmt()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return lsamt.Length(), nil
|
||||
}
|
||||
|
||||
// Iterate lane states
|
||||
func (s *state0) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error {
|
||||
// Get the lane state from the chain
|
||||
lsamt, err := s.getOrLoadLsAmt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Note: we use a map instead of an array to store laneStates because the
|
||||
// client sets the lane ID (the index) and potentially they could use a
|
||||
// very large index.
|
||||
var ls paych.LaneState
|
||||
return lsamt.ForEach(&ls, func(i int64) error {
|
||||
return cb(uint64(i), &laneState0{ls})
|
||||
})
|
||||
}
|
||||
|
||||
type laneState0 struct {
|
||||
paych.LaneState
|
||||
}
|
||||
|
||||
func (ls *laneState0) Redeemed() (big.Int, error) {
|
||||
return ls.LaneState.Redeemed, nil
|
||||
}
|
||||
|
||||
func (ls *laneState0) Nonce() (uint64, error) {
|
||||
return ls.LaneState.Nonce, nil
|
||||
}
|
53
chain/actors/builtin/power/power.go
Normal file
53
chain/actors/builtin/power/power.go
Normal file
@ -0,0 +1,53 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var Address = builtin0.StoragePowerActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.StoragePowerActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
TotalPower() (Claim, error)
|
||||
TotalCommitted() (Claim, error)
|
||||
TotalPowerSmoothed() (builtin.FilterEstimate, error)
|
||||
|
||||
// MinerCounts returns the number of miners. Participating is the number
|
||||
// with power above the minimum miner threshold.
|
||||
MinerCounts() (participating, total uint64, err error)
|
||||
MinerPower(address.Address) (Claim, bool, error)
|
||||
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
|
||||
ListAllMiners() ([]address.Address, error)
|
||||
}
|
||||
|
||||
type Claim struct {
|
||||
// Sum of raw byte power for a miner's sectors.
|
||||
RawBytePower abi.StoragePower
|
||||
|
||||
// Sum of quality adjusted power for a miner's sectors.
|
||||
QualityAdjPower abi.StoragePower
|
||||
}
|
85
chain/actors/builtin/power/v0.go
Normal file
85
chain/actors/builtin/power/v0.go
Normal file
@ -0,0 +1,85 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
power0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) TotalLocked() (abi.TokenAmount, error) {
|
||||
return s.TotalPledgeCollateral, nil
|
||||
}
|
||||
|
||||
func (s *state0) TotalPower() (Claim, error) {
|
||||
return Claim{
|
||||
RawBytePower: s.TotalRawBytePower,
|
||||
QualityAdjPower: s.TotalQualityAdjPower,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Committed power to the network. Includes miners below the minimum threshold.
|
||||
func (s *state0) TotalCommitted() (Claim, error) {
|
||||
return Claim{
|
||||
RawBytePower: s.TotalBytesCommitted,
|
||||
QualityAdjPower: s.TotalQABytesCommitted,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||
claims, err := adt.AsMap(s.store, s.Claims)
|
||||
if err != nil {
|
||||
return Claim{}, false, err
|
||||
}
|
||||
var claim power0.Claim
|
||||
ok, err := claims.Get(abi.AddrKey(addr), &claim)
|
||||
if err != nil {
|
||||
return Claim{}, false, err
|
||||
}
|
||||
return Claim{
|
||||
RawBytePower: claim.RawBytePower,
|
||||
QualityAdjPower: claim.QualityAdjPower,
|
||||
}, ok, nil
|
||||
}
|
||||
|
||||
func (s *state0) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
|
||||
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
|
||||
}
|
||||
|
||||
func (s *state0) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
|
||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochQAPowerSmoothed), nil
|
||||
}
|
||||
|
||||
func (s *state0) MinerCounts() (uint64, uint64, error) {
|
||||
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
|
||||
}
|
||||
|
||||
func (s *state0) ListAllMiners() ([]address.Address, error) {
|
||||
claims, err := adt.AsMap(s.store, s.Claims)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var miners []address.Address
|
||||
err = claims.ForEach(nil, func(k string) error {
|
||||
a, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
miners = append(miners, a)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return miners, nil
|
||||
}
|
50
chain/actors/builtin/reward/reward.go
Normal file
50
chain/actors/builtin/reward/reward.go
Normal file
@ -0,0 +1,50 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var Address = builtin0.RewardActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.RewardActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
ThisEpochBaselinePower() (abi.StoragePower, error)
|
||||
ThisEpochReward() (abi.StoragePower, error)
|
||||
ThisEpochRewardSmoothed() (builtin.FilterEstimate, error)
|
||||
|
||||
EffectiveBaselinePower() (abi.StoragePower, error)
|
||||
EffectiveNetworkTime() (abi.ChainEpoch, error)
|
||||
|
||||
TotalStoragePowerReward() (abi.TokenAmount, error)
|
||||
|
||||
CumsumBaseline() (abi.StoragePower, error)
|
||||
CumsumRealized() (abi.StoragePower, error)
|
||||
|
||||
InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error)
|
||||
PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error)
|
||||
}
|
||||
|
||||
type AwardBlockRewardParams = reward0.AwardBlockRewardParams
|
71
chain/actors/builtin/reward/v0.go
Normal file
71
chain/actors/builtin/reward/v0.go
Normal file
@ -0,0 +1,71 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
reward.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochReward() (abi.StoragePower, error) {
|
||||
return s.State.ThisEpochReward, nil
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||
return s.State.ThisEpochBaselinePower, nil
|
||||
}
|
||||
|
||||
func (s *state0) TotalStoragePowerReward() (abi.TokenAmount, error) {
|
||||
return s.State.TotalMined, nil
|
||||
}
|
||||
|
||||
func (s *state0) EffectiveBaselinePower() (abi.StoragePower, error) {
|
||||
return s.State.EffectiveBaselinePower, nil
|
||||
}
|
||||
|
||||
func (s *state0) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
||||
return s.State.EffectiveNetworkTime, nil
|
||||
}
|
||||
|
||||
func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
}
|
||||
|
||||
func (s *state0) CumsumRealized() (abi.StoragePower, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
}
|
||||
|
||||
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return miner0.InitialPledgeForPower(
|
||||
sectorWeight,
|
||||
s.State.ThisEpochBaselinePower,
|
||||
networkTotalPledge,
|
||||
s.State.ThisEpochRewardSmoothed,
|
||||
&smoothing.FilterEstimate{
|
||||
PositionEstimate: networkQAPower.PositionEstimate,
|
||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||
},
|
||||
circSupply), nil
|
||||
}
|
||||
|
||||
func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
||||
return miner0.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
||||
&smoothing.FilterEstimate{
|
||||
PositionEstimate: networkQAPower.PositionEstimate,
|
||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||
},
|
||||
sectorWeight), nil
|
||||
}
|
71
chain/actors/builtin/verifreg/v0.go
Normal file
71
chain/actors/builtin/verifreg/v0.go
Normal file
@ -0,0 +1,71 @@
|
||||
package verifreg
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
|
||||
type state0 struct {
|
||||
verifreg0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func getDataCap(store adt.Store, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) {
|
||||
if addr.Protocol() != address.ID {
|
||||
return false, big.Zero(), xerrors.Errorf("can only look up ID addresses")
|
||||
}
|
||||
|
||||
vh, err := adt0.AsMap(store, root)
|
||||
if err != nil {
|
||||
return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err)
|
||||
}
|
||||
|
||||
var dcap abi.StoragePower
|
||||
if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil {
|
||||
return false, big.Zero(), xerrors.Errorf("looking up addr: %w", err)
|
||||
} else if !found {
|
||||
return false, big.Zero(), nil
|
||||
}
|
||||
|
||||
return true, dcap, nil
|
||||
}
|
||||
|
||||
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||
return getDataCap(s.store, s.State.VerifiedClients, addr)
|
||||
}
|
||||
|
||||
func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||
return getDataCap(s.store, s.State.Verifiers, addr)
|
||||
}
|
||||
|
||||
func forEachCap(store adt.Store, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||
vh, err := adt0.AsMap(store, root)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading verified clients: %w", err)
|
||||
}
|
||||
var dcap abi.StoragePower
|
||||
return vh.ForEach(&dcap, func(key string) error {
|
||||
a, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(a, dcap)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||
return forEachCap(s.store, s.State.Verifiers, cb)
|
||||
}
|
||||
|
||||
func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||
return forEachCap(s.store, s.State.VerifiedClients, cb)
|
||||
}
|
37
chain/actors/builtin/verifreg/verifreg.go
Normal file
37
chain/actors/builtin/verifreg/verifreg.go
Normal file
@ -0,0 +1,37 @@
|
||||
package verifreg
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var Address = builtin0.VerifiedRegistryActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.VerifiedRegistryActorCodeID:
|
||||
out := state0{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||
}
|
56
chain/actors/policy/policy.go
Normal file
56
chain/actors/policy/policy.go
Normal file
@ -0,0 +1,56 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
)
|
||||
|
||||
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
newTypes := make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
for _, t := range types {
|
||||
newTypes[t] = struct{}{}
|
||||
}
|
||||
// Set for all miner versions.
|
||||
miner0.SupportedProofTypes = newTypes
|
||||
}
|
||||
|
||||
// AddSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
newTypes := make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
for _, t := range types {
|
||||
newTypes[t] = struct{}{}
|
||||
}
|
||||
// Set for all miner versions.
|
||||
miner0.SupportedProofTypes = newTypes
|
||||
}
|
||||
|
||||
// SetPreCommitChallengeDelay sets the pre-commit challenge delay across all
|
||||
// actors versions. Use for testing.
|
||||
func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
|
||||
// Set for all miner versions.
|
||||
miner0.PreCommitChallengeDelay = delay
|
||||
}
|
||||
|
||||
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
|
||||
func GetPreCommitChallengeDelay() abi.ChainEpoch {
|
||||
return miner0.PreCommitChallengeDelay
|
||||
}
|
||||
|
||||
// SetConsensusMinerMinPower sets the minimum power of an individual miner must
|
||||
// meet for leader election, across all actor versions. This should only be used
|
||||
// for testing.
|
||||
func SetConsensusMinerMinPower(p abi.StoragePower) {
|
||||
power0.ConsensusMinerMinPower = p
|
||||
}
|
||||
|
||||
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
|
||||
// only be used for testing.
|
||||
func SetMinVerifiedDealSize(size abi.StoragePower) {
|
||||
verifreg0.MinVerifiedDealSize = size
|
||||
}
|
@ -4,20 +4,19 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@ -49,7 +48,7 @@ func NewStatePredicates(api ChainAPI) *StatePredicates {
|
||||
// - err
|
||||
type DiffTipSetKeyFunc func(ctx context.Context, oldState, newState types.TipSetKey) (changed bool, user UserData, err error)
|
||||
|
||||
type DiffActorStateFunc func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error)
|
||||
type DiffActorStateFunc func(ctx context.Context, oldActorState *types.Actor, newActorState *types.Actor) (changed bool, user UserData, err error)
|
||||
|
||||
// OnActorStateChanged calls diffStateFunc when the state changes for the given actor
|
||||
func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFunc DiffActorStateFunc) DiffTipSetKeyFunc {
|
||||
@ -66,30 +65,30 @@ func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFu
|
||||
if oldActor.Head.Equals(newActor.Head) {
|
||||
return false, nil, nil
|
||||
}
|
||||
return diffStateFunc(ctx, oldActor.Head, newActor.Head)
|
||||
return diffStateFunc(ctx, oldActor, newActor)
|
||||
}
|
||||
}
|
||||
|
||||
type DiffStorageMarketStateFunc func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error)
|
||||
type DiffStorageMarketStateFunc func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error)
|
||||
|
||||
// OnStorageMarketActorChanged calls diffStorageMarketState when the state changes for the market actor
|
||||
func (sp *StatePredicates) OnStorageMarketActorChanged(diffStorageMarketState DiffStorageMarketStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(builtin.StorageMarketActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState market.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(market.Address, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := market.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState market.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := market.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffStorageMarketState(ctx, &oldState, &newState)
|
||||
return diffStorageMarketState(ctx, oldState, newState)
|
||||
})
|
||||
}
|
||||
|
||||
type BalanceTables struct {
|
||||
EscrowTable *adt.BalanceTable
|
||||
LockedTable *adt.BalanceTable
|
||||
EscrowTable market.BalanceTable
|
||||
LockedTable market.BalanceTable
|
||||
}
|
||||
|
||||
// DiffBalanceTablesFunc compares two balance tables
|
||||
@ -97,32 +96,32 @@ type DiffBalanceTablesFunc func(ctx context.Context, oldBalanceTable, newBalance
|
||||
|
||||
// OnBalanceChanged runs when the escrow table for available balances changes
|
||||
func (sp *StatePredicates) OnBalanceChanged(diffBalances DiffBalanceTablesFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) {
|
||||
if oldState.EscrowTable.Equals(newState.EscrowTable) && oldState.LockedTable.Equals(newState.LockedTable) {
|
||||
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
|
||||
bc, err := oldState.BalancesChanged(newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if !bc {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
oldEscrowRoot, err := adt.AsBalanceTable(ctxStore, oldState.EscrowTable)
|
||||
oldEscrowRoot, err := oldState.EscrowTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
oldLockedRoot, err := adt.AsBalanceTable(ctxStore, oldState.LockedTable)
|
||||
oldLockedRoot, err := oldState.LockedTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newEscrowRoot, err := adt.AsBalanceTable(ctxStore, newState.EscrowTable)
|
||||
newEscrowRoot, err := newState.EscrowTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newLockedRoot, err := adt.AsBalanceTable(ctxStore, newState.LockedTable)
|
||||
newLockedRoot, err := newState.LockedTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@ -131,25 +130,27 @@ func (sp *StatePredicates) OnBalanceChanged(diffBalances DiffBalanceTablesFunc)
|
||||
}
|
||||
}
|
||||
|
||||
type DiffAdtArraysFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot *adt.Array) (changed bool, user UserData, err error)
|
||||
type DiffDealStatesFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot market.DealStates) (changed bool, user UserData, err error)
|
||||
type DiffDealProposalsFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot market.DealProposals) (changed bool, user UserData, err error)
|
||||
type DiffAdtArraysFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot adt.Array) (changed bool, user UserData, err error)
|
||||
|
||||
// OnDealStateChanged calls diffDealStates when the market deal state changes
|
||||
func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffAdtArraysFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) {
|
||||
if oldState.States.Equals(newState.States) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
oldRoot, err := adt.AsArray(ctxStore, oldState.States)
|
||||
func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
|
||||
sc, err := oldState.StatesChanged(newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := adt.AsArray(ctxStore, newState.States)
|
||||
|
||||
if !sc {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldRoot, err := oldState.States()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := newState.States()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@ -159,22 +160,22 @@ func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffAdtArraysFunc)
|
||||
}
|
||||
|
||||
// OnDealProposalChanged calls diffDealProps when the market proposal state changes
|
||||
func (sp *StatePredicates) OnDealProposalChanged(diffDealProps DiffAdtArraysFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) {
|
||||
if oldState.Proposals.Equals(newState.Proposals) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
oldRoot, err := adt.AsArray(ctxStore, oldState.Proposals)
|
||||
func (sp *StatePredicates) OnDealProposalChanged(diffDealProps DiffDealProposalsFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
|
||||
pc, err := oldState.ProposalsChanged(newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := adt.AsArray(ctxStore, newState.Proposals)
|
||||
|
||||
if !pc {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldRoot, err := oldState.Proposals()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := newState.Proposals()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@ -183,51 +184,14 @@ func (sp *StatePredicates) OnDealProposalChanged(diffDealProps DiffAdtArraysFunc
|
||||
}
|
||||
}
|
||||
|
||||
var _ AdtArrayDiff = &MarketDealProposalChanges{}
|
||||
|
||||
type MarketDealProposalChanges struct {
|
||||
Added []ProposalIDState
|
||||
Removed []ProposalIDState
|
||||
}
|
||||
|
||||
type ProposalIDState struct {
|
||||
ID abi.DealID
|
||||
Proposal market.DealProposal
|
||||
}
|
||||
|
||||
func (m *MarketDealProposalChanges) Add(key uint64, val *typegen.Deferred) error {
|
||||
dp := new(market.DealProposal)
|
||||
err := dp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealProposalChanges) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
// short circuit, DealProposals are static
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealProposalChanges) Remove(key uint64, val *typegen.Deferred) error {
|
||||
dp := new(market.DealProposal)
|
||||
err := dp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnDealProposalAmtChanged detects changes in the deal proposal AMT for all deal proposals and returns a MarketProposalsChanges structure containing:
|
||||
// - Added Proposals
|
||||
// - Modified Proposals
|
||||
// - Removed Proposals
|
||||
func (sp *StatePredicates) OnDealProposalAmtChanged() DiffAdtArraysFunc {
|
||||
return func(ctx context.Context, oldDealProps, newDealProps *adt.Array) (changed bool, user UserData, err error) {
|
||||
proposalChanges := new(MarketDealProposalChanges)
|
||||
if err := DiffAdtArray(oldDealProps, newDealProps, proposalChanges); err != nil {
|
||||
func (sp *StatePredicates) OnDealProposalAmtChanged() DiffDealProposalsFunc {
|
||||
return func(ctx context.Context, oldDealProps, newDealProps market.DealProposals) (changed bool, user UserData, err error) {
|
||||
proposalChanges, err := market.DiffDealProposals(oldDealProps, newDealProps)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
@ -239,64 +203,14 @@ func (sp *StatePredicates) OnDealProposalAmtChanged() DiffAdtArraysFunc {
|
||||
}
|
||||
}
|
||||
|
||||
var _ AdtArrayDiff = &MarketDealStateChanges{}
|
||||
|
||||
type MarketDealStateChanges struct {
|
||||
Added []DealIDState
|
||||
Modified []DealStateChange
|
||||
Removed []DealIDState
|
||||
}
|
||||
|
||||
type DealIDState struct {
|
||||
ID abi.DealID
|
||||
Deal market.DealState
|
||||
}
|
||||
|
||||
func (m *MarketDealStateChanges) Add(key uint64, val *typegen.Deferred) error {
|
||||
ds := new(market.DealState)
|
||||
err := ds.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealStateChanges) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
dsFrom := new(market.DealState)
|
||||
if err := dsFrom.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dsTo := new(market.DealState)
|
||||
if err := dsTo.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if *dsFrom != *dsTo {
|
||||
m.Modified = append(m.Modified, DealStateChange{abi.DealID(key), dsFrom, dsTo})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealStateChanges) Remove(key uint64, val *typegen.Deferred) error {
|
||||
ds := new(market.DealState)
|
||||
err := ds.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnDealStateAmtChanged detects changes in the deal state AMT for all deal states and returns a MarketDealStateChanges structure containing:
|
||||
// - Added Deals
|
||||
// - Modified Deals
|
||||
// - Removed Deals
|
||||
func (sp *StatePredicates) OnDealStateAmtChanged() DiffAdtArraysFunc {
|
||||
return func(ctx context.Context, oldDealStates, newDealStates *adt.Array) (changed bool, user UserData, err error) {
|
||||
dealStateChanges := new(MarketDealStateChanges)
|
||||
if err := DiffAdtArray(oldDealStates, newDealStates, dealStateChanges); err != nil {
|
||||
func (sp *StatePredicates) OnDealStateAmtChanged() DiffDealStatesFunc {
|
||||
return func(ctx context.Context, oldDealStates, newDealStates market.DealStates) (changed bool, user UserData, err error) {
|
||||
dealStateChanges, err := market.DiffDealStates(oldDealStates, newDealStates)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
@ -309,42 +223,29 @@ func (sp *StatePredicates) OnDealStateAmtChanged() DiffAdtArraysFunc {
|
||||
}
|
||||
|
||||
// ChangedDeals is a set of changes to deal state
|
||||
type ChangedDeals map[abi.DealID]DealStateChange
|
||||
|
||||
// DealStateChange is a change in deal state from -> to
|
||||
type DealStateChange struct {
|
||||
ID abi.DealID
|
||||
From *market.DealState
|
||||
To *market.DealState
|
||||
}
|
||||
type ChangedDeals map[abi.DealID]market.DealStateChange
|
||||
|
||||
// DealStateChangedForIDs detects changes in the deal state AMT for the given deal IDs
|
||||
func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffAdtArraysFunc {
|
||||
return func(ctx context.Context, oldDealStateArray, newDealStateArray *adt.Array) (changed bool, user UserData, err error) {
|
||||
func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDealStatesFunc {
|
||||
return func(ctx context.Context, oldDealStates, newDealStates market.DealStates) (changed bool, user UserData, err error) {
|
||||
changedDeals := make(ChangedDeals)
|
||||
for _, dealID := range dealIds {
|
||||
var oldDealPtr, newDealPtr *market.DealState
|
||||
var oldDeal, newDeal market.DealState
|
||||
|
||||
// If the deal has been removed, we just set it to nil
|
||||
found, err := oldDealStateArray.Get(uint64(dealID), &oldDeal)
|
||||
oldDeal, oldFound, err := oldDealStates.Get(dealID)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if found {
|
||||
oldDealPtr = &oldDeal
|
||||
}
|
||||
|
||||
found, err = newDealStateArray.Get(uint64(dealID), &newDeal)
|
||||
newDeal, newFound, err := newDealStates.Get(dealID)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if found {
|
||||
newDealPtr = &newDeal
|
||||
}
|
||||
|
||||
if oldDeal != newDeal {
|
||||
changedDeals[dealID] = DealStateChange{dealID, oldDealPtr, newDealPtr}
|
||||
existenceChanged := oldFound != newFound
|
||||
valueChanged := (oldFound && newFound) && *oldDeal != *newDeal
|
||||
if existenceChanged || valueChanged {
|
||||
changedDeals[dealID] = market.DealStateChange{ID: dealID, From: oldDeal, To: newDeal}
|
||||
}
|
||||
}
|
||||
if len(changedDeals) > 0 {
|
||||
@ -405,124 +306,43 @@ func (sp *StatePredicates) AvailableBalanceChangedForAddresses(getAddrs func() [
|
||||
}
|
||||
}
|
||||
|
||||
type DiffMinerActorStateFunc func(ctx context.Context, oldState *miner.State, newState *miner.State) (changed bool, user UserData, err error)
|
||||
type DiffMinerActorStateFunc func(ctx context.Context, oldState miner.State, newState miner.State) (changed bool, user UserData, err error)
|
||||
|
||||
func (sp *StatePredicates) OnInitActorChange(diffInitActorState DiffInitActorStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(builtin.InitActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState init_.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(init_.Address, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := init_.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState init_.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := init_.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffInitActorState(ctx, &oldState, &newState)
|
||||
return diffInitActorState(ctx, oldState, newState)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnMinerActorChange(minerAddr address.Address, diffMinerActorState DiffMinerActorStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(minerAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState miner.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(minerAddr, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := miner.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState miner.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := miner.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffMinerActorState(ctx, &oldState, &newState)
|
||||
return diffMinerActorState(ctx, oldState, newState)
|
||||
})
|
||||
}
|
||||
|
||||
type MinerSectorChanges struct {
|
||||
Added []miner.SectorOnChainInfo
|
||||
Extended []SectorExtensions
|
||||
Removed []miner.SectorOnChainInfo
|
||||
}
|
||||
|
||||
var _ AdtArrayDiff = &MinerSectorChanges{}
|
||||
|
||||
type SectorExtensions struct {
|
||||
From miner.SectorOnChainInfo
|
||||
To miner.SectorOnChainInfo
|
||||
}
|
||||
|
||||
func (m *MinerSectorChanges) Add(key uint64, val *typegen.Deferred) error {
|
||||
si := new(miner.SectorOnChainInfo)
|
||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, *si)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerSectorChanges) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
siFrom := new(miner.SectorOnChainInfo)
|
||||
err := siFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
siTo := new(miner.SectorOnChainInfo)
|
||||
err = siTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if siFrom.Expiration != siTo.Expiration {
|
||||
m.Extended = append(m.Extended, SectorExtensions{
|
||||
From: *siFrom,
|
||||
To: *siTo,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerSectorChanges) Remove(key uint64, val *typegen.Deferred) error {
|
||||
si := new(miner.SectorOnChainInfo)
|
||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, *si)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnMinerSectorChange() DiffMinerActorStateFunc {
|
||||
return func(ctx context.Context, oldState, newState *miner.State) (changed bool, user UserData, err error) {
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
sectorChanges := &MinerSectorChanges{
|
||||
Added: []miner.SectorOnChainInfo{},
|
||||
Extended: []SectorExtensions{},
|
||||
Removed: []miner.SectorOnChainInfo{},
|
||||
}
|
||||
|
||||
// no sector changes
|
||||
if oldState.Sectors.Equals(newState.Sectors) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldSectors, err := adt.AsArray(ctxStore, oldState.Sectors)
|
||||
return func(ctx context.Context, oldState, newState miner.State) (changed bool, user UserData, err error) {
|
||||
sectorChanges, err := miner.DiffSectors(oldState, newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newSectors, err := adt.AsArray(ctxStore, newState.Sectors)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if err := DiffAdtArray(oldSectors, newSectors, sectorChanges); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
// nothing changed
|
||||
if len(sectorChanges.Added)+len(sectorChanges.Extended)+len(sectorChanges.Removed) == 0 {
|
||||
return false, nil, nil
|
||||
@ -532,73 +352,13 @@ func (sp *StatePredicates) OnMinerSectorChange() DiffMinerActorStateFunc {
|
||||
}
|
||||
}
|
||||
|
||||
type MinerPreCommitChanges struct {
|
||||
Added []miner.SectorPreCommitOnChainInfo
|
||||
Removed []miner.SectorPreCommitOnChainInfo
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) AsKey(key string) (abi.Keyer, error) {
|
||||
sector, err := abi.ParseUIntKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return miner.SectorKey(abi.SectorNumber(sector)), nil
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) Add(key string, val *typegen.Deferred) error {
|
||||
sp := new(miner.SectorPreCommitOnChainInfo)
|
||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, *sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) Modify(key string, from, to *typegen.Deferred) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) Remove(key string, val *typegen.Deferred) error {
|
||||
sp := new(miner.SectorPreCommitOnChainInfo)
|
||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, *sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnMinerPreCommitChange() DiffMinerActorStateFunc {
|
||||
return func(ctx context.Context, oldState, newState *miner.State) (changed bool, user UserData, err error) {
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
precommitChanges := &MinerPreCommitChanges{
|
||||
Added: []miner.SectorPreCommitOnChainInfo{},
|
||||
Removed: []miner.SectorPreCommitOnChainInfo{},
|
||||
}
|
||||
|
||||
if oldState.PreCommittedSectors.Equals(newState.PreCommittedSectors) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldPrecommits, err := adt.AsMap(ctxStore, oldState.PreCommittedSectors)
|
||||
return func(ctx context.Context, oldState, newState miner.State) (changed bool, user UserData, err error) {
|
||||
precommitChanges, err := miner.DiffPreCommits(oldState, newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newPrecommits, err := adt.AsMap(ctxStore, newState.PreCommittedSectors)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if err := DiffAdtMap(oldPrecommits, newPrecommits, precommitChanges); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if len(precommitChanges.Added)+len(precommitChanges.Removed) == 0 {
|
||||
return false, nil, nil
|
||||
}
|
||||
@ -608,20 +368,20 @@ func (sp *StatePredicates) OnMinerPreCommitChange() DiffMinerActorStateFunc {
|
||||
}
|
||||
|
||||
// DiffPaymentChannelStateFunc is function that compares two states for the payment channel
|
||||
type DiffPaymentChannelStateFunc func(ctx context.Context, oldState *paych.State, newState *paych.State) (changed bool, user UserData, err error)
|
||||
type DiffPaymentChannelStateFunc func(ctx context.Context, oldState paych.State, newState paych.State) (changed bool, user UserData, err error)
|
||||
|
||||
// OnPaymentChannelActorChanged calls diffPaymentChannelState when the state changes for the the payment channel actor
|
||||
func (sp *StatePredicates) OnPaymentChannelActorChanged(paychAddr address.Address, diffPaymentChannelState DiffPaymentChannelStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(paychAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState paych.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(paychAddr, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := paych.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState paych.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := paych.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffPaymentChannelState(ctx, &oldState, &newState)
|
||||
return diffPaymentChannelState(ctx, oldState, newState)
|
||||
})
|
||||
}
|
||||
|
||||
@ -633,13 +393,23 @@ type PayChToSendChange struct {
|
||||
|
||||
// OnToSendAmountChanges monitors changes on the total amount to send from one party to the other on a payment channel
|
||||
func (sp *StatePredicates) OnToSendAmountChanges() DiffPaymentChannelStateFunc {
|
||||
return func(ctx context.Context, oldState *paych.State, newState *paych.State) (changed bool, user UserData, err error) {
|
||||
if oldState.ToSend.Equals(newState.ToSend) {
|
||||
return func(ctx context.Context, oldState paych.State, newState paych.State) (changed bool, user UserData, err error) {
|
||||
ots, err := oldState.ToSend()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
nts, err := newState.ToSend()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if ots.Equals(nts) {
|
||||
return false, nil, nil
|
||||
}
|
||||
return true, &PayChToSendChange{
|
||||
OldToSend: oldState.ToSend,
|
||||
NewToSend: newState.ToSend,
|
||||
OldToSend: ots,
|
||||
NewToSend: nts,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@ -660,7 +430,7 @@ type AddressChange struct {
|
||||
To AddressPair
|
||||
}
|
||||
|
||||
type DiffInitActorStateFunc func(ctx context.Context, oldState *init_.State, newState *init_.State) (changed bool, user UserData, err error)
|
||||
type DiffInitActorStateFunc func(ctx context.Context, oldState init_.State, newState init_.State) (changed bool, user UserData, err error)
|
||||
|
||||
func (i *InitActorAddressChanges) AsKey(key string) (abi.Keyer, error) {
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
@ -748,33 +518,73 @@ func (i *InitActorAddressChanges) Remove(key string, val *typegen.Deferred) erro
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
|
||||
return func(ctx context.Context, oldState, newState *init_.State) (changed bool, user UserData, err error) {
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
return func(ctx context.Context, oldState, newState init_.State) (changed bool, user UserData, err error) {
|
||||
addressChanges := &InitActorAddressChanges{
|
||||
Added: []AddressPair{},
|
||||
Modified: []AddressChange{},
|
||||
Removed: []AddressPair{},
|
||||
}
|
||||
|
||||
if oldState.AddressMap.Equals(newState.AddressMap) {
|
||||
return false, nil, nil
|
||||
}
|
||||
err = oldState.ForEachActor(func(oldId abi.ActorID, oldAddress address.Address) error {
|
||||
oldIdAddress, err := address.NewIDAddress(uint64(oldId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newIdAddress, found, err := newState.ResolveAddress(oldAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
addressChanges.Removed = append(addressChanges.Removed, AddressPair{
|
||||
ID: oldIdAddress,
|
||||
PK: oldAddress,
|
||||
})
|
||||
}
|
||||
|
||||
if oldIdAddress != newIdAddress {
|
||||
addressChanges.Modified = append(addressChanges.Modified, AddressChange{
|
||||
From: AddressPair{
|
||||
ID: oldIdAddress,
|
||||
PK: oldAddress,
|
||||
},
|
||||
To: AddressPair{
|
||||
ID: newIdAddress,
|
||||
PK: oldAddress,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
oldAddrs, err := adt.AsMap(ctxStore, oldState.AddressMap)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newAddrs, err := adt.AsMap(ctxStore, newState.AddressMap)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
err = newState.ForEachActor(func(newId abi.ActorID, newAddress address.Address) error {
|
||||
newIdAddress, err := address.NewIDAddress(uint64(newId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := DiffAdtMap(oldAddrs, newAddrs, addressChanges); err != nil {
|
||||
_, found, err := newState.ResolveAddress(newAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
addressChanges.Added = append(addressChanges.Added, AddressPair{
|
||||
ID: newIdAddress,
|
||||
PK: newAddress,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -16,8 +18,11 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
tutils "github.com/filecoin-project/specs-actors/support/testing"
|
||||
|
||||
@ -69,22 +74,22 @@ func TestMarketPredicates(t *testing.T) {
|
||||
bs := bstore.NewTemporarySync()
|
||||
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||
|
||||
oldDeal1 := &market.DealState{
|
||||
oldDeal1 := &market0.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 2,
|
||||
SlashEpoch: 0,
|
||||
}
|
||||
oldDeal2 := &market.DealState{
|
||||
oldDeal2 := &market0.DealState{
|
||||
SectorStartEpoch: 4,
|
||||
LastUpdatedEpoch: 5,
|
||||
SlashEpoch: 0,
|
||||
}
|
||||
oldDeals := map[abi.DealID]*market.DealState{
|
||||
oldDeals := map[abi.DealID]*market0.DealState{
|
||||
abi.DealID(1): oldDeal1,
|
||||
abi.DealID(2): oldDeal2,
|
||||
}
|
||||
|
||||
oldProp1 := &market.DealProposal{
|
||||
oldProp1 := &market0.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@ -96,7 +101,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
oldProp2 := &market.DealProposal{
|
||||
oldProp2 := &market0.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@ -108,7 +113,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
oldProps := map[abi.DealID]*market.DealProposal{
|
||||
oldProps := map[abi.DealID]*market0.DealProposal{
|
||||
abi.DealID(1): oldProp1,
|
||||
abi.DealID(2): oldProp2,
|
||||
}
|
||||
@ -122,7 +127,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
|
||||
oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
|
||||
|
||||
newDeal1 := &market.DealState{
|
||||
newDeal1 := &market0.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 3,
|
||||
SlashEpoch: 0,
|
||||
@ -131,19 +136,19 @@ func TestMarketPredicates(t *testing.T) {
|
||||
// deal 2 removed
|
||||
|
||||
// added
|
||||
newDeal3 := &market.DealState{
|
||||
newDeal3 := &market0.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 2,
|
||||
SlashEpoch: 3,
|
||||
}
|
||||
newDeals := map[abi.DealID]*market.DealState{
|
||||
newDeals := map[abi.DealID]*market0.DealState{
|
||||
abi.DealID(1): newDeal1,
|
||||
// deal 2 was removed
|
||||
abi.DealID(3): newDeal3,
|
||||
}
|
||||
|
||||
// added
|
||||
newProp3 := &market.DealProposal{
|
||||
newProp3 := &market0.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@ -155,7 +160,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
newProps := map[abi.DealID]*market.DealProposal{
|
||||
newProps := map[abi.DealID]*market0.DealProposal{
|
||||
abi.DealID(1): oldProp1, // 1 was persisted
|
||||
// prop 2 was removed
|
||||
abi.DealID(3): newProp3, // new
|
||||
@ -178,8 +183,8 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
api := newMockAPI(bs)
|
||||
api.setActor(oldState.Key(), &types.Actor{Head: oldStateC})
|
||||
api.setActor(newState.Key(), &types.Actor{Head: newStateC})
|
||||
api.setActor(oldState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: oldStateC})
|
||||
api.setActor(newState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: newStateC})
|
||||
|
||||
t.Run("deal ID predicate", func(t *testing.T) {
|
||||
preds := NewStatePredicates(api)
|
||||
@ -221,7 +226,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
// Test that OnActorStateChanged does not call the callback if the state has not changed
|
||||
mockAddr, err := address.NewFromString("t01")
|
||||
require.NoError(t, err)
|
||||
actorDiffFn := preds.OnActorStateChanged(mockAddr, func(context.Context, cid.Cid, cid.Cid) (bool, UserData, error) {
|
||||
actorDiffFn := preds.OnActorStateChanged(mockAddr, func(context.Context, *types.Actor, *types.Actor) (bool, UserData, error) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
@ -230,11 +235,18 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.False(t, changed)
|
||||
|
||||
// Test that OnDealStateChanged does not call the callback if the state has not changed
|
||||
diffDealStateFn := preds.OnDealStateChanged(func(context.Context, *adt.Array, *adt.Array) (bool, UserData, error) {
|
||||
diffDealStateFn := preds.OnDealStateChanged(func(context.Context, market.DealStates, market.DealStates) (bool, UserData, error) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
marketState := createEmptyMarketState(t, store)
|
||||
marketState0 := createEmptyMarketState(t, store)
|
||||
marketCid, err := store.Put(ctx, marketState0)
|
||||
require.NoError(t, err)
|
||||
marketState, err := market.Load(store, &types.Actor{
|
||||
Code: builtin0.StorageMarketActorCodeID,
|
||||
Head: marketCid,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
changed, _, err = diffDealStateFn(ctx, marketState, marketState)
|
||||
require.NoError(t, err)
|
||||
require.False(t, changed)
|
||||
@ -252,18 +264,18 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.True(t, changed)
|
||||
|
||||
changedDeals, ok := valArr.(*MarketDealStateChanges)
|
||||
changedDeals, ok := valArr.(*market.DealStateChanges)
|
||||
require.True(t, ok)
|
||||
require.Len(t, changedDeals.Added, 1)
|
||||
require.Equal(t, abi.DealID(3), changedDeals.Added[0].ID)
|
||||
require.Equal(t, *newDeal3, changedDeals.Added[0].Deal)
|
||||
require.True(t, dealEquality(*newDeal3, changedDeals.Added[0].Deal))
|
||||
|
||||
require.Len(t, changedDeals.Removed, 1)
|
||||
|
||||
require.Len(t, changedDeals.Modified, 1)
|
||||
require.Equal(t, abi.DealID(1), changedDeals.Modified[0].ID)
|
||||
require.Equal(t, newDeal1, changedDeals.Modified[0].To)
|
||||
require.Equal(t, oldDeal1, changedDeals.Modified[0].From)
|
||||
require.True(t, dealEquality(*newDeal1, *changedDeals.Modified[0].To))
|
||||
require.True(t, dealEquality(*oldDeal1, *changedDeals.Modified[0].From))
|
||||
|
||||
require.Equal(t, abi.DealID(2), changedDeals.Removed[0].ID)
|
||||
})
|
||||
@ -279,17 +291,15 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.True(t, changed)
|
||||
|
||||
changedProps, ok := valArr.(*MarketDealProposalChanges)
|
||||
changedProps, ok := valArr.(*market.DealProposalChanges)
|
||||
require.True(t, ok)
|
||||
require.Len(t, changedProps.Added, 1)
|
||||
require.Equal(t, abi.DealID(3), changedProps.Added[0].ID)
|
||||
require.Equal(t, *newProp3, changedProps.Added[0].Proposal)
|
||||
|
||||
// proposals cannot be modified -- no modified testing
|
||||
|
||||
require.Len(t, changedProps.Removed, 1)
|
||||
require.Equal(t, abi.DealID(2), changedProps.Removed[0].ID)
|
||||
require.Equal(t, *oldProp2, changedProps.Removed[0].Proposal)
|
||||
})
|
||||
|
||||
t.Run("balances predicate", func(t *testing.T) {
|
||||
@ -342,7 +352,14 @@ func TestMarketPredicates(t *testing.T) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
marketState := createEmptyMarketState(t, store)
|
||||
marketState0 := createEmptyMarketState(t, store)
|
||||
marketCid, err := store.Put(ctx, marketState0)
|
||||
require.NoError(t, err)
|
||||
marketState, err := market.Load(store, &types.Actor{
|
||||
Code: builtin0.StorageMarketActorCodeID,
|
||||
Head: marketCid,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
changed, _, err = diffDealBalancesFn(ctx, marketState, marketState)
|
||||
require.NoError(t, err)
|
||||
require.False(t, changed)
|
||||
@ -362,12 +379,12 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
}
|
||||
|
||||
owner, worker := nextIDAddrF(), nextIDAddrF()
|
||||
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
|
||||
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
|
||||
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
|
||||
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner0.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
|
||||
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner0.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
|
||||
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner0.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
|
||||
oldMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si0, si1, si2})
|
||||
|
||||
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
|
||||
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner0.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
|
||||
// 0 delete
|
||||
// 1 extend
|
||||
// 2 same
|
||||
@ -383,8 +400,8 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
api := newMockAPI(bs)
|
||||
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC})
|
||||
api.setActor(newState.Key(), &types.Actor{Head: newMinerC})
|
||||
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin0.StorageMinerActorCodeID})
|
||||
api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin0.StorageMinerActorCodeID})
|
||||
|
||||
preds := NewStatePredicates(api)
|
||||
|
||||
@ -394,7 +411,7 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
require.True(t, change)
|
||||
require.NotNil(t, val)
|
||||
|
||||
sectorChanges, ok := val.(*MinerSectorChanges)
|
||||
sectorChanges, ok := val.(*miner.SectorChanges)
|
||||
require.True(t, ok)
|
||||
|
||||
require.Equal(t, len(sectorChanges.Added), 1)
|
||||
@ -418,7 +435,7 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
require.True(t, change)
|
||||
require.NotNil(t, val)
|
||||
|
||||
sectorChanges, ok = val.(*MinerSectorChanges)
|
||||
sectorChanges, ok = val.(*miner.SectorChanges)
|
||||
require.True(t, ok)
|
||||
|
||||
require.Equal(t, 1, len(sectorChanges.Added))
|
||||
@ -450,7 +467,7 @@ type balance struct {
|
||||
locked abi.TokenAmount
|
||||
}
|
||||
|
||||
func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState, props map[abi.DealID]*market.DealProposal, balances map[address.Address]balance) cid.Cid {
|
||||
func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState, props map[abi.DealID]*market0.DealProposal, balances map[address.Address]balance) cid.Cid {
|
||||
dealRootCid := createDealAMT(ctx, t, store, deals)
|
||||
propRootCid := createProposalAMT(ctx, t, store, props)
|
||||
balancesCids := createBalanceTable(ctx, t, store, balances)
|
||||
@ -465,15 +482,15 @@ func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals
|
||||
return stateC
|
||||
}
|
||||
|
||||
func createEmptyMarketState(t *testing.T, store adt.Store) *market.State {
|
||||
func createEmptyMarketState(t *testing.T, store adt.Store) *market0.State {
|
||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||
require.NoError(t, err)
|
||||
return market.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
||||
return market0.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
||||
}
|
||||
|
||||
func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState) cid.Cid {
|
||||
func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
for dealID, dealState := range deals {
|
||||
err := root.Set(uint64(dealID), dealState)
|
||||
@ -484,7 +501,7 @@ func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map
|
||||
return rootCid
|
||||
}
|
||||
|
||||
func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market.DealProposal) cid.Cid {
|
||||
func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market0.DealProposal) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
for dealID, prop := range props {
|
||||
err := root.Set(uint64(dealID), prop)
|
||||
@ -532,20 +549,20 @@ func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner,
|
||||
return stateC
|
||||
}
|
||||
|
||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner.State {
|
||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner0.State {
|
||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyDeadline, err := store.Put(store.Context(), miner.ConstructDeadline(emptyArrayCid))
|
||||
emptyDeadline, err := store.Put(store.Context(), miner0.ConstructDeadline(emptyArrayCid))
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyVestingFunds := miner.ConstructVestingFunds()
|
||||
emptyVestingFunds := miner0.ConstructVestingFunds()
|
||||
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyDeadlines := miner.ConstructDeadlines(emptyDeadline)
|
||||
emptyDeadlines := miner0.ConstructDeadlines(emptyDeadline)
|
||||
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -555,7 +572,7 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o
|
||||
emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, err := miner.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
|
||||
state, err := miner0.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
|
||||
require.NoError(t, err)
|
||||
return state
|
||||
|
||||
@ -564,7 +581,7 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o
|
||||
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
for _, sector := range sectors {
|
||||
sector := sector
|
||||
sector := (miner0.SectorOnChainInfo)(sector)
|
||||
err := root.Set(uint64(sector.SectorNumber), §or)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@ -597,8 +614,8 @@ const (
|
||||
)
|
||||
|
||||
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
|
||||
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner.SectorPreCommitInfo {
|
||||
return &miner.SectorPreCommitInfo{
|
||||
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner0.SectorPreCommitInfo {
|
||||
return &miner0.SectorPreCommitInfo{
|
||||
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
SectorNumber: sectorNo,
|
||||
SealedCID: sealed,
|
||||
@ -607,3 +624,9 @@ func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiratio
|
||||
Expiration: expiration,
|
||||
}
|
||||
}
|
||||
|
||||
func dealEquality(expected market0.DealState, actual market.DealState) bool {
|
||||
return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch &&
|
||||
expected.SectorStartEpoch == actual.SectorStartEpoch &&
|
||||
expected.SlashEpoch == actual.SlashEpoch
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ func (t *Response) MarshalCBOR(w io.Writer) error {
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Status (blocksync.status) (uint64)
|
||||
// t.Status (exchange.status) (uint64)
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Status)); err != nil {
|
||||
return err
|
||||
@ -164,7 +164,7 @@ func (t *Response) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Chain ([]*blocksync.BSTipSet) (slice)
|
||||
// t.Chain ([]*exchange.BSTipSet) (slice)
|
||||
if len(t.Chain) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Slice value in field t.Chain was too long")
|
||||
}
|
||||
@ -198,7 +198,7 @@ func (t *Response) UnmarshalCBOR(r io.Reader) error {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Status (blocksync.status) (uint64)
|
||||
// t.Status (exchange.status) (uint64)
|
||||
|
||||
{
|
||||
|
||||
@ -222,7 +222,7 @@ func (t *Response) UnmarshalCBOR(r io.Reader) error {
|
||||
|
||||
t.ErrorMessage = string(sval)
|
||||
}
|
||||
// t.Chain ([]*blocksync.BSTipSet) (slice)
|
||||
// t.Chain ([]*exchange.BSTipSet) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
@ -567,7 +567,7 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// t.Messages (blocksync.CompactedMessages) (struct)
|
||||
// t.Messages (exchange.CompactedMessages) (struct)
|
||||
if err := t.Messages.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -621,7 +621,7 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
|
||||
t.Blocks[i] = &v
|
||||
}
|
||||
|
||||
// t.Messages (blocksync.CompactedMessages) (struct)
|
||||
// t.Messages (exchange.CompactedMessages) (struct)
|
||||
|
||||
{
|
||||
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -64,7 +65,15 @@ func NewClient(lc fx.Lifecycle, host host.Host, pmgr peermgr.MaybePeerMgr) Clien
|
||||
// request options without disrupting external calls. In the future the
|
||||
// consumers should be forced to use a more standardized service and
|
||||
// adhere to a single API derived from this function.
|
||||
func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.ID) (*validatedResponse, error) {
|
||||
func (c *client) doRequest(
|
||||
ctx context.Context,
|
||||
req *Request,
|
||||
singlePeer *peer.ID,
|
||||
// In the `GetChainMessages` case, we won't request the headers but we still
|
||||
// need them to check the integrity of the `CompactedMessages` in the response
|
||||
// so the tipset blocks need to be provided by the caller.
|
||||
tipsets []*types.TipSet,
|
||||
) (*validatedResponse, error) {
|
||||
// Validate request.
|
||||
if req.Length == 0 {
|
||||
return nil, xerrors.Errorf("invalid request of length 0")
|
||||
@ -115,7 +124,7 @@ func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.I
|
||||
}
|
||||
|
||||
// Process and validate response.
|
||||
validRes, err := c.processResponse(req, res)
|
||||
validRes, err := c.processResponse(req, res, tipsets)
|
||||
if err != nil {
|
||||
log.Warnf("processing peer %s response failed: %s",
|
||||
peer.String(), err)
|
||||
@ -143,7 +152,7 @@ func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.I
|
||||
// errors. Peer penalization should happen here then, before returning, so
|
||||
// we can apply the correct penalties depending on the cause of the error.
|
||||
// FIXME: Add the `peer` as argument once we implement penalties.
|
||||
func (c *client) processResponse(req *Request, res *Response) (*validatedResponse, error) {
|
||||
func (c *client) processResponse(req *Request, res *Response, tipsets []*types.TipSet) (*validatedResponse, error) {
|
||||
err := res.statusToError()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("status error: %s", err)
|
||||
@ -175,6 +184,16 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
|
||||
// Check for valid block sets and extract them into `TipSet`s.
|
||||
validRes.tipsets = make([]*types.TipSet, resLength)
|
||||
for i := 0; i < resLength; i++ {
|
||||
if res.Chain[i] == nil {
|
||||
return nil, xerrors.Errorf("response with nil tipset in pos %d", i)
|
||||
}
|
||||
for blockIdx, block := range res.Chain[i].Blocks {
|
||||
if block == nil {
|
||||
return nil, xerrors.Errorf("tipset with nil block in pos %d", blockIdx)
|
||||
// FIXME: Maybe we should move this check to `NewTipSet`.
|
||||
}
|
||||
}
|
||||
|
||||
validRes.tipsets[i], err = types.NewTipSet(res.Chain[i].Blocks)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("invalid tipset blocks at height (head - %d): %w", i, err)
|
||||
@ -209,31 +228,28 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
|
||||
// If the headers were also returned check that the compression
|
||||
// indexes are valid before `toFullTipSets()` is called by the
|
||||
// consumer.
|
||||
for tipsetIdx := 0; tipsetIdx < resLength; tipsetIdx++ {
|
||||
msgs := res.Chain[tipsetIdx].Messages
|
||||
blocksNum := len(res.Chain[tipsetIdx].Blocks)
|
||||
if len(msgs.BlsIncludes) != blocksNum {
|
||||
return nil, xerrors.Errorf("BlsIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.BlsIncludes), blocksNum)
|
||||
}
|
||||
if len(msgs.SecpkIncludes) != blocksNum {
|
||||
return nil, xerrors.Errorf("SecpkIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.SecpkIncludes), blocksNum)
|
||||
}
|
||||
for blockIdx := 0; blockIdx < blocksNum; blockIdx++ {
|
||||
for _, mi := range msgs.BlsIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Bls) {
|
||||
return nil, xerrors.Errorf("index in BlsIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Bls))
|
||||
}
|
||||
}
|
||||
for _, mi := range msgs.SecpkIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Secpk) {
|
||||
return nil, xerrors.Errorf("index in SecpkIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Secpk))
|
||||
}
|
||||
}
|
||||
err := c.validateCompressedIndices(res.Chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// If we didn't request the headers they should have been provided
|
||||
// by the caller.
|
||||
if len(tipsets) < len(res.Chain) {
|
||||
return nil, xerrors.Errorf("not enought tipsets provided for message response validation, needed %d, have %d", len(res.Chain), len(tipsets))
|
||||
}
|
||||
chain := make([]*BSTipSet, 0, resLength)
|
||||
for i, resChain := range res.Chain {
|
||||
next := &BSTipSet{
|
||||
Blocks: tipsets[i].Blocks(),
|
||||
Messages: resChain.Messages,
|
||||
}
|
||||
chain = append(chain, next)
|
||||
}
|
||||
|
||||
err := c.validateCompressedIndices(chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,6 +257,42 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
|
||||
return validRes, nil
|
||||
}
|
||||
|
||||
func (c *client) validateCompressedIndices(chain []*BSTipSet) error {
|
||||
resLength := len(chain)
|
||||
for tipsetIdx := 0; tipsetIdx < resLength; tipsetIdx++ {
|
||||
msgs := chain[tipsetIdx].Messages
|
||||
blocksNum := len(chain[tipsetIdx].Blocks)
|
||||
|
||||
if len(msgs.BlsIncludes) != blocksNum {
|
||||
return xerrors.Errorf("BlsIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.BlsIncludes), blocksNum)
|
||||
}
|
||||
|
||||
if len(msgs.SecpkIncludes) != blocksNum {
|
||||
return xerrors.Errorf("SecpkIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.SecpkIncludes), blocksNum)
|
||||
}
|
||||
|
||||
for blockIdx := 0; blockIdx < blocksNum; blockIdx++ {
|
||||
for _, mi := range msgs.BlsIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Bls) {
|
||||
return xerrors.Errorf("index in BlsIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Bls))
|
||||
}
|
||||
}
|
||||
|
||||
for _, mi := range msgs.SecpkIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Secpk) {
|
||||
return xerrors.Errorf("index in SecpkIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Secpk))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBlocks implements Client.GetBlocks(). Refer to the godocs there.
|
||||
func (c *client) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "bsync.GetBlocks")
|
||||
@ -258,7 +310,7 @@ func (c *client) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int)
|
||||
Options: Headers,
|
||||
}
|
||||
|
||||
validRes, err := c.doRequest(ctx, req, nil)
|
||||
validRes, err := c.doRequest(ctx, req, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -276,7 +328,7 @@ func (c *client) GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipS
|
||||
Options: Headers | Messages,
|
||||
}
|
||||
|
||||
validRes, err := c.doRequest(ctx, req, &peer)
|
||||
validRes, err := c.doRequest(ctx, req, &peer, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -287,7 +339,10 @@ func (c *client) GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipS
|
||||
}
|
||||
|
||||
// GetChainMessages implements Client.GetChainMessages(). Refer to the godocs there.
|
||||
func (c *client) GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error) {
|
||||
func (c *client) GetChainMessages(ctx context.Context, tipsets []*types.TipSet) ([]*CompactedMessages, error) {
|
||||
head := tipsets[0]
|
||||
length := uint64(len(tipsets))
|
||||
|
||||
ctx, span := trace.StartSpan(ctx, "GetChainMessages")
|
||||
if span.IsRecordingEvents() {
|
||||
span.AddAttributes(
|
||||
@ -303,7 +358,7 @@ func (c *client) GetChainMessages(ctx context.Context, head *types.TipSet, lengt
|
||||
Options: Messages,
|
||||
}
|
||||
|
||||
validRes, err := c.doRequest(ctx, req, nil)
|
||||
validRes, err := c.doRequest(ctx, req, nil, tipsets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -357,6 +412,12 @@ func (c *client) sendRequestToPeer(ctx context.Context, peer peer.ID, req *Reque
|
||||
return nil, xerrors.Errorf("failed to open stream to peer: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
go helpers.FullClose(stream) //nolint:errcheck
|
||||
}()
|
||||
|
||||
// Write request.
|
||||
_ = stream.SetWriteDeadline(time.Now().Add(WriteReqDeadline))
|
||||
if err := cborutil.WriteCborRPC(stream, req); err != nil {
|
||||
|
@ -32,10 +32,9 @@ type Client interface {
|
||||
// or less.
|
||||
GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error)
|
||||
|
||||
// GetChainMessages fetches messages from the network, from the provided
|
||||
// tipset *backwards*, returning the messages from as many tipsets as the
|
||||
// count parameter, or less.
|
||||
GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error)
|
||||
// GetChainMessages fetches messages from the network, starting from the first provided tipset
|
||||
// and returning messages from as many tipsets as requested or less.
|
||||
GetChainMessages(ctx context.Context, tipsets []*types.TipSet) ([]*CompactedMessages, error)
|
||||
|
||||
// GetFullTipSet fetches a full tipset from a given peer. If successful,
|
||||
// the fetched object contains block headers and all messages in full form.
|
||||
|
@ -40,7 +40,7 @@ const (
|
||||
WriteReqDeadline = 5 * time.Second
|
||||
ReadResDeadline = WriteReqDeadline
|
||||
ReadResMinSpeed = 50 << 10
|
||||
ShufflePeersPrefix = 5
|
||||
ShufflePeersPrefix = 16
|
||||
WriteResDeadline = 60 * time.Second
|
||||
)
|
||||
|
||||
@ -139,6 +139,8 @@ func (res *Response) statusToError() error {
|
||||
|
||||
// FIXME: Rename.
|
||||
type BSTipSet struct {
|
||||
// List of blocks belonging to a single tipset to which the
|
||||
// `CompactedMessages` are linked.
|
||||
Blocks []*types.BlockHeader
|
||||
Messages *CompactedMessages
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
)
|
||||
|
||||
@ -39,7 +40,9 @@ func (s *server) HandleStream(stream inet.Stream) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "chainxchg.HandleStream")
|
||||
defer span.End()
|
||||
|
||||
defer stream.Close() //nolint:errcheck
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
defer helpers.FullClose(stream) //nolint:errcheck
|
||||
|
||||
var req Request
|
||||
if err := cborutil.ReadCborRPC(bufio.NewReader(stream), &req); err != nil {
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
saminer "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -28,6 +27,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@ -121,9 +121,8 @@ var DefaultRemainderAccountActor = genesis.Actor{
|
||||
}
|
||||
|
||||
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
// TODO: we really shouldn't modify a global variable here.
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
|
||||
mr := repo.NewMemory(nil)
|
||||
lr, err := mr.Lock(repo.StorageMiner)
|
||||
@ -489,13 +488,16 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke
|
||||
// ResyncBankerNonce is used for dealing with messages made when
|
||||
// simulating forks
|
||||
func (cg *ChainGen) ResyncBankerNonce(ts *types.TipSet) error {
|
||||
var act types.Actor
|
||||
err := cg.sm.WithParentState(ts, cg.sm.WithActor(cg.banker, stmgr.GetActor(&act)))
|
||||
st, err := cg.sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
act, err := st.GetActor(cg.banker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cg.bankerNonce = act.Nonce
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -4,21 +4,16 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
}
|
||||
|
||||
func testGeneration(t testing.TB, n int, msgs int, sectors int) {
|
||||
|
@ -6,8 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
@ -19,13 +17,14 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -116,7 +115,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
return nil, nil, xerrors.Errorf("putting empty object: %w", err)
|
||||
}
|
||||
|
||||
state, err := state.NewStateTree(cst)
|
||||
state, err := state.NewStateTree(cst, builtin.Version0)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("making new state tree: %w", err)
|
||||
}
|
||||
@ -127,7 +126,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.SystemActorAddr, sysact); err != nil {
|
||||
if err := state.SetActor(builtin0.SystemActorAddr, sysact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set init actor: %w", err)
|
||||
}
|
||||
|
||||
@ -137,7 +136,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.InitActorAddr, initact); err != nil {
|
||||
if err := state.SetActor(builtin0.InitActorAddr, initact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set init actor: %w", err)
|
||||
}
|
||||
|
||||
@ -148,7 +147,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
|
||||
}
|
||||
|
||||
err = state.SetActor(builtin.RewardActorAddr, rewact)
|
||||
err = state.SetActor(builtin0.RewardActorAddr, rewact)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("set network account actor: %w", err)
|
||||
}
|
||||
@ -158,7 +157,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup cron actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.CronActorAddr, cronact); err != nil {
|
||||
if err := state.SetActor(builtin0.CronActorAddr, cronact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set cron actor: %w", err)
|
||||
}
|
||||
|
||||
@ -167,7 +166,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup storage market actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.StoragePowerActorAddr, spact); err != nil {
|
||||
if err := state.SetActor(builtin0.StoragePowerActorAddr, spact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set storage market actor: %w", err)
|
||||
}
|
||||
|
||||
@ -176,7 +175,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup storage market actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.StorageMarketActorAddr, marketact); err != nil {
|
||||
if err := state.SetActor(builtin0.StorageMarketActorAddr, marketact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set market actor: %w", err)
|
||||
}
|
||||
|
||||
@ -185,20 +184,20 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup storage market actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.VerifiedRegistryActorAddr, verifact); err != nil {
|
||||
if err := state.SetActor(builtin0.VerifiedRegistryActorAddr, verifact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set market actor: %w", err)
|
||||
}
|
||||
|
||||
burntRoot, err := cst.Put(ctx, &account.State{
|
||||
Address: builtin.BurntFundsActorAddr,
|
||||
burntRoot, err := cst.Put(ctx, &account0.State{
|
||||
Address: builtin0.BurntFundsActorAddr,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("failed to setup burnt funds actor state: %w", err)
|
||||
}
|
||||
|
||||
// Setup burnt-funds
|
||||
err = state.SetActor(builtin.BurntFundsActorAddr, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
err = state.SetActor(builtin0.BurntFundsActorAddr, &types.Actor{
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: burntRoot,
|
||||
})
|
||||
@ -263,13 +262,13 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
verifierState, err := cst.Put(ctx, &account.State{Address: verifierAd})
|
||||
verifierState, err := cst.Put(ctx, &account0.State{Address: verifierAd})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = state.SetActor(verifierId, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: verifierState,
|
||||
})
|
||||
@ -316,7 +315,7 @@ func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.St
|
||||
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
|
||||
return xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
}
|
||||
st, err := cst.Put(ctx, &account.State{Address: ainfo.Owner})
|
||||
st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -327,7 +326,7 @@ func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.St
|
||||
}
|
||||
|
||||
err = state.SetActor(ida, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: info.Balance,
|
||||
Head: st,
|
||||
})
|
||||
@ -345,7 +344,7 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
|
||||
return xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
}
|
||||
pending, err := adt.MakeEmptyMap(adt.WrapStore(ctx, cst)).Root()
|
||||
pending, err := adt0.MakeEmptyMap(adt0.WrapStore(ctx, cst)).Root()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to create empty map: %v", err)
|
||||
}
|
||||
@ -365,12 +364,12 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
continue
|
||||
}
|
||||
|
||||
st, err := cst.Put(ctx, &account.State{Address: e})
|
||||
st, err := cst.Put(ctx, &account0.State{Address: e})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = state.SetActor(idAddress, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: st,
|
||||
})
|
||||
@ -380,7 +379,7 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
signers = append(signers, idAddress)
|
||||
}
|
||||
|
||||
st, err := cst.Put(ctx, &multisig.State{
|
||||
st, err := cst.Put(ctx, &multisig0.State{
|
||||
Signers: signers,
|
||||
NumApprovalsThreshold: uint64(ainfo.Threshold),
|
||||
StartEpoch: abi.ChainEpoch(ainfo.VestingStart),
|
||||
@ -392,7 +391,7 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
return err
|
||||
}
|
||||
err = state.SetActor(ida, &types.Actor{
|
||||
Code: builtin.MultisigActorCodeID,
|
||||
Code: builtin0.MultisigActorCodeID,
|
||||
Balance: info.Balance,
|
||||
Head: st,
|
||||
})
|
||||
@ -406,10 +405,6 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
|
||||
var sum abi.PaddedPieceSize
|
||||
|
||||
nwv := func(context.Context, abi.ChainEpoch) network.Version {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
vmopt := vm.VMOpts{
|
||||
StateBase: stateroot,
|
||||
Epoch: 0,
|
||||
@ -417,10 +412,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
Bstore: cs.Blockstore(),
|
||||
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
|
||||
CircSupplyCalc: nil,
|
||||
NtwkVersion: nwv,
|
||||
NtwkVersion: genesisNetworkVersion,
|
||||
BaseFee: types.NewInt(0),
|
||||
}
|
||||
vm, err := vm.NewVM(&vmopt)
|
||||
vm, err := vm.NewVM(ctx, &vmopt)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||
}
|
||||
@ -447,7 +442,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
_, err = doExecValue(ctx, vm, builtin.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg.AddVerifierParams{
|
||||
_, err = doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{
|
||||
|
||||
Address: verifier,
|
||||
Allowance: abi.NewStoragePower(int64(sum)), // eh, close enough
|
||||
@ -458,7 +453,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
}
|
||||
|
||||
for c, amt := range verifNeeds {
|
||||
_, err := doExecValue(ctx, vm, builtin.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg.AddVerifiedClientParams{
|
||||
_, err := doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{
|
||||
Address: c,
|
||||
Allowance: abi.NewStoragePower(int64(amt)),
|
||||
}))
|
||||
@ -500,8 +495,8 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
|
||||
return nil, xerrors.Errorf("setup miners failed: %w", err)
|
||||
}
|
||||
|
||||
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||
emptyroot, err := adt.MakeEmptyArray(store).Root()
|
||||
store := adt0.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||
emptyroot, err := adt0.MakeEmptyArray(store).Root()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("amt build failed: %w", err)
|
||||
}
|
||||
@ -549,7 +544,7 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
|
||||
}
|
||||
|
||||
b := &types.BlockHeader{
|
||||
Miner: builtin.SystemActorAddr,
|
||||
Miner: builtin0.SystemActorAddr,
|
||||
Ticket: genesisticket,
|
||||
Parents: []cid.Cid{filecoinGenesisCid},
|
||||
Height: 0,
|
||||
|
@ -6,11 +6,13 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
@ -23,12 +25,12 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
@ -65,10 +67,6 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
nwv := func(context.Context, abi.ChainEpoch) network.Version {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
vmopt := &vm.VMOpts{
|
||||
StateBase: sroot,
|
||||
Epoch: 0,
|
||||
@ -76,11 +74,11 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
Bstore: cs.Blockstore(),
|
||||
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
|
||||
CircSupplyCalc: csc,
|
||||
NtwkVersion: nwv,
|
||||
NtwkVersion: genesisNetworkVersion,
|
||||
BaseFee: types.NewInt(0),
|
||||
}
|
||||
|
||||
vm, err := vm.NewVM(vmopt)
|
||||
vm, err := vm.NewVM(ctx, vmopt)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||
}
|
||||
@ -108,7 +106,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
|
||||
{
|
||||
constructorParams := &power.CreateMinerParams{
|
||||
constructorParams := &power0.CreateMinerParams{
|
||||
Owner: m.Worker,
|
||||
Worker: m.Worker,
|
||||
Peer: []byte(m.PeerId),
|
||||
@ -116,12 +114,12 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
|
||||
params := mustEnc(constructorParams)
|
||||
rval, err := doExecValue(ctx, vm, builtin.StoragePowerActorAddr, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
|
||||
rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
||||
}
|
||||
|
||||
var ma power.CreateMinerReturn
|
||||
var ma power0.CreateMinerReturn
|
||||
if err := ma.UnmarshalCBOR(bytes.NewReader(rval)); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("unmarshaling CreateMinerReturn: %w", err)
|
||||
}
|
||||
@ -132,9 +130,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
minerInfos[i].maddr = ma.IDAddress
|
||||
|
||||
err = vm.MutateState(ctx, minerInfos[i].maddr, func(cst cbor.IpldStore, st *miner.State) error {
|
||||
maxPeriods := miner.MaxSectorExpirationExtension / miner.WPoStProvingPeriod
|
||||
minerInfos[i].presealExp = (maxPeriods-1)*miner.WPoStProvingPeriod + st.ProvingPeriodStart - 1
|
||||
// TODO: ActorUpgrade
|
||||
err = vm.MutateState(ctx, minerInfos[i].maddr, func(cst cbor.IpldStore, st *miner0.State) error {
|
||||
maxPeriods := miner0.MaxSectorExpirationExtension / miner0.WPoStProvingPeriod
|
||||
minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + st.ProvingPeriodStart - 1
|
||||
|
||||
return nil
|
||||
})
|
||||
@ -147,7 +146,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
|
||||
if m.MarketBalance.GreaterThan(big.Zero()) {
|
||||
params := mustEnc(&minerInfos[i].maddr)
|
||||
_, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
|
||||
_, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err)
|
||||
}
|
||||
@ -159,7 +158,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
publish := func(params *market.PublishStorageDealsParams) error {
|
||||
fmt.Printf("publishing %d storage deals on miner %s with worker %s\n", len(params.Deals), params.Deals[0].Proposal.Provider, m.Worker)
|
||||
|
||||
ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
|
||||
ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
|
||||
}
|
||||
@ -210,13 +209,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("getting deal weight: %w", err)
|
||||
}
|
||||
|
||||
sectorWeight := miner.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
|
||||
qaPow = types.BigAdd(qaPow, sectorWeight)
|
||||
}
|
||||
}
|
||||
|
||||
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
|
||||
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
|
||||
st.TotalQualityAdjPower = qaPow
|
||||
st.TotalRawBytePower = rawPow
|
||||
|
||||
@ -228,8 +227,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("mutating state: %w", err)
|
||||
}
|
||||
|
||||
err = vm.MutateState(ctx, builtin.RewardActorAddr, func(sct cbor.IpldStore, st *reward.State) error {
|
||||
*st = *reward.ConstructState(qaPow)
|
||||
err = vm.MutateState(ctx, reward.Address, func(sct cbor.IpldStore, st *reward0.State) error {
|
||||
*st = *reward0.ConstructState(qaPow)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@ -255,10 +254,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("getting deal weight: %w", err)
|
||||
}
|
||||
|
||||
sectorWeight := miner.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
|
||||
// we've added fake power for this sector above, remove it now
|
||||
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
|
||||
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
|
||||
st.TotalQualityAdjPower = types.BigSub(st.TotalQualityAdjPower, sectorWeight) //nolint:scopelint
|
||||
st.TotalRawBytePower = types.BigSub(st.TotalRawBytePower, types.NewInt(uint64(m.SectorSize)))
|
||||
return nil
|
||||
@ -277,9 +276,9 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("getting current total power: %w", err)
|
||||
}
|
||||
|
||||
pcd := miner.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight)
|
||||
pcd := miner0.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight)
|
||||
|
||||
pledge := miner.InitialPledgeForPower(
|
||||
pledge := miner0.InitialPledgeForPower(
|
||||
sectorWeight,
|
||||
epochReward.ThisEpochBaselinePower,
|
||||
tpow.PledgeCollateral,
|
||||
@ -301,7 +300,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
Sectors: []abi.SectorNumber{preseal.SectorID},
|
||||
}
|
||||
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, builtin.StoragePowerActorAddr, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
|
||||
}
|
||||
@ -310,7 +309,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
|
||||
// Sanity-check total network power
|
||||
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
|
||||
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
|
||||
if !st.TotalRawBytePower.Equals(rawPow) {
|
||||
return xerrors.Errorf("st.TotalRawBytePower doesn't match previously calculated rawPow")
|
||||
}
|
||||
@ -349,12 +348,12 @@ func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization cry
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power.CurrentTotalPowerReturn, error) {
|
||||
pwret, err := doExecValue(ctx, vm, builtin.StoragePowerActorAddr, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
|
||||
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
||||
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pwr power.CurrentTotalPowerReturn
|
||||
var pwr power0.CurrentTotalPowerReturn
|
||||
if err := pwr.UnmarshalCBOR(bytes.NewReader(pwret)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -362,38 +361,38 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*
|
||||
return &pwr, nil
|
||||
}
|
||||
|
||||
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market.VerifyDealsForActivationReturn, error) {
|
||||
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market0.VerifyDealsForActivationReturn, error) {
|
||||
params := &market.VerifyDealsForActivationParams{
|
||||
DealIDs: dealIDs,
|
||||
SectorStart: sectorStart,
|
||||
SectorExpiry: sectorExpiry,
|
||||
}
|
||||
|
||||
var dealWeights market.VerifyDealsForActivationReturn
|
||||
var dealWeights market0.VerifyDealsForActivationReturn
|
||||
ret, err := doExecValue(ctx, vm,
|
||||
builtin.StorageMarketActorAddr,
|
||||
market.Address,
|
||||
maddr,
|
||||
abi.NewTokenAmount(0),
|
||||
builtin.MethodsMarket.VerifyDealsForActivation,
|
||||
mustEnc(params),
|
||||
)
|
||||
if err != nil {
|
||||
return market.VerifyDealsForActivationReturn{}, err
|
||||
return market0.VerifyDealsForActivationReturn{}, err
|
||||
}
|
||||
if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
|
||||
return market.VerifyDealsForActivationReturn{}, err
|
||||
return market0.VerifyDealsForActivationReturn{}, err
|
||||
}
|
||||
|
||||
return dealWeights, nil
|
||||
}
|
||||
|
||||
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward.ThisEpochRewardReturn, error) {
|
||||
rwret, err := doExecValue(ctx, vm, builtin.RewardActorAddr, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
|
||||
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) {
|
||||
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var epochReward reward.ThisEpochRewardReturn
|
||||
var epochReward reward0.ThisEpochRewardReturn
|
||||
if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -17,7 +17,7 @@ import (
|
||||
func SetupRewardActor(bs bstore.Blockstore, qaPower big.Int) (*types.Actor, error) {
|
||||
cst := cbor.NewCborStore(bs)
|
||||
|
||||
st := reward.ConstructState(qaPower)
|
||||
st := reward0.ConstructState(qaPower)
|
||||
|
||||
hcid, err := cst.Put(context.TODO(), st)
|
||||
if err != nil {
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -30,7 +30,7 @@ func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sms := power.ConstructState(emptyMap, emptyMultiMap)
|
||||
sms := power0.ConstructState(emptyMap, emptyMultiMap)
|
||||
|
||||
stcid, err := store.Put(store.Context(), sms)
|
||||
if err != nil {
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -34,7 +34,7 @@ func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sms := verifreg.ConstructState(h, RootVerifierID)
|
||||
sms := verifreg0.ConstructState(h, RootVerifierID)
|
||||
|
||||
stcid, err := store.Put(store.Context(), sms)
|
||||
if err != nil {
|
||||
|
@ -3,6 +3,9 @@ package genesis
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -46,3 +49,14 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
|
||||
|
||||
return ret.Return, nil
|
||||
}
|
||||
|
||||
var GenesisNetworkVersion = func() network.Version { // TODO: Get from build/
|
||||
if build.UseNewestNetwork() { // TODO: Get from build/
|
||||
return build.NewestNetworkVersion // TODO: Get from build/
|
||||
} // TODO: Get from build/
|
||||
return network.Version1 // TODO: Get from build/
|
||||
}() // TODO: Get from build/
|
||||
|
||||
func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/
|
||||
return GenesisNetworkVersion // TODO: Get from build/
|
||||
} // TODO: Get from build/
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"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/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/events/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -151,7 +152,7 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
|
||||
}
|
||||
|
||||
smsg, err := fm.api.MpoolPushMessage(ctx, &types.Message{
|
||||
To: builtin.StorageMarketActorAddr,
|
||||
To: market.Address,
|
||||
From: wallet,
|
||||
Value: toAdd,
|
||||
Method: builtin.MethodsMarket.AddBalance,
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@ -47,7 +48,7 @@ func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, s
|
||||
func addFundsMsg(toAdd abi.TokenAmount, addr address.Address, wallet address.Address) *types.Message {
|
||||
params, _ := actors.SerializeParams(&addr)
|
||||
return &types.Message{
|
||||
To: builtin.StorageMarketActorAddr,
|
||||
To: market.Address,
|
||||
From: wallet,
|
||||
Value: toAdd,
|
||||
Method: builtin.MethodsMarket.AddBalance,
|
||||
|
@ -47,13 +47,15 @@ func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error {
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) GetActorAfter(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
var act types.Actor
|
||||
stcid, _, err := mpp.sm.TipSetState(context.TODO(), ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("computing tipset state for GetActor: %w", err)
|
||||
}
|
||||
|
||||
return &act, mpp.sm.WithStateTree(stcid, mpp.sm.WithActor(addr, stmgr.GetActor(&act)))
|
||||
st, err := mpp.sm.StateTree(stcid)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load state tree: %w", err)
|
||||
}
|
||||
return st.GetActor(addr)
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
|
@ -1216,6 +1216,9 @@ func makeZipfPremiumDistribution(rng *rand.Rand) func() uint64 {
|
||||
}
|
||||
|
||||
func TestCompetitiveMessageSelectionExp(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping in short mode")
|
||||
}
|
||||
var capacityBoost, rewardBoost, tqReward float64
|
||||
seeds := []int64{1947, 1976, 2020, 2100, 10000, 143324, 432432, 131, 32, 45}
|
||||
for _, seed := range seeds {
|
||||
|
@ -1,14 +1,10 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
@ -16,6 +12,12 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@ -23,8 +25,10 @@ var log = logging.Logger("statetree")
|
||||
|
||||
// StateTree stores actors state by their ID.
|
||||
type StateTree struct {
|
||||
root *adt.Map
|
||||
Store cbor.IpldStore
|
||||
root adt.Map
|
||||
version builtin.Version // TODO
|
||||
info cid.Cid
|
||||
Store cbor.IpldStore
|
||||
|
||||
snaps *stateSnaps
|
||||
}
|
||||
@ -116,26 +120,57 @@ func (ss *stateSnaps) deleteActor(addr address.Address) {
|
||||
ss.layers[len(ss.layers)-1].actors[addr] = streeOp{Delete: true}
|
||||
}
|
||||
|
||||
func NewStateTree(cst cbor.IpldStore) (*StateTree, error) {
|
||||
func NewStateTree(cst cbor.IpldStore, version builtin.Version) (*StateTree, error) {
|
||||
var info cid.Cid
|
||||
switch version {
|
||||
case builtin.Version0:
|
||||
// info is undefined
|
||||
default:
|
||||
return nil, xerrors.Errorf("unsupported state tree version: %d", version)
|
||||
}
|
||||
root, err := adt.NewMap(adt.WrapStore(context.TODO(), cst), version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &StateTree{
|
||||
root: adt.MakeEmptyMap(adt.WrapStore(context.TODO(), cst)),
|
||||
Store: cst,
|
||||
snaps: newStateSnaps(),
|
||||
root: root,
|
||||
info: info,
|
||||
version: version,
|
||||
Store: cst,
|
||||
snaps: newStateSnaps(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
||||
nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), c)
|
||||
var root types.StateRoot
|
||||
// Try loading as a new-style state-tree (version/actors tuple).
|
||||
if err := cst.Get(context.TODO(), c, &root); err != nil {
|
||||
// We failed to decode as the new version, must be an old version.
|
||||
root.Actors = c
|
||||
root.Version = builtin.Version0
|
||||
}
|
||||
|
||||
// If that fails, load as an old-style state-tree (direct hampt, version 0.
|
||||
nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), root.Actors, builtin.Version(root.Version))
|
||||
if err != nil {
|
||||
log.Errorf("loading hamt node %s failed: %s", c, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch root.Version {
|
||||
case builtin.Version0:
|
||||
// supported
|
||||
default:
|
||||
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version)
|
||||
}
|
||||
|
||||
return &StateTree{
|
||||
root: nd,
|
||||
Store: cst,
|
||||
snaps: newStateSnaps(),
|
||||
root: nd,
|
||||
info: root.Info,
|
||||
version: builtin.Version(root.Version),
|
||||
Store: cst,
|
||||
snaps: newStateSnaps(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -161,17 +196,17 @@ func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
|
||||
return resa, nil
|
||||
}
|
||||
|
||||
act, err := st.GetActor(builtin.InitActorAddr)
|
||||
act, err := st.GetActor(init_.Address)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("getting init actor: %w", err)
|
||||
}
|
||||
|
||||
var ias init_.State
|
||||
if err := st.Store.Get(context.TODO(), act.Head, &ias); err != nil {
|
||||
ias, err := init_.Load(&AdtStore{st.Store}, act)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("loading init actor state: %w", err)
|
||||
}
|
||||
|
||||
a, found, err := ias.ResolveAddress(&AdtStore{st.Store}, addr)
|
||||
a, found, err := ias.ResolveAddress(addr)
|
||||
if err == nil && !found {
|
||||
err = types.ErrActorNotFound
|
||||
}
|
||||
@ -265,7 +300,16 @@ func (st *StateTree) Flush(ctx context.Context) (cid.Cid, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return st.root.Root()
|
||||
root, err := st.root.Root()
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to flush state-tree hamt: %w", err)
|
||||
}
|
||||
// If we're version 0, return a raw tree.
|
||||
if st.version == builtin.Version0 {
|
||||
return root, nil
|
||||
}
|
||||
// Otherwise, return a versioned tree.
|
||||
return st.Store.Put(ctx, &types.StateRoot{Version: uint64(st.version), Actors: root, Info: st.info})
|
||||
}
|
||||
|
||||
func (st *StateTree) Snapshot(ctx context.Context) error {
|
||||
@ -283,19 +327,19 @@ func (st *StateTree) ClearSnapshot() {
|
||||
|
||||
func (st *StateTree) RegisterNewAddress(addr address.Address) (address.Address, error) {
|
||||
var out address.Address
|
||||
err := st.MutateActor(builtin.InitActorAddr, func(initact *types.Actor) error {
|
||||
var ias init_.State
|
||||
if err := st.Store.Get(context.TODO(), initact.Head, &ias); err != nil {
|
||||
err := st.MutateActor(init_.Address, func(initact *types.Actor) error {
|
||||
ias, err := init_.Load(&AdtStore{st.Store}, initact)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oaddr, err := ias.MapAddressToNewID(&AdtStore{st.Store}, addr)
|
||||
oaddr, err := ias.MapAddressToNewID(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out = oaddr
|
||||
|
||||
ncid, err := st.Store.Put(context.TODO(), &ias)
|
||||
ncid, err := st.Store.Put(context.TODO(), ias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -341,6 +385,7 @@ func (st *StateTree) MutateActor(addr address.Address, f func(*types.Actor) erro
|
||||
func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error {
|
||||
var act types.Actor
|
||||
return st.root.ForEach(&act, func(k string) error {
|
||||
act := act // copy
|
||||
addr, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("invalid address (%x) found in state tree key: %w", []byte(k), err)
|
||||
@ -349,3 +394,44 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error
|
||||
return f(addr, &act)
|
||||
})
|
||||
}
|
||||
|
||||
func Diff(oldTree, newTree *StateTree) (map[string]types.Actor, error) {
|
||||
out := map[string]types.Actor{}
|
||||
|
||||
var (
|
||||
ncval, ocval cbg.Deferred
|
||||
buf = bytes.NewReader(nil)
|
||||
)
|
||||
if err := newTree.root.ForEach(&ncval, func(k string) error {
|
||||
var act types.Actor
|
||||
|
||||
addr, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
||||
}
|
||||
|
||||
found, err := oldTree.root.Get(abi.AddrKey(addr), &ocval)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if found && bytes.Equal(ocval.Raw, ncval.Raw) {
|
||||
return nil // not changed
|
||||
}
|
||||
|
||||
buf.Reset(ncval.Raw)
|
||||
err = act.UnmarshalCBOR(buf)
|
||||
buf.Reset(nil)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out[addr.String()] = act
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
@ -5,17 +5,20 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
address "github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
address "github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
builtin2 "github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func BenchmarkStateTreeSet(b *testing.B) {
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst)
|
||||
st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@ -42,7 +45,7 @@ func BenchmarkStateTreeSet(b *testing.B) {
|
||||
|
||||
func BenchmarkStateTreeSetFlush(b *testing.B) {
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst)
|
||||
st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@ -72,7 +75,7 @@ func BenchmarkStateTreeSetFlush(b *testing.B) {
|
||||
|
||||
func BenchmarkStateTree10kGetActor(b *testing.B) {
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst)
|
||||
st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@ -114,7 +117,7 @@ func BenchmarkStateTree10kGetActor(b *testing.B) {
|
||||
|
||||
func TestSetCache(t *testing.T) {
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst)
|
||||
st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -151,7 +154,7 @@ func TestSetCache(t *testing.T) {
|
||||
func TestSnapshots(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst)
|
||||
st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -234,7 +237,7 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) {
|
||||
|
||||
func TestStateTreeConsistency(t *testing.T) {
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst)
|
||||
st, err := NewStateTree(cst, builtin2.VersionForNetwork(build.NewestNetworkVersion))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
|
||||
BaseFee: types.NewInt(0),
|
||||
}
|
||||
|
||||
vmi, err := vm.NewVM(vmopt)
|
||||
vmi, err := vm.NewVM(ctx, vmopt)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||
}
|
||||
@ -134,7 +134,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
|
||||
NtwkVersion: sm.GetNtwkVersion,
|
||||
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||
}
|
||||
vmi, err := vm.NewVM(vmopt)
|
||||
vmi, err := vm.NewVM(ctx, vmopt)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||
}
|
||||
|
@ -6,13 +6,14 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
@ -96,11 +97,8 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
return xerrors.Errorf("failed to get tipset at lookback height: %w", err)
|
||||
}
|
||||
|
||||
var lbtree *state.StateTree
|
||||
if err = sm.WithStateTree(lbts.ParentState(), func(state *state.StateTree) error {
|
||||
lbtree = state
|
||||
return nil
|
||||
}); err != nil {
|
||||
lbtree, err := sm.ParentState(lbts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading state tree failed: %w", err)
|
||||
}
|
||||
|
||||
@ -125,7 +123,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
// Take all excess funds away, put them into the reserve account
|
||||
err = fetree.ForEach(func(addr address.Address, act *types.Actor) error {
|
||||
switch act.Code {
|
||||
case builtin.AccountActorCodeID, builtin.MultisigActorCodeID, builtin.PaymentChannelActorCodeID:
|
||||
case builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.PaymentChannelActorCodeID:
|
||||
sysAcc, err := isSystemAccount(addr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("checking system account: %w", err)
|
||||
@ -138,9 +136,9 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
Amt: act.Balance,
|
||||
})
|
||||
}
|
||||
case builtin.StorageMinerActorCodeID:
|
||||
var st miner.State
|
||||
if err := sm.WithActorState(ctx, &st)(act); err != nil {
|
||||
case builtin0.StorageMinerActorCodeID:
|
||||
var st miner0.State
|
||||
if err := sm.ChainStore().Store(ctx).Get(ctx, act.Head, &st); err != nil {
|
||||
return xerrors.Errorf("failed to load miner state: %w", err)
|
||||
}
|
||||
|
||||
@ -176,8 +174,8 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
}
|
||||
|
||||
// pull up power table to give miners back some funds proportional to their power
|
||||
var ps power.State
|
||||
powAct, err := tree.GetActor(builtin.StoragePowerActorAddr)
|
||||
var ps power0.State
|
||||
powAct, err := tree.GetActor(builtin0.StoragePowerActorAddr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to load power actor: %w", err)
|
||||
}
|
||||
@ -205,7 +203,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
}
|
||||
|
||||
switch act.Code {
|
||||
case builtin.AccountActorCodeID, builtin.MultisigActorCodeID, builtin.PaymentChannelActorCodeID:
|
||||
case builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.PaymentChannelActorCodeID:
|
||||
nbalance := big.Min(prevBalance, AccountCap)
|
||||
if nbalance.Sign() != 0 {
|
||||
transfersBack = append(transfersBack, transfer{
|
||||
@ -214,18 +212,18 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
Amt: nbalance,
|
||||
})
|
||||
}
|
||||
case builtin.StorageMinerActorCodeID:
|
||||
var st miner.State
|
||||
if err := sm.WithActorState(ctx, &st)(act); err != nil {
|
||||
case builtin0.StorageMinerActorCodeID:
|
||||
var st miner0.State
|
||||
if err := sm.ChainStore().Store(ctx).Get(ctx, act.Head, &st); err != nil {
|
||||
return xerrors.Errorf("failed to load miner state: %w", err)
|
||||
}
|
||||
|
||||
var minfo miner.MinerInfo
|
||||
var minfo miner0.MinerInfo
|
||||
if err := cst.Get(ctx, st.Info, &minfo); err != nil {
|
||||
return xerrors.Errorf("failed to get miner info: %w", err)
|
||||
}
|
||||
|
||||
sectorsArr, err := adt.AsArray(sm.ChainStore().Store(ctx), st.Sectors)
|
||||
sectorsArr, err := adt0.AsArray(sm.ChainStore().Store(ctx), st.Sectors)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to load sectors array: %w", err)
|
||||
}
|
||||
@ -244,12 +242,12 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
// Now make sure to give each miner who had power at the lookback some FIL
|
||||
lbact, err := lbtree.GetActor(addr)
|
||||
if err == nil {
|
||||
var lbst miner.State
|
||||
if err := sm.WithActorState(ctx, &lbst)(lbact); err != nil {
|
||||
var lbst miner0.State
|
||||
if err := sm.ChainStore().Store(ctx).Get(ctx, lbact.Head, &lbst); err != nil {
|
||||
return xerrors.Errorf("failed to load miner state: %w", err)
|
||||
}
|
||||
|
||||
lbsectors, err := adt.AsArray(sm.ChainStore().Store(ctx), lbst.Sectors)
|
||||
lbsectors, err := adt0.AsArray(sm.ChainStore().Store(ctx), lbst.Sectors)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to load lb sectors array: %w", err)
|
||||
}
|
||||
@ -279,11 +277,11 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
}
|
||||
|
||||
// transfer all burnt funds back to the reserve account
|
||||
burntAct, err := tree.GetActor(builtin.BurntFundsActorAddr)
|
||||
burntAct, err := tree.GetActor(builtin0.BurntFundsActorAddr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to load burnt funds actor: %w", err)
|
||||
}
|
||||
if err := doTransfer(tree, builtin.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil {
|
||||
if err := doTransfer(tree, builtin0.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil {
|
||||
return xerrors.Errorf("failed to unburn funds: %w", err)
|
||||
}
|
||||
|
||||
|
@ -8,17 +8,15 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
. "github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@ -33,11 +31,9 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
}
|
||||
|
||||
const testForkHeight = 40
|
||||
@ -148,8 +144,8 @@ func TestForkHeightTriggers(t *testing.T) {
|
||||
}
|
||||
|
||||
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
|
||||
sm.SetVMConstructor(func(vmopt *vm.VMOpts) (*vm.VM, error) {
|
||||
nvm, err := vm.NewVM(vmopt)
|
||||
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
||||
nvm, err := vm.NewVM(ctx, vmopt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -168,7 +164,7 @@ func TestForkHeightTriggers(t *testing.T) {
|
||||
|
||||
m := &types.Message{
|
||||
From: cg.Banker(),
|
||||
To: builtin.InitActorAddr,
|
||||
To: lotusinit.Address,
|
||||
Method: builtin.MethodsInit.Exec,
|
||||
Params: enc,
|
||||
GasLimit: types.TestGasLimit,
|
||||
|
@ -2,7 +2,6 @@ package stmgr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -12,144 +11,56 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
type StateTreeCB func(state *state.StateTree) error
|
||||
|
||||
func (sm *StateManager) WithParentStateTsk(tsk types.TipSetKey, cb StateTreeCB) error {
|
||||
func (sm *StateManager) ParentStateTsk(tsk types.TipSetKey) (*state.StateTree, error) {
|
||||
ts, err := sm.cs.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return sm.ParentState(ts)
|
||||
}
|
||||
|
||||
func (sm *StateManager) ParentState(ts *types.TipSet) (*state.StateTree, error) {
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, sm.parentState(ts))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("load state tree: %w", err)
|
||||
return nil, xerrors.Errorf("load state tree: %w", err)
|
||||
}
|
||||
|
||||
return cb(state)
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithParentState(ts *types.TipSet, cb StateTreeCB) error {
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, sm.parentState(ts))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("load state tree: %w", err)
|
||||
}
|
||||
|
||||
return cb(state)
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithStateTree(st cid.Cid, cb StateTreeCB) error {
|
||||
func (sm *StateManager) StateTree(st cid.Cid) (*state.StateTree, error) {
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, st)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("load state tree: %w", err)
|
||||
return nil, xerrors.Errorf("load state tree: %w", err)
|
||||
}
|
||||
|
||||
return cb(state)
|
||||
return state, nil
|
||||
}
|
||||
|
||||
type ActorCB func(act *types.Actor) error
|
||||
|
||||
func GetActor(out *types.Actor) ActorCB {
|
||||
return func(act *types.Actor) error {
|
||||
*out = *act
|
||||
return nil
|
||||
func (sm *StateManager) LoadActor(_ context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
state, err := sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return state.GetActor(addr)
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithActor(addr address.Address, cb ActorCB) StateTreeCB {
|
||||
return func(state *state.StateTree) error {
|
||||
act, err := state.GetActor(addr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get actor: %w", err)
|
||||
}
|
||||
|
||||
return cb(act)
|
||||
func (sm *StateManager) LoadActorTsk(_ context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
state, err := sm.ParentStateTsk(tsk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return state.GetActor(addr)
|
||||
}
|
||||
|
||||
// WithActorState usage:
|
||||
// Option 1: WithActorState(ctx, idAddr, func(store adt.Store, st *ActorStateType) error {...})
|
||||
// Option 2: WithActorState(ctx, idAddr, actorStatePtr)
|
||||
func (sm *StateManager) WithActorState(ctx context.Context, out interface{}) ActorCB {
|
||||
return func(act *types.Actor) error {
|
||||
store := sm.cs.Store(ctx)
|
||||
|
||||
outCallback := reflect.TypeOf(out).Kind() == reflect.Func
|
||||
|
||||
var st reflect.Value
|
||||
if outCallback {
|
||||
st = reflect.New(reflect.TypeOf(out).In(1).Elem())
|
||||
} else {
|
||||
st = reflect.ValueOf(out)
|
||||
}
|
||||
if err := store.Get(ctx, act.Head, st.Interface()); err != nil {
|
||||
return xerrors.Errorf("read actor head: %w", err)
|
||||
}
|
||||
|
||||
if outCallback {
|
||||
out := reflect.ValueOf(out).Call([]reflect.Value{reflect.ValueOf(store), st})
|
||||
if !out[0].IsNil() && out[0].Interface().(error) != nil {
|
||||
return out[0].Interface().(error)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type DeadlinesCB func(store adt.Store, deadlines *miner.Deadlines) error
|
||||
|
||||
func (sm *StateManager) WithDeadlines(cb DeadlinesCB) func(store adt.Store, mas *miner.State) error {
|
||||
return func(store adt.Store, mas *miner.State) error {
|
||||
deadlines, err := mas.LoadDeadlines(store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cb(store, deadlines)
|
||||
}
|
||||
}
|
||||
|
||||
type DeadlineCB func(store adt.Store, idx uint64, deadline *miner.Deadline) error
|
||||
|
||||
func (sm *StateManager) WithDeadline(idx uint64, cb DeadlineCB) DeadlinesCB {
|
||||
return func(store adt.Store, deadlines *miner.Deadlines) error {
|
||||
d, err := deadlines.LoadDeadline(store, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cb(store, idx, d)
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithEachDeadline(cb DeadlineCB) DeadlinesCB {
|
||||
return func(store adt.Store, deadlines *miner.Deadlines) error {
|
||||
return deadlines.ForEach(store, func(dlIdx uint64, dl *miner.Deadline) error {
|
||||
return cb(store, dlIdx, dl)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type PartitionCB func(store adt.Store, idx uint64, partition *miner.Partition) error
|
||||
|
||||
func (sm *StateManager) WithEachPartition(cb PartitionCB) DeadlineCB {
|
||||
return func(store adt.Store, idx uint64, deadline *miner.Deadline) error {
|
||||
parts, err := deadline.PartitionsArray(store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var partition miner.Partition
|
||||
return parts.ForEach(&partition, func(i int64) error {
|
||||
p := partition
|
||||
return cb(store, uint64(i), &p)
|
||||
})
|
||||
func (sm *StateManager) LoadActorRaw(_ context.Context, addr address.Address, st cid.Cid) (*types.Actor, error) {
|
||||
state, err := sm.StateTree(st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return state.GetActor(addr)
|
||||
}
|
||||
|
@ -5,35 +5,35 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
|
||||
"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/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"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/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
)
|
||||
|
||||
var log = logging.Logger("statemgr")
|
||||
@ -45,7 +45,7 @@ type StateManager struct {
|
||||
compWait map[string]chan struct{}
|
||||
stlk sync.Mutex
|
||||
genesisMsigLk sync.Mutex
|
||||
newVM func(*vm.VMOpts) (*vm.VM, error)
|
||||
newVM func(context.Context, *vm.VMOpts) (*vm.VM, error)
|
||||
genInfo *genesisInfo
|
||||
}
|
||||
|
||||
@ -160,27 +160,27 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
BaseFee: baseFee,
|
||||
}
|
||||
|
||||
vmi, err := sm.newVM(vmopt)
|
||||
vmi, err := sm.newVM(ctx, vmopt)
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
||||
}
|
||||
|
||||
runCron := func() error {
|
||||
// TODO: this nonce-getting is a tiny bit ugly
|
||||
ca, err := vmi.StateTree().GetActor(builtin.SystemActorAddr)
|
||||
ca, err := vmi.StateTree().GetActor(builtin0.SystemActorAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cronMsg := &types.Message{
|
||||
To: builtin.CronActorAddr,
|
||||
From: builtin.SystemActorAddr,
|
||||
To: builtin0.CronActorAddr,
|
||||
From: builtin0.SystemActorAddr,
|
||||
Nonce: ca.Nonce,
|
||||
Value: types.NewInt(0),
|
||||
GasFeeCap: types.NewInt(0),
|
||||
GasPremium: types.NewInt(0),
|
||||
GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little
|
||||
Method: builtin.MethodsCron.EpochTick,
|
||||
Method: builtin0.MethodsCron.EpochTick,
|
||||
Params: nil,
|
||||
}
|
||||
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
|
||||
@ -201,6 +201,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
|
||||
for i := parentEpoch; i < epoch; i++ {
|
||||
// handle state forks
|
||||
// XXX: The state tree
|
||||
err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts)
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
|
||||
@ -244,7 +245,6 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
processedMsgs[m.Cid()] = true
|
||||
}
|
||||
|
||||
var err error
|
||||
params, err := actors.SerializeParams(&reward.AwardBlockRewardParams{
|
||||
Miner: b.Miner,
|
||||
Penalty: penalty,
|
||||
@ -255,24 +255,24 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to serialize award params: %w", err)
|
||||
}
|
||||
|
||||
sysAct, err := vmi.StateTree().GetActor(builtin.SystemActorAddr)
|
||||
if err != nil {
|
||||
sysAct, actErr := vmi.StateTree().GetActor(builtin0.SystemActorAddr)
|
||||
if actErr != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
|
||||
}
|
||||
|
||||
rwMsg := &types.Message{
|
||||
From: builtin.SystemActorAddr,
|
||||
To: builtin.RewardActorAddr,
|
||||
From: builtin0.SystemActorAddr,
|
||||
To: reward.Address,
|
||||
Nonce: sysAct.Nonce,
|
||||
Value: types.NewInt(0),
|
||||
GasFeeCap: types.NewInt(0),
|
||||
GasPremium: types.NewInt(0),
|
||||
GasLimit: 1 << 30,
|
||||
Method: builtin.MethodsReward.AwardBlockReward,
|
||||
Method: builtin0.MethodsReward.AwardBlockReward,
|
||||
Params: params,
|
||||
}
|
||||
ret, err := vmi.ApplyImplicitMessage(ctx, rwMsg)
|
||||
if err != nil {
|
||||
ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg)
|
||||
if actErr != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, err)
|
||||
}
|
||||
if cb != nil {
|
||||
@ -290,7 +290,11 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
return cid.Cid{}, cid.Cid{}, err
|
||||
}
|
||||
|
||||
rectarr := adt.MakeEmptyArray(sm.cs.Store(ctx))
|
||||
// XXX: Is the height correct? Or should it be epoch-1?
|
||||
rectarr, err := adt.NewArray(sm.cs.Store(ctx), builtin.VersionForNetwork(sm.GetNtwkVersion(ctx, epoch)))
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to create receipts amt: %w", err)
|
||||
}
|
||||
for i, receipt := range receipts {
|
||||
if err := rectarr.Set(uint64(i), receipt); err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err)
|
||||
@ -601,10 +605,9 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
|
||||
default:
|
||||
}
|
||||
|
||||
var act types.Actor
|
||||
err := sm.WithParentState(cur, sm.WithActor(m.VMMessage().From, GetActor(&act)))
|
||||
act, err := sm.LoadActor(ctx, m.VMMessage().From, cur)
|
||||
if err != nil {
|
||||
return nil, nil, cid.Undef, err
|
||||
return nil, nil, cid.Cid{}, err
|
||||
}
|
||||
|
||||
// we either have no messages from the sender, or the latest message we found has a lower nonce than the one being searched for,
|
||||
@ -689,17 +692,13 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r, err := adt.AsMap(sm.cs.Store(ctx), st)
|
||||
stateTree, err := sm.StateTree(st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out []address.Address
|
||||
err = r.ForEach(nil, func(k string) error {
|
||||
addr, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
||||
}
|
||||
err = stateTree.ForEach(func(addr address.Address, act *types.Actor) error {
|
||||
out = append(out, addr)
|
||||
return nil
|
||||
})
|
||||
@ -711,8 +710,17 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]
|
||||
}
|
||||
|
||||
func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) {
|
||||
var state market.State
|
||||
_, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts)
|
||||
st, err := sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return api.MarketBalance{}, err
|
||||
}
|
||||
|
||||
act, err := st.GetActor(market.Address)
|
||||
if err != nil {
|
||||
return api.MarketBalance{}, err
|
||||
}
|
||||
|
||||
mstate, err := market.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return api.MarketBalance{}, err
|
||||
}
|
||||
@ -724,7 +732,7 @@ func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address,
|
||||
|
||||
var out api.MarketBalance
|
||||
|
||||
et, err := adt.AsBalanceTable(sm.cs.Store(ctx), state.EscrowTable)
|
||||
et, err := mstate.EscrowTable()
|
||||
if err != nil {
|
||||
return api.MarketBalance{}, err
|
||||
}
|
||||
@ -733,7 +741,7 @@ func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address,
|
||||
return api.MarketBalance{}, xerrors.Errorf("getting escrow balance: %w", err)
|
||||
}
|
||||
|
||||
lt, err := adt.AsBalanceTable(sm.cs.Store(ctx), state.LockedTable)
|
||||
lt, err := mstate.LockedTable()
|
||||
if err != nil {
|
||||
return api.MarketBalance{}, err
|
||||
}
|
||||
@ -774,12 +782,12 @@ func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) SetVMConstructor(nvm func(*vm.VMOpts) (*vm.VM, error)) {
|
||||
func (sm *StateManager) SetVMConstructor(nvm func(context.Context, *vm.VMOpts) (*vm.VM, error)) {
|
||||
sm.newVM = nvm
|
||||
}
|
||||
|
||||
type genesisInfo struct {
|
||||
genesisMsigs []multisig.State
|
||||
genesisMsigs []msig0.State
|
||||
// info about the Accounts in the genesis state
|
||||
genesisActors []genesisActor
|
||||
genesisPledge abi.TokenAmount
|
||||
@ -827,51 +835,56 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
|
||||
return xerrors.Errorf("setting up genesis pledge: %w", err)
|
||||
}
|
||||
|
||||
r, err := adt.AsMap(sm.cs.Store(ctx), st)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis actors: %w", err)
|
||||
}
|
||||
|
||||
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
|
||||
var act types.Actor
|
||||
err = r.ForEach(&act, func(k string) error {
|
||||
if act.Code == builtin.MultisigActorCodeID {
|
||||
var s multisig.State
|
||||
err := sm.cs.Store(ctx).Get(ctx, act.Head, &s)
|
||||
err = sTree.ForEach(func(kaddr address.Address, act *types.Actor) error {
|
||||
if act.IsMultisigActor() {
|
||||
s, err := multisig.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.StartEpoch != 0 {
|
||||
se, err := s.StartEpoch()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if se != 0 {
|
||||
return xerrors.New("genesis multisig doesn't start vesting at epoch 0!")
|
||||
}
|
||||
|
||||
ot, f := totalsByEpoch[s.UnlockDuration]
|
||||
if f {
|
||||
totalsByEpoch[s.UnlockDuration] = big.Add(ot, s.InitialBalance)
|
||||
} else {
|
||||
totalsByEpoch[s.UnlockDuration] = s.InitialBalance
|
||||
ud, err := s.UnlockDuration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else if act.Code == builtin.AccountActorCodeID {
|
||||
ib, err := s.InitialBalance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ot, f := totalsByEpoch[ud]
|
||||
if f {
|
||||
totalsByEpoch[ud] = big.Add(ot, ib)
|
||||
} else {
|
||||
totalsByEpoch[ud] = ib
|
||||
}
|
||||
|
||||
} else if act.IsAccountActor() {
|
||||
// should exclude burnt funds actor and "remainder account actor"
|
||||
// should only ever be "faucet" accounts in testnets
|
||||
kaddr, err := address.NewFromBytes([]byte(k))
|
||||
if kaddr == builtin0.BurntFundsActorAddr {
|
||||
return nil
|
||||
}
|
||||
|
||||
kid, err := sTree.LookupID(kaddr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding address: %w", err)
|
||||
return xerrors.Errorf("resolving address: %w", err)
|
||||
}
|
||||
|
||||
if kaddr != builtin.BurntFundsActorAddr {
|
||||
kid, err := sTree.LookupID(kaddr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("resolving address: %w", err)
|
||||
}
|
||||
|
||||
gi.genesisActors = append(gi.genesisActors, genesisActor{
|
||||
addr: kid,
|
||||
initBal: act.Balance,
|
||||
})
|
||||
}
|
||||
gi.genesisActors = append(gi.genesisActors, genesisActor{
|
||||
addr: kid,
|
||||
initBal: act.Balance,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -880,9 +893,10 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
|
||||
return xerrors.Errorf("error setting up genesis infos: %w", err)
|
||||
}
|
||||
|
||||
gi.genesisMsigs = make([]multisig.State, 0, len(totalsByEpoch))
|
||||
// TODO: use network upgrade abstractions or always start at actors v0?
|
||||
gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
for k, v := range totalsByEpoch {
|
||||
ns := multisig.State{
|
||||
ns := msig0.State{
|
||||
InitialBalance: v,
|
||||
UnlockDuration: k,
|
||||
PendingTxns: cid.Undef,
|
||||
@ -936,30 +950,30 @@ func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error {
|
||||
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
|
||||
|
||||
// 6 months
|
||||
sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay)
|
||||
sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay)
|
||||
totalsByEpoch[sixMonths] = big.NewInt(49_929_341)
|
||||
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
|
||||
|
||||
// 1 year
|
||||
oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay)
|
||||
oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay)
|
||||
totalsByEpoch[oneYear] = big.NewInt(22_421_712)
|
||||
|
||||
// 2 years
|
||||
twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
|
||||
twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay)
|
||||
totalsByEpoch[twoYears] = big.NewInt(7_223_364)
|
||||
|
||||
// 3 years
|
||||
threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
|
||||
threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay)
|
||||
totalsByEpoch[threeYears] = big.NewInt(87_637_883)
|
||||
|
||||
// 6 years
|
||||
sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay)
|
||||
sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay)
|
||||
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
|
||||
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
|
||||
|
||||
gi.genesisMsigs = make([]multisig.State, 0, len(totalsByEpoch))
|
||||
gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
for k, v := range totalsByEpoch {
|
||||
ns := multisig.State{
|
||||
ns := msig0.State{
|
||||
InitialBalance: v,
|
||||
UnlockDuration: k,
|
||||
PendingTxns: cid.Undef,
|
||||
@ -1002,46 +1016,45 @@ func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch,
|
||||
}
|
||||
|
||||
func GetFilMined(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
ractor, err := st.GetActor(builtin.RewardActorAddr)
|
||||
ractor, err := st.GetActor(reward.Address)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load reward actor state: %w", err)
|
||||
}
|
||||
|
||||
var rst reward.State
|
||||
if err := st.Store.Get(ctx, ractor.Head, &rst); err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load reward state: %w", err)
|
||||
rst, err := reward.Load(adt.WrapStore(ctx, st.Store), ractor)
|
||||
if err != nil {
|
||||
return big.Zero(), err
|
||||
}
|
||||
|
||||
return rst.TotalMined, nil
|
||||
return rst.TotalStoragePowerReward()
|
||||
}
|
||||
|
||||
func getFilMarketLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
mactor, err := st.GetActor(builtin.StorageMarketActorAddr)
|
||||
act, err := st.GetActor(market.Address)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load market actor: %w", err)
|
||||
}
|
||||
|
||||
var mst market.State
|
||||
if err := st.Store.Get(ctx, mactor.Head, &mst); err != nil {
|
||||
mst, err := market.Load(adt.WrapStore(ctx, st.Store), act)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load market state: %w", err)
|
||||
}
|
||||
|
||||
fml := types.BigAdd(mst.TotalClientLockedCollateral, mst.TotalProviderLockedCollateral)
|
||||
fml = types.BigAdd(fml, mst.TotalClientStorageFee)
|
||||
return fml, nil
|
||||
return mst.TotalLocked()
|
||||
}
|
||||
|
||||
func getFilPowerLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
pactor, err := st.GetActor(builtin.StoragePowerActorAddr)
|
||||
pactor, err := st.GetActor(power.Address)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load power actor: %w", err)
|
||||
}
|
||||
|
||||
var pst power.State
|
||||
if err := st.Store.Get(ctx, pactor.Head, &pst); err != nil {
|
||||
pst, err := power.Load(adt.WrapStore(ctx, st.Store), pactor)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load power state: %w", err)
|
||||
}
|
||||
return pst.TotalPledgeCollateral, nil
|
||||
|
||||
return pst.TotalLocked()
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
@ -1060,7 +1073,7 @@ func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) (
|
||||
}
|
||||
|
||||
func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
burnt, err := st.GetActor(builtin.BurntFundsActorAddr)
|
||||
burnt, err := st.GetActor(builtin0.BurntFundsActorAddr)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err)
|
||||
}
|
||||
@ -1125,6 +1138,8 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
|
||||
// TODO: move hard fork epoch checks to a schedule defined in build/
|
||||
|
||||
if build.UseNewestNetwork() {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
@ -1139,3 +1154,39 @@ func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoc
|
||||
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) {
|
||||
st, err := sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
act, err := st.GetActor(addr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
actState, err := paych.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return act, actState, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetMarketState(ctx context.Context, ts *types.TipSet) (market.State, error) {
|
||||
st, err := sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
act, err := st.GetActor(market.Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
actState, err := market.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return actState, nil
|
||||
}
|
||||
|
@ -9,11 +9,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
saruntime "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -21,210 +17,176 @@ import (
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/cron"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron"
|
||||
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
func GetNetworkName(ctx context.Context, sm *StateManager, st cid.Cid) (dtypes.NetworkName, error) {
|
||||
var state init_.State
|
||||
err := sm.WithStateTree(st, sm.WithActor(builtin.InitActorAddr, sm.WithActorState(ctx, &state)))
|
||||
act, err := sm.LoadActorRaw(ctx, init_.Address, st)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ias, err := init_.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return dtypes.NetworkName(state.NetworkName), nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) LoadActorState(ctx context.Context, addr address.Address, out interface{}, ts *types.TipSet) (*types.Actor, error) {
|
||||
var a *types.Actor
|
||||
if err := sm.WithParentState(ts, sm.WithActor(addr, func(act *types.Actor) error {
|
||||
a = act
|
||||
return sm.WithActorState(ctx, out)(act)
|
||||
})); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) LoadActorStateRaw(ctx context.Context, addr address.Address, out interface{}, st cid.Cid) (*types.Actor, error) {
|
||||
var a *types.Actor
|
||||
if err := sm.WithStateTree(st, sm.WithActor(addr, func(act *types.Actor) error {
|
||||
a = act
|
||||
return sm.WithActorState(ctx, out)(act)
|
||||
})); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a, nil
|
||||
return ias.NetworkName()
|
||||
}
|
||||
|
||||
func GetMinerWorkerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorStateRaw(ctx, maddr, &mas, st)
|
||||
state, err := sm.StateTree(st)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("(get sset) failed to load state tree: %w", err)
|
||||
}
|
||||
act, err := state.GetActor(maddr)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("(get sset) failed to load miner actor: %w", err)
|
||||
}
|
||||
mas, err := miner.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, st)
|
||||
info, err := mas.Info()
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("load state tree: %w", err)
|
||||
return address.Undef, xerrors.Errorf("failed to load actor info: %w", err)
|
||||
}
|
||||
|
||||
info, err := mas.GetInfo(sm.cs.Store(ctx))
|
||||
if err != nil {
|
||||
return address.Address{}, err
|
||||
}
|
||||
|
||||
return vm.ResolveToKeyAddr(state, cst, info.Worker)
|
||||
return vm.ResolveToKeyAddr(state, sm.cs.Store(ctx), info.Worker)
|
||||
}
|
||||
|
||||
func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (power.Claim, power.Claim, error) {
|
||||
func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (power.Claim, power.Claim, bool, error) {
|
||||
return GetPowerRaw(ctx, sm, ts.ParentState(), maddr)
|
||||
}
|
||||
|
||||
func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (power.Claim, power.Claim, error) {
|
||||
var ps power.State
|
||||
_, err := sm.LoadActorStateRaw(ctx, builtin.StoragePowerActorAddr, &ps, st)
|
||||
func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (power.Claim, power.Claim, bool, error) {
|
||||
act, err := sm.LoadActorRaw(ctx, power.Address, st)
|
||||
if err != nil {
|
||||
return power.Claim{}, power.Claim{}, xerrors.Errorf("(get sset) failed to load power actor state: %w", err)
|
||||
return power.Claim{}, power.Claim{}, false, xerrors.Errorf("(get sset) failed to load power actor state: %w", err)
|
||||
}
|
||||
|
||||
pas, err := power.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return power.Claim{}, power.Claim{}, false, err
|
||||
}
|
||||
|
||||
tpow, err := pas.TotalPower()
|
||||
if err != nil {
|
||||
return power.Claim{}, power.Claim{}, false, err
|
||||
}
|
||||
|
||||
var mpow power.Claim
|
||||
if maddr != address.Undef {
|
||||
cm, err := adt.AsMap(sm.cs.Store(ctx), ps.Claims)
|
||||
if err != nil {
|
||||
return power.Claim{}, power.Claim{}, err
|
||||
var found bool
|
||||
mpow, found, err = pas.MinerPower(maddr)
|
||||
if err != nil || !found {
|
||||
// TODO: return an error when not found?
|
||||
return power.Claim{}, power.Claim{}, false, err
|
||||
}
|
||||
|
||||
var claim power.Claim
|
||||
if _, err := cm.Get(abi.AddrKey(maddr), &claim); err != nil {
|
||||
return power.Claim{}, power.Claim{}, err
|
||||
}
|
||||
|
||||
mpow = claim
|
||||
}
|
||||
|
||||
return mpow, power.Claim{
|
||||
RawBytePower: ps.TotalRawBytePower,
|
||||
QualityAdjPower: ps.TotalQualityAdjPower,
|
||||
}, nil
|
||||
minpow, err := pas.MinerNominalPowerMeetsConsensusMinimum(maddr)
|
||||
if err != nil {
|
||||
return power.Claim{}, power.Claim{}, false, err
|
||||
}
|
||||
|
||||
return mpow, tpow, minpow, nil
|
||||
}
|
||||
|
||||
func PreCommitInfo(ctx context.Context, sm *StateManager, maddr address.Address, sid abi.SectorNumber, ts *types.TipSet) (miner.SectorPreCommitOnChainInfo, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
func PreCommitInfo(ctx context.Context, sm *StateManager, maddr address.Address, sid abi.SectorNumber, ts *types.TipSet) (*miner.SectorPreCommitOnChainInfo, error) {
|
||||
act, err := sm.LoadActor(ctx, maddr, ts)
|
||||
if err != nil {
|
||||
return miner.SectorPreCommitOnChainInfo{}, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor: %w", err)
|
||||
}
|
||||
|
||||
i, ok, err := mas.GetPrecommittedSector(sm.cs.Store(ctx), sid)
|
||||
mas, err := miner.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return miner.SectorPreCommitOnChainInfo{}, err
|
||||
}
|
||||
if !ok {
|
||||
return miner.SectorPreCommitOnChainInfo{}, xerrors.New("precommit not found")
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
return *i, nil
|
||||
return mas.GetPrecommittedSector(sid)
|
||||
}
|
||||
|
||||
func MinerSectorInfo(ctx context.Context, sm *StateManager, maddr address.Address, sid abi.SectorNumber, ts *types.TipSet) (*miner.SectorOnChainInfo, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
act, err := sm.LoadActor(ctx, maddr, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor: %w", err)
|
||||
}
|
||||
|
||||
mas, err := miner.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
sectorInfo, ok, err := mas.GetSector(sm.cs.Store(ctx), sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return sectorInfo, nil
|
||||
return mas.GetSector(sid)
|
||||
}
|
||||
|
||||
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, filter *bitfield.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, snos *bitfield.BitField) ([]*miner.SectorOnChainInfo, error) {
|
||||
act, err := sm.LoadActor(ctx, maddr, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor: %w", err)
|
||||
}
|
||||
|
||||
mas, err := miner.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.Sectors, filter, filterOut)
|
||||
return mas.LoadSectors(snos)
|
||||
}
|
||||
|
||||
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]proof.SectorInfo, error) {
|
||||
var partsProving []bitfield.BitField
|
||||
var mas *miner.State
|
||||
var info *miner.MinerInfo
|
||||
|
||||
err := sm.WithStateTree(st, sm.WithActor(maddr, sm.WithActorState(ctx, func(store adt.Store, mst *miner.State) error {
|
||||
var err error
|
||||
|
||||
mas = mst
|
||||
|
||||
info, err = mas.GetInfo(store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner info: %w", err)
|
||||
}
|
||||
|
||||
deadlines, err := mas.LoadDeadlines(store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading deadlines: %w", err)
|
||||
}
|
||||
|
||||
return deadlines.ForEach(store, func(dlIdx uint64, deadline *miner.Deadline) error {
|
||||
partitions, err := deadline.PartitionsArray(store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting partition array: %w", err)
|
||||
}
|
||||
|
||||
var partition miner.Partition
|
||||
return partitions.ForEach(&partition, func(partIdx int64) error {
|
||||
p, err := bitfield.SubtractBitField(partition.Sectors, partition.Faults)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("subtract faults from partition sectors: %w", err)
|
||||
}
|
||||
|
||||
partsProving = append(partsProving, p)
|
||||
|
||||
return nil
|
||||
})
|
||||
})
|
||||
})))
|
||||
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]proof0.SectorInfo, error) {
|
||||
act, err := sm.LoadActorRaw(ctx, maddr, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
|
||||
}
|
||||
|
||||
provingSectors, err := bitfield.MultiMerge(partsProving...)
|
||||
mas, err := miner.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("merge partition proving sets: %w", err)
|
||||
return nil, xerrors.Errorf("failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
// TODO (!!): Actor Update: Make this active sectors
|
||||
|
||||
allSectors, err := miner.AllPartSectors(mas, miner.Partition.AllSectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get all sectors: %w", err)
|
||||
}
|
||||
|
||||
faultySectors, err := miner.AllPartSectors(mas, miner.Partition.FaultySectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get faulty sectors: %w", err)
|
||||
}
|
||||
|
||||
provingSectors, err := bitfield.SubtractBitField(allSectors, faultySectors) // TODO: This is wrong, as it can contain faaults, change to just ActiveSectors in an upgrade
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("calc proving sectors: %w", err)
|
||||
}
|
||||
|
||||
numProvSect, err := provingSectors.Count()
|
||||
@ -237,6 +199,11 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
info, err := mas.Info()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting miner info: %w", err)
|
||||
}
|
||||
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(info.SectorSize)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting seal proof type: %w", err)
|
||||
@ -257,28 +224,31 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
||||
return nil, xerrors.Errorf("generating winning post challenges: %w", err)
|
||||
}
|
||||
|
||||
sectors, err := provingSectors.All(miner.SectorsMax)
|
||||
iter, err := provingSectors.BitIterator()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to enumerate all sector IDs: %w", err)
|
||||
return nil, xerrors.Errorf("iterating over proving sectors: %w", err)
|
||||
}
|
||||
|
||||
sectorAmt, err := adt.AsArray(sm.cs.Store(ctx), mas.Sectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load sectors amt: %w", err)
|
||||
}
|
||||
|
||||
out := make([]proof.SectorInfo, len(ids))
|
||||
for i, n := range ids {
|
||||
sid := sectors[n]
|
||||
|
||||
var sinfo miner.SectorOnChainInfo
|
||||
if found, err := sectorAmt.Get(sid, &sinfo); err != nil {
|
||||
return nil, xerrors.Errorf("failed to get sector %d: %w", sid, err)
|
||||
} else if !found {
|
||||
return nil, xerrors.Errorf("failed to find sector %d", sid)
|
||||
// Select winning sectors by _index_ in the all-sectors bitfield.
|
||||
selectedSectors := bitfield.New()
|
||||
prev := uint64(0)
|
||||
for _, n := range ids {
|
||||
sno, err := iter.Nth(n - prev)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("iterating over proving sectors: %w", err)
|
||||
}
|
||||
selectedSectors.Set(sno)
|
||||
prev = n
|
||||
}
|
||||
|
||||
out[i] = proof.SectorInfo{
|
||||
sectors, err := mas.LoadSectors(&selectedSectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading proving sectors: %w", err)
|
||||
}
|
||||
|
||||
out := make([]proof0.SectorInfo, len(sectors))
|
||||
for i, sinfo := range sectors {
|
||||
out[i] = proof0.SectorInfo{
|
||||
SealProof: spt,
|
||||
SectorNumber: sinfo.SectorNumber,
|
||||
SealedCID: sinfo.SealedCID,
|
||||
@ -289,33 +259,40 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
||||
}
|
||||
|
||||
func StateMinerInfo(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*miner.MinerInfo, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorStateRaw(ctx, maddr, &mas, ts.ParentState())
|
||||
act, err := sm.LoadActor(ctx, maddr, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err)
|
||||
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
|
||||
}
|
||||
|
||||
return mas.GetInfo(sm.cs.Store(ctx))
|
||||
mas, err := miner.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
mi, err := mas.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &mi, err
|
||||
}
|
||||
|
||||
func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (bool, error) {
|
||||
var spas power.State
|
||||
_, err := sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &spas, ts)
|
||||
act, err := sm.LoadActor(ctx, power.Address, ts)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("(get miner slashed) failed to load power actor state")
|
||||
return false, xerrors.Errorf("failed to load power actor: %w", err)
|
||||
}
|
||||
|
||||
store := sm.cs.Store(ctx)
|
||||
|
||||
claims, err := adt.AsMap(store, spas.Claims)
|
||||
spas, err := power.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("failed to load power actor state: %w", err)
|
||||
}
|
||||
|
||||
ok, err := claims.Get(abi.AddrKey(maddr), nil)
|
||||
_, ok, err := spas.MinerPower(maddr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("getting miner power: %w", err)
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return true, nil
|
||||
}
|
||||
@ -324,108 +301,61 @@ func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, ma
|
||||
}
|
||||
|
||||
func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) {
|
||||
var state market.State
|
||||
if _, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil {
|
||||
return nil, err
|
||||
act, err := sm.LoadActor(ctx, market.Address, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load market actor: %w", err)
|
||||
}
|
||||
store := sm.ChainStore().Store(ctx)
|
||||
|
||||
da, err := adt.AsArray(store, state.Proposals)
|
||||
state, err := market.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load market actor state: %w", err)
|
||||
}
|
||||
|
||||
proposals, err := state.Proposals()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dp market.DealProposal
|
||||
if found, err := da.Get(uint64(dealID), &dp); err != nil {
|
||||
proposal, found, err := proposals.Get(dealID)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !found {
|
||||
return nil, xerrors.Errorf("deal %d not found", dealID)
|
||||
}
|
||||
|
||||
sa, err := market.AsDealStateArray(store, state.States)
|
||||
states, err := state.States()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
st, found, err := sa.Get(dealID)
|
||||
st, found, err := states.Get(dealID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !found {
|
||||
st = &market.DealState{
|
||||
SectorStartEpoch: -1,
|
||||
LastUpdatedEpoch: -1,
|
||||
SlashEpoch: -1,
|
||||
}
|
||||
st = market.EmptyDealState()
|
||||
}
|
||||
|
||||
return &api.MarketDeal{
|
||||
Proposal: dp,
|
||||
Proposal: *proposal,
|
||||
State: *st,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([]address.Address, error) {
|
||||
var state power.State
|
||||
if _, err := sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &state, ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m, err := adt.AsMap(sm.cs.Store(ctx), state.Claims)
|
||||
act, err := sm.LoadActor(ctx, power.Address, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, xerrors.Errorf("failed to load power actor: %w", err)
|
||||
}
|
||||
|
||||
var miners []address.Address
|
||||
err = m.ForEach(nil, func(k string) error {
|
||||
a, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
miners = append(miners, a)
|
||||
return nil
|
||||
})
|
||||
powState, err := power.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, xerrors.Errorf("failed to load power actor state: %w", err)
|
||||
}
|
||||
|
||||
return miners, nil
|
||||
}
|
||||
|
||||
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid, filter *bitfield.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
|
||||
a, err := adt.AsArray(store.ActorStore(ctx, bs), ssc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sset []*api.ChainSectorInfo
|
||||
var v cbg.Deferred
|
||||
if err := a.ForEach(&v, func(i int64) error {
|
||||
if filter != nil {
|
||||
set, err := filter.IsSet(uint64(i))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("filter check error: %w", err)
|
||||
}
|
||||
if set == filterOut {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var oci miner.SectorOnChainInfo
|
||||
if err := cbor.DecodeInto(v.Raw, &oci); err != nil {
|
||||
return err
|
||||
}
|
||||
sset = append(sset, &api.ChainSectorInfo{
|
||||
Info: oci,
|
||||
ID: abi.SectorNumber(i),
|
||||
})
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sset, nil
|
||||
return powState.ListAllMiners()
|
||||
}
|
||||
|
||||
func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, msgs []*types.Message, ts *types.TipSet) (cid.Cid, []*api.InvocResult, error) {
|
||||
@ -449,7 +379,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
||||
NtwkVersion: sm.GetNtwkVersion,
|
||||
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||
}
|
||||
vmi, err := vm.NewVM(vmopt)
|
||||
vmi, err := vm.NewVM(ctx, vmopt)
|
||||
if err != nil {
|
||||
return cid.Undef, nil, err
|
||||
}
|
||||
@ -537,9 +467,14 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mas miner.State
|
||||
if _, err := sm.LoadActorStateRaw(ctx, maddr, &mas, lbst); err != nil {
|
||||
return nil, err
|
||||
act, err := sm.LoadActorRaw(ctx, maddr, lbst)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
|
||||
}
|
||||
|
||||
mas, err := miner.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
@ -554,19 +489,19 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
||||
|
||||
sectors, err := GetSectorsForWinningPoSt(ctx, pv, sm, lbst, maddr, prand)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting wpost proving set: %w", err)
|
||||
return nil, xerrors.Errorf("getting winning post proving set: %w", err)
|
||||
}
|
||||
|
||||
if len(sectors) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
mpow, tpow, err := GetPowerRaw(ctx, sm, lbst, maddr)
|
||||
mpow, tpow, hmp, err := GetPowerRaw(ctx, sm, lbst, maddr)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get power: %w", err)
|
||||
}
|
||||
|
||||
info, err := mas.GetInfo(sm.cs.Store(ctx))
|
||||
info, err := mas.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -576,11 +511,6 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
||||
return nil, xerrors.Errorf("resolving worker address: %w", err)
|
||||
}
|
||||
|
||||
hmp, err := MinerHasMinPower(ctx, sm, maddr, lbts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("determining if miner has min power failed: %w", err)
|
||||
}
|
||||
|
||||
return &api.MiningBaseInfo{
|
||||
MinerPower: mpow.QualityAdjPower,
|
||||
NetworkPower: tpow.QualityAdjPower,
|
||||
@ -605,24 +535,24 @@ var MethodsMap = map[cid.Cid]map[abi.MethodNum]MethodMeta{}
|
||||
func init() {
|
||||
cidToMethods := map[cid.Cid][2]interface{}{
|
||||
// builtin.SystemActorCodeID: {builtin.MethodsSystem, system.Actor{} }- apparently it doesn't have methods
|
||||
builtin.InitActorCodeID: {builtin.MethodsInit, init_.Actor{}},
|
||||
builtin.CronActorCodeID: {builtin.MethodsCron, cron.Actor{}},
|
||||
builtin.AccountActorCodeID: {builtin.MethodsAccount, account.Actor{}},
|
||||
builtin.StoragePowerActorCodeID: {builtin.MethodsPower, power.Actor{}},
|
||||
builtin.StorageMinerActorCodeID: {builtin.MethodsMiner, miner.Actor{}},
|
||||
builtin.StorageMarketActorCodeID: {builtin.MethodsMarket, market.Actor{}},
|
||||
builtin.PaymentChannelActorCodeID: {builtin.MethodsPaych, paych.Actor{}},
|
||||
builtin.MultisigActorCodeID: {builtin.MethodsMultisig, multisig.Actor{}},
|
||||
builtin.RewardActorCodeID: {builtin.MethodsReward, reward.Actor{}},
|
||||
builtin.VerifiedRegistryActorCodeID: {builtin.MethodsVerifiedRegistry, verifreg.Actor{}},
|
||||
builtin0.InitActorCodeID: {builtin0.MethodsInit, init0.Actor{}},
|
||||
builtin0.CronActorCodeID: {builtin0.MethodsCron, cron0.Actor{}},
|
||||
builtin0.AccountActorCodeID: {builtin0.MethodsAccount, account0.Actor{}},
|
||||
builtin0.StoragePowerActorCodeID: {builtin0.MethodsPower, power0.Actor{}},
|
||||
builtin0.StorageMinerActorCodeID: {builtin0.MethodsMiner, miner0.Actor{}},
|
||||
builtin0.StorageMarketActorCodeID: {builtin0.MethodsMarket, market0.Actor{}},
|
||||
builtin0.PaymentChannelActorCodeID: {builtin0.MethodsPaych, paych0.Actor{}},
|
||||
builtin0.MultisigActorCodeID: {builtin0.MethodsMultisig, msig0.Actor{}},
|
||||
builtin0.RewardActorCodeID: {builtin0.MethodsReward, reward0.Actor{}},
|
||||
builtin0.VerifiedRegistryActorCodeID: {builtin0.MethodsVerifiedRegistry, verifreg0.Actor{}},
|
||||
}
|
||||
|
||||
for c, m := range cidToMethods {
|
||||
exports := m[1].(saruntime.Invokee).Exports()
|
||||
exports := m[1].(vm.Invokee).Exports()
|
||||
methods := make(map[abi.MethodNum]MethodMeta, len(exports))
|
||||
|
||||
// Explicitly add send, it's special.
|
||||
methods[builtin.MethodSend] = MethodMeta{
|
||||
methods[builtin0.MethodSend] = MethodMeta{
|
||||
Name: "Send",
|
||||
Params: reflect.TypeOf(new(abi.EmptyValue)),
|
||||
Ret: reflect.TypeOf(new(abi.EmptyValue)),
|
||||
@ -662,9 +592,9 @@ func init() {
|
||||
}
|
||||
|
||||
switch abi.MethodNum(number) {
|
||||
case builtin.MethodSend:
|
||||
case builtin0.MethodSend:
|
||||
panic("method 0 is reserved for Send")
|
||||
case builtin.MethodConstructor:
|
||||
case builtin0.MethodConstructor:
|
||||
if fnName != "Constructor" {
|
||||
panic("method 1 is reserved for Constructor")
|
||||
}
|
||||
@ -681,9 +611,9 @@ func init() {
|
||||
}
|
||||
|
||||
func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, method abi.MethodNum, ts *types.TipSet) (cbg.CBORUnmarshaler, error) {
|
||||
var act types.Actor
|
||||
if err := sm.WithParentState(ts, sm.WithActor(to, GetActor(&act))); err != nil {
|
||||
return nil, xerrors.Errorf("getting actor: %w", err)
|
||||
act, err := sm.LoadActor(ctx, to, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor: %w", err)
|
||||
}
|
||||
|
||||
m, found := MethodsMap[act.Code][method]
|
||||
@ -694,13 +624,17 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me
|
||||
}
|
||||
|
||||
func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Address, ts *types.TipSet) (bool, error) {
|
||||
var ps power.State
|
||||
_, err := sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &ps, ts)
|
||||
pact, err := sm.LoadActor(ctx, power.Address, ts)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("loading power actor state: %w", err)
|
||||
}
|
||||
|
||||
return ps.MinerNominalPowerMeetsConsensusMinimum(sm.ChainStore().Store(ctx), addr)
|
||||
ps, err := power.Load(sm.cs.Store(ctx), pact)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return ps.MinerNominalPowerMeetsConsensusMinimum(addr)
|
||||
}
|
||||
|
||||
func CheckTotalFIL(ctx context.Context, sm *StateManager, ts *types.TipSet) (abi.TokenAmount, error) {
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
@ -767,32 +766,16 @@ type BlockMessages struct {
|
||||
func (cs *ChainStore) BlockMsgsForTipset(ts *types.TipSet) ([]BlockMessages, error) {
|
||||
applied := make(map[address.Address]uint64)
|
||||
|
||||
cst := cbor.NewCborStore(cs.bs)
|
||||
st, err := state.LoadStateTree(cst, ts.Blocks()[0].ParentStateRoot)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load state tree")
|
||||
}
|
||||
|
||||
preloadAddr := func(a address.Address) error {
|
||||
if _, ok := applied[a]; !ok {
|
||||
act, err := st.GetActor(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
applied[a] = act.Nonce
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
selectMsg := func(m *types.Message) (bool, error) {
|
||||
if err := preloadAddr(m.From); err != nil {
|
||||
return false, err
|
||||
// The first match for a sender is guaranteed to have correct nonce -- the block isn't valid otherwise
|
||||
if _, ok := applied[m.From]; !ok {
|
||||
applied[m.From] = m.Nonce
|
||||
}
|
||||
|
||||
if applied[m.From] != m.Nonce {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
applied[m.From]++
|
||||
|
||||
return true, nil
|
||||
@ -1318,7 +1301,7 @@ func (cs *ChainStore) GetLatestBeaconEntry(ts *types.TipSet) (*types.BeaconEntry
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, xerrors.Errorf("found NO beacon entries in the 20 blocks prior to given tipset")
|
||||
return nil, xerrors.Errorf("found NO beacon entries in the 20 latest tipsets")
|
||||
}
|
||||
|
||||
type chainRand struct {
|
||||
|
@ -8,12 +8,9 @@ import (
|
||||
datastore "github.com/ipfs/go-datastore"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -22,11 +19,9 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
}
|
||||
|
||||
func BenchmarkGetRandomness(b *testing.B) {
|
||||
|
@ -4,12 +4,12 @@ import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
|
||||
big2 "github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
@ -34,16 +34,22 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
|
||||
return types.NewInt(0), xerrors.Errorf("load state tree: %w", err)
|
||||
}
|
||||
|
||||
act, err := state.GetActor(builtin.StoragePowerActorAddr)
|
||||
act, err := state.GetActor(power.Address)
|
||||
if err != nil {
|
||||
return types.NewInt(0), xerrors.Errorf("get power actor: %w", err)
|
||||
}
|
||||
|
||||
var st power.State
|
||||
if err := cst.Get(ctx, act.Head, &st); err != nil {
|
||||
return types.NewInt(0), xerrors.Errorf("get power actor head (%s, height=%d): %w", act.Head, ts.Height(), err)
|
||||
powState, err := power.Load(cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return types.NewInt(0), xerrors.Errorf("failed to load power actor state: %w", err)
|
||||
}
|
||||
tpow = st.TotalQualityAdjPower // TODO: REVIEW: Is this correct?
|
||||
|
||||
claim, err := powState.TotalPower()
|
||||
if err != nil {
|
||||
return types.NewInt(0), xerrors.Errorf("failed to get total power: %w", err)
|
||||
}
|
||||
|
||||
tpow = claim.QualityAdjPower // TODO: REVIEW: Is this correct?
|
||||
}
|
||||
|
||||
log2P := int64(0)
|
||||
|
@ -1,7 +1,6 @@
|
||||
package sub
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -11,7 +10,6 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
address "github.com/filecoin-project/go-address"
|
||||
miner "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
@ -28,6 +26,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@ -432,6 +431,7 @@ func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *typ
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
buf := bufbstore.NewBufferedBstore(bv.chain.Blockstore())
|
||||
cst := cbor.NewCborStore(buf)
|
||||
state, err := state.LoadStateTree(cst, st)
|
||||
@ -443,19 +443,12 @@ func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *typ
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
blk, err := bv.chain.Blockstore().Get(act.Head)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
aso := blk.RawData()
|
||||
|
||||
var mst miner.State
|
||||
err = mst.UnmarshalCBOR(bytes.NewReader(aso))
|
||||
mst, err := miner.Load(bv.chain.Store(ctx), act)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
info, err := mst.GetInfo(adt.WrapStore(ctx, cst))
|
||||
info, err := mst.Info()
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
188
chain/sync.go
188
chain/sync.go
@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -18,6 +17,7 @@ import (
|
||||
|
||||
"github.com/Gurpartap/async"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
@ -33,13 +33,12 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
blst "github.com/supranational/blst/bindings/go"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/exchange"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
@ -63,20 +62,12 @@ var (
|
||||
// where the Syncer publishes candidate chain heads to be synced.
|
||||
LocalIncoming = "incoming"
|
||||
|
||||
log = logging.Logger("chain")
|
||||
defaultMessageFetchWindowSize = 200
|
||||
)
|
||||
log = logging.Logger("chain")
|
||||
|
||||
func init() {
|
||||
if s := os.Getenv("LOTUS_BSYNC_MSG_WINDOW"); s != "" {
|
||||
val, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
log.Errorf("failed to parse LOTUS_BSYNC_MSG_WINDOW: %s", err)
|
||||
return
|
||||
}
|
||||
defaultMessageFetchWindowSize = val
|
||||
}
|
||||
}
|
||||
concurrentSyncRequests = exchange.ShufflePeersPrefix
|
||||
syncRequestBatchSize = 8
|
||||
syncRequestRetries = 5
|
||||
)
|
||||
|
||||
// Syncer is in charge of running the chain synchronization logic. As such, it
|
||||
// is tasked with these functions, amongst others:
|
||||
@ -132,8 +123,6 @@ type Syncer struct {
|
||||
|
||||
verifier ffiwrapper.Verifier
|
||||
|
||||
windowSize int
|
||||
|
||||
tickerCtxCancel context.CancelFunc
|
||||
|
||||
checkptLk sync.Mutex
|
||||
@ -175,7 +164,6 @@ func NewSyncer(ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.C
|
||||
receiptTracker: newBlockReceiptTracker(),
|
||||
connmgr: connmgr,
|
||||
verifier: verifier,
|
||||
windowSize: defaultMessageFetchWindowSize,
|
||||
|
||||
incoming: pubsub.New(50),
|
||||
}
|
||||
@ -387,21 +375,28 @@ func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) bool {
|
||||
return syncer.InformNewHead(from, fts)
|
||||
}
|
||||
|
||||
func copyBlockstore(from, to bstore.Blockstore) error {
|
||||
cids, err := from.AllKeysChan(context.TODO())
|
||||
func copyBlockstore(ctx context.Context, from, to bstore.Blockstore) error {
|
||||
ctx, span := trace.StartSpan(ctx, "copyBlockstore")
|
||||
defer span.End()
|
||||
|
||||
cids, err := from.AllKeysChan(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: should probably expose better methods on the blockstore for this operation
|
||||
var blks []blocks.Block
|
||||
for c := range cids {
|
||||
b, err := from.Get(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := to.Put(b); err != nil {
|
||||
return err
|
||||
}
|
||||
blks = append(blks, b)
|
||||
}
|
||||
|
||||
if err := to.PutMany(blks); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -640,26 +635,25 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
|
||||
}
|
||||
|
||||
func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, baseTs *types.TipSet) error {
|
||||
var spast power.State
|
||||
|
||||
_, err := syncer.sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &spast, baseTs)
|
||||
act, err := syncer.sm.LoadActor(ctx, power.Address, baseTs)
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("failed to load power actor: %w", err)
|
||||
}
|
||||
|
||||
cm, err := adt.AsMap(syncer.store.Store(ctx), spast.Claims)
|
||||
powState, err := power.Load(syncer.store.Store(ctx), act)
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("failed to load power actor state: %w", err)
|
||||
}
|
||||
|
||||
var claim power.Claim
|
||||
exist, err := cm.Get(abi.AddrKey(maddr), &claim)
|
||||
_, exist, err := powState.MinerPower(maddr)
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("failed to look up miner's claim: %w", err)
|
||||
}
|
||||
|
||||
if !exist {
|
||||
return xerrors.New("miner isn't valid")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -859,7 +853,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
||||
return xerrors.Errorf("received block was from slashed or invalid miner")
|
||||
}
|
||||
|
||||
mpow, tpow, err := stmgr.GetPowerRaw(ctx, syncer.sm, lbst, h.Miner)
|
||||
mpow, tpow, _, err := stmgr.GetPowerRaw(ctx, syncer.sm, lbst, h.Miner)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed getting power: %w", err)
|
||||
}
|
||||
@ -991,7 +985,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block
|
||||
|
||||
rand, err := store.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, h.Height, buf.Bytes())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get randomness for verifying winningPost proof: %w", err)
|
||||
return xerrors.Errorf("failed to get randomness for verifying winning post proof: %w", err)
|
||||
}
|
||||
|
||||
mid, err := address.IDFromAddress(h.Miner)
|
||||
@ -1483,8 +1477,6 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
|
||||
|
||||
span.AddAttributes(trace.Int64Attribute("num_headers", int64(len(headers))))
|
||||
|
||||
windowSize := syncer.windowSize
|
||||
mainLoop:
|
||||
for i := len(headers) - 1; i >= 0; {
|
||||
fts, err := syncer.store.TryFillTipSet(headers[i])
|
||||
if err != nil {
|
||||
@ -1498,35 +1490,20 @@ mainLoop:
|
||||
continue
|
||||
}
|
||||
|
||||
batchSize := windowSize
|
||||
batchSize := concurrentSyncRequests * syncRequestBatchSize
|
||||
if i < batchSize {
|
||||
batchSize = i
|
||||
batchSize = i + 1
|
||||
}
|
||||
|
||||
nextI := (i + 1) - batchSize // want to fetch batchSize values, 'i' points to last one we want to fetch, so its 'inclusive' of our request, thus we need to add one to our request start index
|
||||
|
||||
ss.SetStage(api.StageFetchingMessages)
|
||||
var bstout []*exchange.CompactedMessages
|
||||
for len(bstout) < batchSize {
|
||||
next := headers[nextI]
|
||||
|
||||
nreq := batchSize - len(bstout)
|
||||
bstips, err := syncer.Exchange.GetChainMessages(ctx, next, uint64(nreq))
|
||||
if err != nil {
|
||||
// TODO check errors for temporary nature
|
||||
if windowSize > 1 {
|
||||
windowSize /= 2
|
||||
log.Infof("error fetching messages: %s; reducing window size to %d and trying again", err, windowSize)
|
||||
continue mainLoop
|
||||
}
|
||||
return xerrors.Errorf("message processing failed: %w", err)
|
||||
}
|
||||
|
||||
bstout = append(bstout, bstips...)
|
||||
nextI += len(bstips)
|
||||
}
|
||||
startOffset := i + 1 - batchSize
|
||||
bstout, batchErr := syncer.fetchMessages(ctx, headers[startOffset:startOffset+batchSize], startOffset)
|
||||
ss.SetStage(api.StageMessages)
|
||||
|
||||
if batchErr != nil {
|
||||
return xerrors.Errorf("failed to fetch messages: %w", err)
|
||||
}
|
||||
|
||||
for bsi := 0; bsi < len(bstout); bsi++ {
|
||||
// temp storage so we don't persist data we dont want to
|
||||
bs := bstore.NewTemporary()
|
||||
@ -1546,36 +1523,91 @@ mainLoop:
|
||||
return err
|
||||
}
|
||||
|
||||
if err := persistMessages(bs, bstip); err != nil {
|
||||
if err := persistMessages(ctx, bs, bstip); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyBlockstore(bs, syncer.store.Blockstore()); err != nil {
|
||||
if err := copyBlockstore(ctx, bs, syncer.store.Blockstore()); err != nil {
|
||||
return xerrors.Errorf("message processing failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if i >= windowSize {
|
||||
newWindowSize := windowSize + 10
|
||||
if newWindowSize > int(exchange.MaxRequestLength) {
|
||||
newWindowSize = int(exchange.MaxRequestLength)
|
||||
}
|
||||
if newWindowSize > windowSize {
|
||||
windowSize = newWindowSize
|
||||
log.Infof("successfully fetched %d messages; increasing window size to %d", len(bstout), windowSize)
|
||||
}
|
||||
}
|
||||
|
||||
i -= batchSize
|
||||
}
|
||||
|
||||
// remember our window size
|
||||
syncer.windowSize = windowSize
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func persistMessages(bs bstore.Blockstore, bst *exchange.CompactedMessages) error {
|
||||
func (syncer *Syncer) fetchMessages(ctx context.Context, headers []*types.TipSet, startOffset int) ([]*exchange.CompactedMessages, error) {
|
||||
batchSize := len(headers)
|
||||
batch := make([]*exchange.CompactedMessages, batchSize)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var mx sync.Mutex
|
||||
var batchErr error
|
||||
|
||||
start := build.Clock.Now()
|
||||
|
||||
for j := 0; j < batchSize; j += syncRequestBatchSize {
|
||||
wg.Add(1)
|
||||
go func(j int) {
|
||||
defer wg.Done()
|
||||
|
||||
nreq := syncRequestBatchSize
|
||||
if j+nreq > batchSize {
|
||||
nreq = batchSize - j
|
||||
}
|
||||
|
||||
failed := false
|
||||
for offset := 0; !failed && offset < nreq; {
|
||||
nextI := j + offset
|
||||
lastI := j + nreq
|
||||
|
||||
var requestErr error
|
||||
var requestResult []*exchange.CompactedMessages
|
||||
for retry := 0; requestResult == nil && retry < syncRequestRetries; retry++ {
|
||||
if retry > 0 {
|
||||
log.Infof("fetching messages at %d (retry %d)", startOffset+nextI, retry)
|
||||
} else {
|
||||
log.Infof("fetching messages at %d", startOffset+nextI)
|
||||
}
|
||||
|
||||
result, err := syncer.Exchange.GetChainMessages(ctx, headers[nextI:lastI])
|
||||
if err != nil {
|
||||
requestErr = multierror.Append(requestErr, err)
|
||||
} else {
|
||||
requestResult = result
|
||||
}
|
||||
}
|
||||
|
||||
mx.Lock()
|
||||
if requestResult != nil {
|
||||
copy(batch[j+offset:], requestResult)
|
||||
offset += len(requestResult)
|
||||
} else {
|
||||
log.Errorf("error fetching messages at %d: %s", nextI, requestErr)
|
||||
batchErr = multierror.Append(batchErr, requestErr)
|
||||
failed = true
|
||||
}
|
||||
mx.Unlock()
|
||||
}
|
||||
}(j)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
if batchErr != nil {
|
||||
return nil, batchErr
|
||||
}
|
||||
|
||||
log.Infof("fetching messages for %d tipsets at %d done; took %s", batchSize, startOffset, build.Clock.Since(start))
|
||||
|
||||
return batch, nil
|
||||
}
|
||||
|
||||
func persistMessages(ctx context.Context, bs bstore.Blockstore, bst *exchange.CompactedMessages) error {
|
||||
_, span := trace.StartSpan(ctx, "persistMessages")
|
||||
defer span.End()
|
||||
|
||||
for _, m := range bst.Bls {
|
||||
//log.Infof("putting BLS message: %s", m.Cid())
|
||||
if _, err := store.PutMessage(bs, m); err != nil {
|
||||
@ -1707,7 +1739,7 @@ func (syncer *Syncer) getLatestBeaconEntry(_ context.Context, ts *types.TipSet)
|
||||
cur = next
|
||||
}
|
||||
|
||||
return nil, xerrors.Errorf("found NO beacon entries in the 20 blocks prior to given tipset")
|
||||
return nil, xerrors.Errorf("found NO beacon entries in the 20 latest tipsets")
|
||||
}
|
||||
|
||||
func (syncer *Syncer) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool {
|
||||
|
@ -19,13 +19,10 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
@ -43,11 +40,9 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
}
|
||||
|
||||
const source = 0
|
||||
@ -662,6 +657,49 @@ func TestDuplicateNonce(t *testing.T) {
|
||||
require.Equal(t, includedMsg, mft[0].VMMessage().Cid(), "messages for tipset didn't contain expected message")
|
||||
}
|
||||
|
||||
// This test asserts that a block that includes a message with bad nonce can't be synced. A nonce is "bad" if it can't
|
||||
// be applied on the parent state.
|
||||
func TestBadNonce(t *testing.T) {
|
||||
H := 10
|
||||
tu := prepSyncTest(t, H)
|
||||
|
||||
base := tu.g.CurTipset
|
||||
|
||||
// Produce a message from the banker with a bad nonce
|
||||
makeBadMsg := func() *types.SignedMessage {
|
||||
|
||||
ba, err := tu.nds[0].StateGetActor(context.TODO(), tu.g.Banker(), base.TipSet().Key())
|
||||
require.NoError(t, err)
|
||||
msg := types.Message{
|
||||
To: tu.g.Banker(),
|
||||
From: tu.g.Banker(),
|
||||
|
||||
Nonce: ba.Nonce + 5,
|
||||
|
||||
Value: types.NewInt(1),
|
||||
|
||||
Method: 0,
|
||||
|
||||
GasLimit: 100_000_000,
|
||||
GasFeeCap: types.NewInt(0),
|
||||
GasPremium: types.NewInt(0),
|
||||
}
|
||||
|
||||
sig, err := tu.g.Wallet().Sign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes())
|
||||
require.NoError(t, err)
|
||||
|
||||
return &types.SignedMessage{
|
||||
Message: msg,
|
||||
Signature: *sig,
|
||||
}
|
||||
}
|
||||
|
||||
msgs := make([][]*types.SignedMessage, 1)
|
||||
msgs[0] = []*types.SignedMessage{makeBadMsg()}
|
||||
|
||||
tu.mineOnBlock(base, 0, []int{0}, true, true, msgs)
|
||||
}
|
||||
|
||||
func BenchmarkSyncBasic(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
runSyncBenchLength(b, 100)
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
)
|
||||
|
||||
var ErrActorNotFound = errors.New("actor not found")
|
||||
@ -19,5 +19,17 @@ type Actor struct {
|
||||
}
|
||||
|
||||
func (a *Actor) IsAccountActor() bool {
|
||||
return a.Code == builtin.AccountActorCodeID
|
||||
return a.Code == builtin0.AccountActorCodeID
|
||||
}
|
||||
|
||||
func (a *Actor) IsStorageMinerActor() bool {
|
||||
return a.Code == builtin0.StorageMinerActorCodeID
|
||||
}
|
||||
|
||||
func (a *Actor) IsMultisigActor() bool {
|
||||
return a.Code == builtin0.MultisigActorCodeID
|
||||
}
|
||||
|
||||
func (a *Actor) IsPaymentChannelActor() bool {
|
||||
return a.Code == builtin0.PaymentChannelActorCodeID
|
||||
}
|
||||
|
@ -1634,3 +1634,131 @@ func (t *BeaconEntry) UnmarshalCBOR(r io.Reader) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufStateRoot = []byte{131}
|
||||
|
||||
func (t *StateRoot) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufStateRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Version (uint64) (uint64)
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Version)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Actors (cid.Cid) (struct)
|
||||
|
||||
if err := cbg.WriteCidBuf(scratch, w, t.Actors); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.Actors: %w", err)
|
||||
}
|
||||
|
||||
// t.Info (cid.Cid) (struct)
|
||||
|
||||
if err := cbg.WriteCidBuf(scratch, w, t.Info); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.Info: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *StateRoot) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = StateRoot{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 3 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Version (uint64) (uint64)
|
||||
|
||||
{
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.Version = uint64(extra)
|
||||
|
||||
}
|
||||
// t.Actors (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.Actors: %w", err)
|
||||
}
|
||||
|
||||
t.Actors = c
|
||||
|
||||
}
|
||||
// t.Info (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.Info: %w", err)
|
||||
}
|
||||
|
||||
t.Info = c
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufStateInfo = []byte{128}
|
||||
|
||||
func (t *StateInfo) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufStateInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *StateInfo) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = StateInfo{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 0 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
15
chain/types/state.go
Normal file
15
chain/types/state.go
Normal file
@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
import "github.com/ipfs/go-cid"
|
||||
|
||||
type StateRoot struct {
|
||||
// State root version. Versioned along with actors (for now).
|
||||
Version uint64
|
||||
// Actors tree. The structure depends on the state root version.
|
||||
Actors cid.Cid
|
||||
// Info. The structure depends on the state root version.
|
||||
Info cid.Cid
|
||||
}
|
||||
|
||||
// TODO: version this.
|
||||
type StateInfo struct{}
|
@ -6,7 +6,7 @@ import (
|
||||
"math/rand"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"golang.org/x/xerrors"
|
||||
@ -19,15 +19,15 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types/mock"
|
||||
"github.com/filecoin-project/lotus/chain/vectors"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(2048)
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg0.MinVerifiedDealSize = big.NewInt(2048)
|
||||
power0.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
}
|
||||
|
||||
func MakeHeaderVectors() []vectors.HeaderVector {
|
||||
|
@ -22,6 +22,17 @@ type GasOutputs struct {
|
||||
GasBurned int64
|
||||
}
|
||||
|
||||
// ZeroGasOutputs returns a logically zeroed GasOutputs.
|
||||
func ZeroGasOutputs() GasOutputs {
|
||||
return GasOutputs{
|
||||
BaseFeeBurn: big.Zero(),
|
||||
OverEstimationBurn: big.Zero(),
|
||||
MinerPenalty: big.Zero(),
|
||||
MinerTip: big.Zero(),
|
||||
Refund: big.Zero(),
|
||||
}
|
||||
}
|
||||
|
||||
// ComputeGasOverestimationBurn computes amount of gas to be refunded and amount of gas to be burned
|
||||
// Result is (refund, burn)
|
||||
func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) {
|
||||
@ -58,13 +69,7 @@ func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) {
|
||||
|
||||
func ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.TokenAmount) GasOutputs {
|
||||
gasUsedBig := big.NewInt(gasUsed)
|
||||
out := GasOutputs{
|
||||
BaseFeeBurn: big.Zero(),
|
||||
OverEstimationBurn: big.Zero(),
|
||||
MinerPenalty: big.Zero(),
|
||||
MinerTip: big.Zero(),
|
||||
Refund: big.Zero(),
|
||||
}
|
||||
out := ZeroGasOutputs()
|
||||
|
||||
baseFeeToPay := baseFee
|
||||
if baseFee.Cmp(feeCap.Int) > 0 {
|
||||
|
@ -6,28 +6,28 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/cron"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/system"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron"
|
||||
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
system0 "github.com/filecoin-project/specs-actors/actors/builtin/system"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
)
|
||||
|
||||
type Invoker struct {
|
||||
@ -35,7 +35,7 @@ type Invoker struct {
|
||||
builtInState map[cid.Cid]reflect.Type
|
||||
}
|
||||
|
||||
type invokeFunc func(rt runtime.Runtime, params []byte) ([]byte, aerrors.ActorError)
|
||||
type invokeFunc func(rt vmr.Runtime, params []byte) ([]byte, aerrors.ActorError)
|
||||
type nativeCode []invokeFunc
|
||||
|
||||
func NewInvoker() *Invoker {
|
||||
@ -45,22 +45,23 @@ func NewInvoker() *Invoker {
|
||||
}
|
||||
|
||||
// add builtInCode using: register(cid, singleton)
|
||||
inv.Register(builtin.SystemActorCodeID, system.Actor{}, abi.EmptyValue{})
|
||||
inv.Register(builtin.InitActorCodeID, init_.Actor{}, init_.State{})
|
||||
inv.Register(builtin.RewardActorCodeID, reward.Actor{}, reward.State{})
|
||||
inv.Register(builtin.CronActorCodeID, cron.Actor{}, cron.State{})
|
||||
inv.Register(builtin.StoragePowerActorCodeID, power.Actor{}, power.State{})
|
||||
inv.Register(builtin.StorageMarketActorCodeID, market.Actor{}, market.State{})
|
||||
inv.Register(builtin.StorageMinerActorCodeID, miner.Actor{}, miner.State{})
|
||||
inv.Register(builtin.MultisigActorCodeID, multisig.Actor{}, multisig.State{})
|
||||
inv.Register(builtin.PaymentChannelActorCodeID, paych.Actor{}, paych.State{})
|
||||
inv.Register(builtin.VerifiedRegistryActorCodeID, verifreg.Actor{}, verifreg.State{})
|
||||
inv.Register(builtin.AccountActorCodeID, account.Actor{}, account.State{})
|
||||
// NETUPGRADE: register code IDs for v2, etc.
|
||||
inv.Register(builtin0.SystemActorCodeID, system0.Actor{}, abi.EmptyValue{})
|
||||
inv.Register(builtin0.InitActorCodeID, init0.Actor{}, init0.State{})
|
||||
inv.Register(builtin0.RewardActorCodeID, reward0.Actor{}, reward0.State{})
|
||||
inv.Register(builtin0.CronActorCodeID, cron0.Actor{}, cron0.State{})
|
||||
inv.Register(builtin0.StoragePowerActorCodeID, power0.Actor{}, power0.State{})
|
||||
inv.Register(builtin0.StorageMarketActorCodeID, market0.Actor{}, market0.State{})
|
||||
inv.Register(builtin0.StorageMinerActorCodeID, miner0.Actor{}, miner0.State{})
|
||||
inv.Register(builtin0.MultisigActorCodeID, msig0.Actor{}, msig0.State{})
|
||||
inv.Register(builtin0.PaymentChannelActorCodeID, paych0.Actor{}, paych0.State{})
|
||||
inv.Register(builtin0.VerifiedRegistryActorCodeID, verifreg0.Actor{}, verifreg0.State{})
|
||||
inv.Register(builtin0.AccountActorCodeID, account0.Actor{}, account0.State{})
|
||||
|
||||
return inv
|
||||
}
|
||||
|
||||
func (inv *Invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
||||
func (inv *Invoker) Invoke(codeCid cid.Cid, rt vmr.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
||||
|
||||
code, ok := inv.builtInCode[codeCid]
|
||||
if !ok {
|
||||
@ -176,7 +177,7 @@ func DecodeParams(b []byte, out interface{}) error {
|
||||
}
|
||||
|
||||
func DumpActorState(code cid.Cid, b []byte) (interface{}, error) {
|
||||
if code == builtin.AccountActorCodeID { // Account code special case
|
||||
if code == builtin0.AccountActorCodeID { // Account code special case
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -8,15 +8,14 @@ import (
|
||||
gruntime "runtime"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
rtt "github.com/filecoin-project/go-state-types/rt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
rtt "github.com/filecoin-project/go-state-types/rt"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
rt0 "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -318,14 +317,6 @@ func (rt *Runtime) CurrEpoch() abi.ChainEpoch {
|
||||
return rt.height
|
||||
}
|
||||
|
||||
type dumbWrapperType struct {
|
||||
val []byte
|
||||
}
|
||||
|
||||
func (dwt *dumbWrapperType) Into(um cbor.Unmarshaler) error {
|
||||
return um.UnmarshalCBOR(bytes.NewReader(dwt.val))
|
||||
}
|
||||
|
||||
func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m cbor.Marshaler, value abi.TokenAmount, out cbor.Er) exitcode.ExitCode {
|
||||
if !rt.allowInternal {
|
||||
rt.Abortf(exitcode.SysErrorIllegalActor, "runtime.Send() is currently disallowed")
|
||||
@ -391,8 +382,8 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum,
|
||||
|
||||
if subrt != nil {
|
||||
rt.numActorsCreated = subrt.numActorsCreated
|
||||
rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace)
|
||||
}
|
||||
rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace)
|
||||
return ret, errSend
|
||||
}
|
||||
|
||||
|
@ -18,12 +18,12 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
)
|
||||
@ -192,12 +192,12 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error {
|
||||
}
|
||||
|
||||
// use that to get the miner state
|
||||
var mas miner.State
|
||||
if err = ss.cst.Get(ss.ctx, act.Head, &mas); err != nil {
|
||||
mas, err := miner.Load(adt.WrapStore(ss.ctx, ss.cst), act)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info, err := mas.GetInfo(adt.WrapStore(ss.ctx, ss.cst))
|
||||
info, err := mas.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,15 +5,9 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
block "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
@ -25,15 +19,21 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/account"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/lib/bufbstore"
|
||||
)
|
||||
|
||||
@ -41,6 +41,12 @@ var log = logging.Logger("vm")
|
||||
var actorLog = logging.Logger("actors")
|
||||
var gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
|
||||
|
||||
// stat counters
|
||||
var (
|
||||
StatSends uint64
|
||||
StatApplied uint64
|
||||
)
|
||||
|
||||
// ResolveToKeyAddr returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`.
|
||||
func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Address) (address.Address, error) {
|
||||
if addr.Protocol() == address.BLS || addr.Protocol() == address.SECP256K1 {
|
||||
@ -52,16 +58,12 @@ func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Ad
|
||||
return address.Undef, xerrors.Errorf("failed to find actor: %s", addr)
|
||||
}
|
||||
|
||||
if act.Code != builtin.AccountActorCodeID {
|
||||
return address.Undef, xerrors.Errorf("address %s was not for an account actor", addr)
|
||||
}
|
||||
|
||||
var aast account.State
|
||||
if err := cst.Get(context.TODO(), act.Head, &aast); err != nil {
|
||||
aast, err := account.Load(adt.WrapStore(context.TODO(), cst), act)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("failed to get account actor state for %s: %w", addr, err)
|
||||
}
|
||||
|
||||
return aast.Address, nil
|
||||
return aast.PubkeyAddress()
|
||||
}
|
||||
|
||||
var _ cbor.IpldBlockstore = (*gasChargingBlocks)(nil)
|
||||
@ -166,11 +168,11 @@ type VMOpts struct {
|
||||
Bstore bstore.Blockstore
|
||||
Syscalls SyscallBuilder
|
||||
CircSupplyCalc CircSupplyCalculator
|
||||
NtwkVersion NtwkVersionGetter
|
||||
NtwkVersion NtwkVersionGetter // TODO: stebalien: In what cases do we actually need this? It seems like even when creating new networks we want to use the 'global'/build-default version getter
|
||||
BaseFee abi.TokenAmount
|
||||
}
|
||||
|
||||
func NewVM(opts *VMOpts) (*VM, error) {
|
||||
func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
|
||||
buf := bufbstore.NewBufferedBstore(opts.Bstore)
|
||||
cst := cbor.NewCborStore(buf)
|
||||
state, err := state.LoadStateTree(cst, opts.StateBase)
|
||||
@ -209,6 +211,8 @@ type ApplyRet struct {
|
||||
func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||
gasCharge *GasCharge, start time.Time) ([]byte, aerrors.ActorError, *Runtime) {
|
||||
|
||||
defer atomic.AddUint64(&StatSends, 1)
|
||||
|
||||
st := vm.cstate
|
||||
|
||||
origin := msg.From
|
||||
@ -317,6 +321,7 @@ func checkMessage(msg *types.Message) error {
|
||||
|
||||
func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) {
|
||||
start := build.Clock.Now()
|
||||
defer atomic.AddUint64(&StatApplied, 1)
|
||||
ret, actorErr, rt := vm.send(ctx, msg, nil, nil, start)
|
||||
rt.finilizeGasTracing()
|
||||
return &ApplyRet{
|
||||
@ -336,6 +341,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
start := build.Clock.Now()
|
||||
ctx, span := trace.StartSpan(ctx, "vm.ApplyMessage")
|
||||
defer span.End()
|
||||
defer atomic.AddUint64(&StatApplied, 1)
|
||||
msg := cmsg.VMMessage()
|
||||
if span.IsRecordingEvents() {
|
||||
span.AddAttributes(
|
||||
@ -355,14 +361,14 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
msgGasCost := msgGas.Total()
|
||||
// this should never happen, but is currently still exercised by some tests
|
||||
if msgGasCost > msg.GasLimit {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = types.BigMul(vm.baseFee, abi.NewTokenAmount(msgGasCost))
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrOutOfGas,
|
||||
GasUsed: 0,
|
||||
},
|
||||
GasCosts: GasOutputs{
|
||||
MinerPenalty: types.BigMul(vm.baseFee, abi.NewTokenAmount(msgGasCost)),
|
||||
},
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
}, nil
|
||||
}
|
||||
@ -374,15 +380,15 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
// this should never happen, but is currently still exercised by some tests
|
||||
if err != nil {
|
||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderInvalid,
|
||||
GasUsed: 0,
|
||||
},
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "actor not found: %s", msg.From),
|
||||
GasCosts: GasOutputs{
|
||||
MinerPenalty: minerPenaltyAmount,
|
||||
},
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
}, nil
|
||||
}
|
||||
@ -390,21 +396,23 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
}
|
||||
|
||||
// this should never happen, but is currently still exercised by some tests
|
||||
if !fromActor.Code.Equals(builtin.AccountActorCodeID) {
|
||||
if !fromActor.IsAccountActor() {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderInvalid,
|
||||
GasUsed: 0,
|
||||
},
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "send from not account actor: %s", fromActor.Code),
|
||||
GasCosts: GasOutputs{
|
||||
MinerPenalty: minerPenaltyAmount,
|
||||
},
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if msg.Nonce != fromActor.Nonce {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderStateInvalid,
|
||||
@ -413,15 +421,15 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid,
|
||||
"actor nonce invalid: msg:%d != state:%d", msg.Nonce, fromActor.Nonce),
|
||||
|
||||
GasCosts: GasOutputs{
|
||||
MinerPenalty: minerPenaltyAmount,
|
||||
},
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
}, nil
|
||||
}
|
||||
|
||||
gascost := types.BigMul(types.NewInt(uint64(msg.GasLimit)), msg.GasFeeCap)
|
||||
if fromActor.Balance.LessThan(gascost) {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderStateInvalid,
|
||||
@ -429,9 +437,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
},
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid,
|
||||
"actor balance less than needed: %s < %s", types.FIL(fromActor.Balance), types.FIL(gascost)),
|
||||
GasCosts: GasOutputs{
|
||||
MinerPenalty: minerPenaltyAmount,
|
||||
},
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
}, nil
|
||||
}
|
||||
@ -499,7 +505,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
return nil, xerrors.Errorf("failed to burn base fee: %w", err)
|
||||
}
|
||||
|
||||
if err := vm.transferFromGasHolder(builtin.RewardActorAddr, gasHolder, gasOutputs.MinerTip); err != nil {
|
||||
if err := vm.transferFromGasHolder(reward.Address, gasHolder, gasOutputs.MinerTip); err != nil {
|
||||
return nil, xerrors.Errorf("failed to give miner gas reward: %w", err)
|
||||
}
|
||||
|
||||
@ -551,7 +557,7 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
|
||||
return cid.Undef, xerrors.Errorf("flushing vm: %w", err)
|
||||
}
|
||||
|
||||
if err := Copy(from, to, root); err != nil {
|
||||
if err := Copy(ctx, from, to, root); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("copying tree: %w", err)
|
||||
}
|
||||
|
||||
@ -605,9 +611,18 @@ func linksForObj(blk block.Block, cb func(cid.Cid)) error {
|
||||
}
|
||||
}
|
||||
|
||||
func Copy(from, to blockstore.Blockstore, root cid.Cid) error {
|
||||
func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) error {
|
||||
ctx, span := trace.StartSpan(ctx, "vm.Copy") // nolint
|
||||
defer span.End()
|
||||
|
||||
var numBlocks int
|
||||
var totalCopySize int
|
||||
|
||||
var batch []block.Block
|
||||
batchCp := func(blk block.Block) error {
|
||||
numBlocks++
|
||||
totalCopySize += len(blk.RawData())
|
||||
|
||||
batch = append(batch, blk)
|
||||
if len(batch) > 100 {
|
||||
if err := to.PutMany(batch); err != nil {
|
||||
@ -628,6 +643,11 @@ func Copy(from, to blockstore.Blockstore, root cid.Cid) error {
|
||||
}
|
||||
}
|
||||
|
||||
span.AddAttributes(
|
||||
trace.Int64Attribute("numBlocks", int64(numBlocks)),
|
||||
trace.Int64Attribute("copySize", int64(totalCopySize)),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
38
cli/chain.go
38
cli/chain.go
@ -40,6 +40,7 @@ var chainCmd = &cli.Command{
|
||||
chainHeadCmd,
|
||||
chainGetBlock,
|
||||
chainReadObjCmd,
|
||||
chainDeleteObjCmd,
|
||||
chainStatObjCmd,
|
||||
chainGetMsgCmd,
|
||||
chainSetHeadCmd,
|
||||
@ -193,6 +194,43 @@ var chainReadObjCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainDeleteObjCmd = &cli.Command{
|
||||
Name: "delete-obj",
|
||||
Usage: "Delete an object from the chain blockstore",
|
||||
Description: "WARNING: Removing wrong objects from the chain blockstore may lead to sync issues",
|
||||
ArgsUsage: "[objectCid]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "really-do-it",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
c, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse cid input: %s", err)
|
||||
}
|
||||
|
||||
if !cctx.Bool("really-do-it") {
|
||||
return xerrors.Errorf("pass the --really-do-it flag to proceed")
|
||||
}
|
||||
|
||||
err = api.ChainDeleteObj(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Obj %s deleted\n", c.String())
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var chainStatObjCmd = &cli.Command{
|
||||
Name: "stat-obj",
|
||||
Usage: "Collect size and ipld link counts for objs",
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
tm "github.com/buger/goterm"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/fatih/color"
|
||||
@ -29,11 +31,11 @@ import (
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/tablewriter"
|
||||
)
|
||||
@ -527,6 +529,11 @@ func interactiveDeal(cctx *cli.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if days < int(build.MinDealDuration/builtin.EpochsInDay) {
|
||||
printErr(xerrors.Errorf("minimum duration is %d days", int(build.MinDealDuration/builtin.EpochsInDay)))
|
||||
continue
|
||||
}
|
||||
|
||||
state = "miner"
|
||||
case "miner":
|
||||
fmt.Print("Miner Address (t0..): ")
|
||||
@ -1044,12 +1051,8 @@ var clientListDeals = &cli.Command{
|
||||
func dealFromDealInfo(ctx context.Context, full api.FullNode, head *types.TipSet, v api.DealInfo) deal {
|
||||
if v.DealID == 0 {
|
||||
return deal{
|
||||
LocalDeal: v,
|
||||
OnChainDealState: market.DealState{
|
||||
SectorStartEpoch: -1,
|
||||
LastUpdatedEpoch: -1,
|
||||
SlashEpoch: -1,
|
||||
},
|
||||
LocalDeal: v,
|
||||
OnChainDealState: *market.EmptyDealState(),
|
||||
}
|
||||
}
|
||||
|
||||
|
125
cli/multisig.go
125
cli/multisig.go
@ -2,8 +2,6 @@ package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -16,21 +14,20 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var multisigCmd = &cli.Command{
|
||||
@ -153,7 +150,7 @@ var msigCreateCmd = &cli.Command{
|
||||
|
||||
// get address of newly created miner
|
||||
|
||||
var execreturn init_.ExecReturn
|
||||
var execreturn init0.ExecReturn
|
||||
if err := execreturn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -186,50 +183,73 @@ var msigInspectCmd = &cli.Command{
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
store := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(api)))
|
||||
|
||||
maddr, err := address.NewFromString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
obj, err := api.ChainReadObj(ctx, act.Head)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
head, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mstate samsig.State
|
||||
if err := mstate.UnmarshalCBOR(bytes.NewReader(obj)); err != nil {
|
||||
act, err := api.StateGetActor(ctx, maddr, head.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mstate, err := multisig.Load(store, act)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
locked, err := mstate.LockedBalance(head.Height())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
locked := mstate.AmountLocked(head.Height() - mstate.StartEpoch)
|
||||
fmt.Printf("Balance: %s\n", types.FIL(act.Balance))
|
||||
fmt.Printf("Spendable: %s\n", types.FIL(types.BigSub(act.Balance, locked)))
|
||||
|
||||
if cctx.Bool("vesting") {
|
||||
fmt.Printf("InitialBalance: %s\n", types.FIL(mstate.InitialBalance))
|
||||
fmt.Printf("StartEpoch: %d\n", mstate.StartEpoch)
|
||||
fmt.Printf("UnlockDuration: %d\n", mstate.UnlockDuration)
|
||||
ib, err := mstate.InitialBalance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("InitialBalance: %s\n", types.FIL(ib))
|
||||
se, err := mstate.StartEpoch()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("StartEpoch: %d\n", se)
|
||||
ud, err := mstate.UnlockDuration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("UnlockDuration: %d\n", ud)
|
||||
}
|
||||
|
||||
fmt.Printf("Threshold: %d / %d\n", mstate.NumApprovalsThreshold, len(mstate.Signers))
|
||||
signers, err := mstate.Signers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
threshold, err := mstate.Threshold()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Threshold: %d / %d\n", threshold, len(signers))
|
||||
fmt.Println("Signers:")
|
||||
for _, s := range mstate.Signers {
|
||||
for _, s := range signers {
|
||||
fmt.Printf("\t%s\n", s)
|
||||
}
|
||||
|
||||
pending, err := GetMultisigPending(ctx, api, mstate.PendingTxns)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading pending transactions: %w", err)
|
||||
pending := make(map[int64]multisig.Transaction)
|
||||
if err := mstate.ForEachPendingTxn(func(id int64, txn multisig.Transaction) error {
|
||||
pending[id] = txn
|
||||
return nil
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("reading pending transactions: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Transactions: ", len(pending))
|
||||
@ -246,7 +266,7 @@ var msigInspectCmd = &cli.Command{
|
||||
fmt.Fprintf(w, "ID\tState\tApprovals\tTo\tValue\tMethod\tParams\n")
|
||||
for _, txid := range txids {
|
||||
tx := pending[txid]
|
||||
fmt.Fprintf(w, "%d\t%s\t%d\t%s\t%s\t%d\t%x\n", txid, state(tx), len(tx.Approved), tx.To, types.FIL(tx.Value), tx.Method, tx.Params)
|
||||
fmt.Fprintf(w, "%d\t%s\t%d\t%s\t%s\t%d\t%x\n", txid, "pending", len(tx.Approved), tx.To, types.FIL(tx.Value), tx.Method, tx.Params)
|
||||
}
|
||||
if err := w.Flush(); err != nil {
|
||||
return xerrors.Errorf("flushing output: %+v", err)
|
||||
@ -258,43 +278,6 @@ var msigInspectCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) (map[int64]*samsig.Transaction, error) {
|
||||
bs := apibstore.NewAPIBlockstore(lapi)
|
||||
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||
|
||||
nd, err := adt.AsMap(store, hroot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txs := make(map[int64]*samsig.Transaction)
|
||||
var tx samsig.Transaction
|
||||
err = nd.ForEach(&tx, func(k string) error {
|
||||
txid, _ := binary.Varint([]byte(k))
|
||||
|
||||
cpy := tx // copy so we don't clobber on future iterations.
|
||||
txs[txid] = &cpy
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to iterate transactions hamt: %w", err)
|
||||
}
|
||||
|
||||
return txs, nil
|
||||
}
|
||||
|
||||
func state(tx *samsig.Transaction) string {
|
||||
/* // TODO(why): I strongly disagree with not having these... but i need to move forward
|
||||
if tx.Complete {
|
||||
return "done"
|
||||
}
|
||||
if tx.Canceled {
|
||||
return "canceled"
|
||||
}
|
||||
*/
|
||||
return "pending"
|
||||
}
|
||||
|
||||
var msigProposeCmd = &cli.Command{
|
||||
Name: "propose",
|
||||
Usage: "Propose a multisig transaction",
|
||||
@ -372,7 +355,7 @@ var msigProposeCmd = &cli.Command{
|
||||
return fmt.Errorf("failed to look up multisig %s: %w", msig, err)
|
||||
}
|
||||
|
||||
if act.Code != builtin.MultisigActorCodeID {
|
||||
if !act.IsMultisigActor() {
|
||||
return fmt.Errorf("actor %s is not a multisig actor", msig)
|
||||
}
|
||||
|
||||
@ -392,7 +375,7 @@ var msigProposeCmd = &cli.Command{
|
||||
return fmt.Errorf("proposal returned exit %d", wait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
var retval samsig.ProposeReturn
|
||||
var retval msig0.ProposeReturn
|
||||
if err := retval.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal propose return value: %w", err)
|
||||
}
|
||||
|
@ -12,38 +12,31 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
saminer "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api/test"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
builder "github.com/filecoin-project/lotus/node/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/api/test"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
builder "github.com/filecoin-project/lotus/node/test"
|
||||
)
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
}
|
||||
|
||||
// TestPaymentChannels does a basic test to exercise the payment channel CLI
|
||||
@ -88,7 +81,9 @@ func TestPaymentChannels(t *testing.T) {
|
||||
|
||||
// Wait for the chain to reach the settle height
|
||||
chState := getPaychState(ctx, t, paymentReceiver, chAddr)
|
||||
waitForHeight(ctx, t, paymentReceiver, chState.SettlingAt)
|
||||
sa, err := chState.SettlingAt()
|
||||
require.NoError(t, err)
|
||||
waitForHeight(ctx, t, paymentReceiver, sa)
|
||||
|
||||
// receiver: paych collect <channel>
|
||||
cmd = []string{chAddr.String()}
|
||||
@ -540,8 +535,7 @@ func getPaychState(ctx context.Context, t *testing.T, node test.TestNode, chAddr
|
||||
require.NoError(t, err)
|
||||
|
||||
store := cbor.NewCborStore(apibstore.NewAPIBlockstore(node))
|
||||
var chState paych.State
|
||||
err = store.Get(ctx, act.Head, &chState)
|
||||
chState, err := paych.Load(adt.WrapStore(ctx, store), act)
|
||||
require.NoError(t, err)
|
||||
|
||||
return chState
|
||||
|
@ -259,13 +259,13 @@ var stateSectorsCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
sectors, err := api.StateMinerSectors(ctx, maddr, nil, true, ts.Key())
|
||||
sectors, err := api.StateMinerSectors(ctx, maddr, nil, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range sectors {
|
||||
fmt.Printf("%d: %x\n", s.Info.SectorNumber, s.Info.SealedCID)
|
||||
fmt.Printf("%d: %x\n", s.SectorNumber, s.SealedCID)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -305,7 +305,7 @@ var stateActiveSectorsCmd = &cli.Command{
|
||||
}
|
||||
|
||||
for _, s := range sectors {
|
||||
fmt.Printf("%d: %x\n", s.Info.SectorNumber, s.Info.SealedCID)
|
||||
fmt.Printf("%d: %x\n", s.SectorNumber, s.SealedCID)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
43
cli/sync.go
43
cli/sync.go
@ -225,6 +225,16 @@ var syncCheckpointCmd = &cli.Command{
|
||||
}
|
||||
|
||||
func SyncWait(ctx context.Context, napi api.FullNode) error {
|
||||
tick := time.Second / 4
|
||||
|
||||
lastLines := 0
|
||||
ticker := time.NewTicker(tick)
|
||||
defer ticker.Stop()
|
||||
|
||||
samples := 8
|
||||
i := 0
|
||||
var app, lastApp uint64
|
||||
|
||||
for {
|
||||
state, err := napi.SyncState(ctx)
|
||||
if err != nil {
|
||||
@ -249,14 +259,41 @@ func SyncWait(ctx context.Context, napi api.FullNode) error {
|
||||
|
||||
ss := state.ActiveSyncs[working]
|
||||
|
||||
var baseHeight abi.ChainEpoch
|
||||
var target []cid.Cid
|
||||
var theight abi.ChainEpoch
|
||||
var heightDiff int64
|
||||
|
||||
if ss.Base != nil {
|
||||
baseHeight = ss.Base.Height()
|
||||
heightDiff = int64(ss.Base.Height())
|
||||
}
|
||||
if ss.Target != nil {
|
||||
target = ss.Target.Cids()
|
||||
theight = ss.Target.Height()
|
||||
heightDiff = int64(ss.Target.Height()) - heightDiff
|
||||
} else {
|
||||
heightDiff = 0
|
||||
}
|
||||
|
||||
fmt.Printf("\r\x1b[2KWorker %d: Target Height: %d\tTarget: %s\tState: %s\tHeight: %d", working, theight, target, ss.Stage, ss.Height)
|
||||
for i := 0; i < lastLines; i++ {
|
||||
fmt.Print("\r\x1b[2K\x1b[A")
|
||||
}
|
||||
|
||||
fmt.Printf("Worker: %d; Base: %d; Target: %d (diff: %d)\n", working, baseHeight, theight, heightDiff)
|
||||
fmt.Printf("State: %s; Current Epoch: %d; Todo: %d\n", ss.Stage, ss.Height, theight-ss.Height)
|
||||
lastLines = 2
|
||||
|
||||
if i%samples == 0 {
|
||||
lastApp = app
|
||||
app = state.VMApplied
|
||||
}
|
||||
if i > 0 {
|
||||
fmt.Printf("Validated %d messages (%d per second)\n", state.VMApplied, (app-lastApp)*uint64(time.Second/tick)/uint64(samples))
|
||||
lastLines++
|
||||
}
|
||||
|
||||
_ = target // todo: maybe print? (creates a bunch of line wrapping issues with most tipsets)
|
||||
|
||||
if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelaySecs) {
|
||||
fmt.Println("\nDone!")
|
||||
@ -267,7 +304,9 @@ func SyncWait(ctx context.Context, napi api.FullNode) error {
|
||||
case <-ctx.Done():
|
||||
fmt.Println("\nExit by user")
|
||||
return nil
|
||||
case <-build.Clock.After(1 * time.Second):
|
||||
case <-ticker.C:
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
@ -382,7 +382,11 @@ var walletVerify = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if api.WalletVerify(ctx, addr, msg, &sig) {
|
||||
ok, err := api.WalletVerify(ctx, addr, msg, &sig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok {
|
||||
fmt.Println("valid")
|
||||
return nil
|
||||
}
|
||||
|
@ -27,11 +27,11 @@ import (
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper/basicfs"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
)
|
||||
@ -76,7 +76,7 @@ func main() {
|
||||
|
||||
log.Info("Starting lotus-bench")
|
||||
|
||||
miner.SupportedProofTypes[abi.RegisteredSealProof_StackedDrg2KiBV1] = struct{}{}
|
||||
policy.AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
|
||||
app := &cli.App{
|
||||
Name: "lotus-bench",
|
||||
@ -387,7 +387,7 @@ var sealBenchCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
log.Error("post verification failed")
|
||||
log.Error("window post verification failed")
|
||||
}
|
||||
|
||||
verifyWindowpost1 := time.Now()
|
||||
@ -403,7 +403,7 @@ var sealBenchCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
log.Error("post verification failed")
|
||||
log.Error("window post verification failed")
|
||||
}
|
||||
|
||||
verifyWindowpost2 := time.Now()
|
||||
|
@ -1,7 +1,6 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
@ -9,14 +8,13 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
_init "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/events/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
cw_util "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/util"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
_init "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
func (p *Processor) setupCommonActors() error {
|
||||
@ -150,32 +148,17 @@ func (p Processor) storeActorAddresses(ctx context.Context, actors map[cid.Cid]A
|
||||
return err
|
||||
}
|
||||
|
||||
initActorRaw, err := p.node.ChainReadObj(ctx, initActor.Head)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var initActorState _init.State
|
||||
if err := initActorState.UnmarshalCBOR(bytes.NewReader(initActorRaw)); err != nil {
|
||||
return err
|
||||
}
|
||||
ctxStore := cw_util.NewAPIIpldStore(ctx, p.node)
|
||||
addrMap, err := adt.AsMap(ctxStore, initActorState.AddressMap)
|
||||
initActorState, err := _init.Load(cw_util.NewAPIIpldStore(ctx, p.node), initActor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// gross..
|
||||
var actorID typegen.CborInt
|
||||
if err := addrMap.ForEach(&actorID, func(key string) error {
|
||||
longAddr, err := address.NewFromBytes([]byte(key))
|
||||
if err := initActorState.ForEachActor(func(id abi.ActorID, addr address.Address) error {
|
||||
idAddr, err := address.NewIDAddress(uint64(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
shortAddr, err := address.NewIDAddress(uint64(actorID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addressToID[longAddr] = shortAddr
|
||||
addressToID[addr] = idAddr
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/events/state"
|
||||
)
|
||||
|
||||
@ -293,7 +294,7 @@ func (p *Processor) updateMarketActorDealProposals(ctx context.Context, marketTi
|
||||
if !changed {
|
||||
continue
|
||||
}
|
||||
changes, ok := val.(*state.MarketDealStateChanges)
|
||||
changes, ok := val.(*market.DealStateChanges)
|
||||
if !ok {
|
||||
return xerrors.Errorf("Unknown type returned by Deal State AMT predicate: %T", val)
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user