Merge pull request #5418 from filecoin-project/next
v3 actors staging branch
This commit is contained in:
commit
77fa3d6ca7
@ -201,6 +201,8 @@ jobs:
|
|||||||
<<: *test
|
<<: *test
|
||||||
test-window-post:
|
test-window-post:
|
||||||
<<: *test
|
<<: *test
|
||||||
|
test-window-post-dispute:
|
||||||
|
<<: *test
|
||||||
test-terminate:
|
test-terminate:
|
||||||
<<: *test
|
<<: *test
|
||||||
test-conformance:
|
test-conformance:
|
||||||
@ -265,6 +267,16 @@ jobs:
|
|||||||
path: /tmp/test-reports
|
path: /tmp/test-reports
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: /tmp/test-artifacts/conformance-coverage.html
|
path: /tmp/test-artifacts/conformance-coverage.html
|
||||||
|
build-ntwk-calibration:
|
||||||
|
description: |
|
||||||
|
Compile lotus binaries for the calibration network
|
||||||
|
parameters:
|
||||||
|
<<: *test-params
|
||||||
|
executor: << parameters.executor >>
|
||||||
|
steps:
|
||||||
|
- install-deps
|
||||||
|
- prepare
|
||||||
|
- run: make calibnet
|
||||||
build-lotus-soup:
|
build-lotus-soup:
|
||||||
description: |
|
description: |
|
||||||
Compile `lotus-soup` Testground test plan
|
Compile `lotus-soup` Testground test plan
|
||||||
@ -591,6 +603,11 @@ workflows:
|
|||||||
go-test-flags: "-run=TestWindowedPost"
|
go-test-flags: "-run=TestWindowedPost"
|
||||||
winpost-test: "1"
|
winpost-test: "1"
|
||||||
test-suite-name: window-post
|
test-suite-name: window-post
|
||||||
|
- test-window-post-dispute:
|
||||||
|
codecov-upload: true
|
||||||
|
go-test-flags: "-run=TestWindowPostDispute"
|
||||||
|
winpost-test: "1"
|
||||||
|
test-suite-name: window-post-dispute
|
||||||
- test-terminate:
|
- test-terminate:
|
||||||
codecov-upload: true
|
codecov-upload: true
|
||||||
go-test-flags: "-run=TestTerminate"
|
go-test-flags: "-run=TestTerminate"
|
||||||
@ -611,6 +628,7 @@ workflows:
|
|||||||
test-suite-name: conformance-bleeding-edge
|
test-suite-name: conformance-bleeding-edge
|
||||||
packages: "./conformance"
|
packages: "./conformance"
|
||||||
vectors-branch: master
|
vectors-branch: master
|
||||||
|
- build-ntwk-calibration
|
||||||
- build-lotus-soup
|
- build-lotus-soup
|
||||||
- trigger-testplans:
|
- trigger-testplans:
|
||||||
filters:
|
filters:
|
||||||
|
@ -949,7 +949,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Deadline struct {
|
type Deadline struct {
|
||||||
PostSubmissions bitfield.BitField
|
PostSubmissions bitfield.BitField
|
||||||
|
DisputableProofCount uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type Partition struct {
|
type Partition struct {
|
||||||
|
@ -17,9 +17,9 @@ import (
|
|||||||
|
|
||||||
func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
for _, height := range []abi.ChainEpoch{
|
for _, height := range []abi.ChainEpoch{
|
||||||
1, // before
|
2, // before
|
||||||
162, // while sealing
|
162, // while sealing
|
||||||
520, // after upgrade deal
|
530, // after upgrade deal
|
||||||
5000, // after
|
5000, // after
|
||||||
} {
|
} {
|
||||||
height := height // make linters happy by copying
|
height := height // make linters happy by copying
|
||||||
@ -31,7 +31,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
|
|
||||||
func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) {
|
func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(upgradeHeight)}, OneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ type TestStorageNode struct {
|
|||||||
ListenAddr multiaddr.Multiaddr
|
ListenAddr multiaddr.Multiaddr
|
||||||
|
|
||||||
MineOne func(context.Context, miner.MineReq) error
|
MineOne func(context.Context, miner.MineReq) error
|
||||||
|
Stop func(context.Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var PresealGenesis = -1
|
var PresealGenesis = -1
|
||||||
@ -110,14 +111,19 @@ var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
|||||||
var OneFull = DefaultFullOpts(1)
|
var OneFull = DefaultFullOpts(1)
|
||||||
var TwoFull = DefaultFullOpts(2)
|
var TwoFull = DefaultFullOpts(2)
|
||||||
|
|
||||||
var FullNodeWithActorsV2At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
var FullNodeWithActorsV3At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||||
return FullNodeOpts{
|
return FullNodeOpts{
|
||||||
Opts: func(nodes []TestNode) node.Option {
|
Opts: func(nodes []TestNode) node.Option {
|
||||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||||
// Skip directly to tape height so precommits work.
|
// prepare for upgrade.
|
||||||
Network: network.Version5,
|
Network: network.Version9,
|
||||||
Height: upgradeHeight,
|
Height: 1,
|
||||||
Migration: stmgr.UpgradeActorsV2,
|
Migration: stmgr.UpgradeActorsV2,
|
||||||
|
}, {
|
||||||
|
// Skip directly to tape height so precommits work.
|
||||||
|
Network: network.Version10,
|
||||||
|
Height: upgradeHeight,
|
||||||
|
Migration: stmgr.UpgradeActorsV3,
|
||||||
}})
|
}})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,18 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
|
"github.com/filecoin-project/go-state-types/dline"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||||
|
proof3 "github.com/filecoin-project/specs-actors/v3/actors/runtime/proof"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
minerActor "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
bminer "github.com/filecoin-project/lotus/miner"
|
bminer "github.com/filecoin-project/lotus/miner"
|
||||||
"github.com/filecoin-project/lotus/node/impl"
|
"github.com/filecoin-project/lotus/node/impl"
|
||||||
@ -201,7 +206,7 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n,
|
|||||||
|
|
||||||
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||||
for _, height := range []abi.ChainEpoch{
|
for _, height := range []abi.ChainEpoch{
|
||||||
1, // before
|
2, // before
|
||||||
162, // while sealing
|
162, // while sealing
|
||||||
5000, // while proving
|
5000, // while proving
|
||||||
} {
|
} {
|
||||||
@ -218,7 +223,7 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(upgradeHeight)}, OneMiner)
|
||||||
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
@ -437,7 +442,7 @@ func TestTerminate(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
|
|
||||||
nSectors := uint64(2)
|
nSectors := uint64(2)
|
||||||
|
|
||||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}})
|
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(2)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}})
|
||||||
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
@ -602,3 +607,420 @@ loop:
|
|||||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1)))
|
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// First, we configure two miners. After sealing, we're going to turn off the first miner so
|
||||||
|
// it doesn't submit proofs.
|
||||||
|
///
|
||||||
|
// Then we're going to manually submit bad proofs.
|
||||||
|
n, sn := b(t, []FullNodeOpts{
|
||||||
|
FullNodeWithActorsV3At(2),
|
||||||
|
}, []StorageMiner{
|
||||||
|
{Full: 0, Preseal: PresealGenesis},
|
||||||
|
{Full: 0},
|
||||||
|
})
|
||||||
|
|
||||||
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
|
chainMiner := sn[0]
|
||||||
|
evilMiner := sn[1]
|
||||||
|
|
||||||
|
{
|
||||||
|
addrinfo, err := client.NetAddrsListen(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := chainMiner.NetConnect(ctx, addrinfo); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := evilMiner.NetConnect(ctx, addrinfo); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultFrom, err := client.WalletDefaultAddress(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
build.Clock.Sleep(time.Second)
|
||||||
|
|
||||||
|
// Mine with the _second_ node (the good one).
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(done)
|
||||||
|
for ctx.Err() == nil {
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
if err := chainMiner.MineOne(ctx, MineNext); err != nil {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
// context was canceled, ignore the error.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
defer func() {
|
||||||
|
cancel()
|
||||||
|
<-done
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Give the chain miner enough sectors to win every block.
|
||||||
|
pledgeSectors(t, ctx, chainMiner, 10, 0, nil)
|
||||||
|
// And the evil one 1 sector. No cookie for you.
|
||||||
|
pledgeSectors(t, ctx, evilMiner, 1, 0, nil)
|
||||||
|
|
||||||
|
// Let the evil miner's sectors gain power.
|
||||||
|
evilMinerAddr, err := evilMiner.ActorAddress(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
di, err := client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
fmt.Printf("Running one proving period\n")
|
||||||
|
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod*2)
|
||||||
|
|
||||||
|
for {
|
||||||
|
head, err := client.ChainHead(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod*2 {
|
||||||
|
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ssz, err := evilMiner.ActorSectorSize(ctx, evilMinerAddr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// make sure it has gained power.
|
||||||
|
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)))
|
||||||
|
|
||||||
|
evilSectors, err := evilMiner.SectorsList(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
evilSectorNo := evilSectors[0] // only one.
|
||||||
|
evilSectorLoc, err := client.StateSectorPartition(ctx, evilMinerAddr, evilSectorNo, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
fmt.Println("evil miner stopping")
|
||||||
|
|
||||||
|
// Now stop the evil miner, and start manually submitting bad proofs.
|
||||||
|
require.NoError(t, evilMiner.Stop(ctx))
|
||||||
|
|
||||||
|
fmt.Println("evil miner stopped")
|
||||||
|
|
||||||
|
// Wait until we need to prove our sector.
|
||||||
|
for {
|
||||||
|
di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if di.Index == evilSectorLoc.Deadline {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition)
|
||||||
|
require.NoError(t, err, "evil proof not accepted")
|
||||||
|
|
||||||
|
// Wait until after the proving period.
|
||||||
|
for {
|
||||||
|
di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if di.Index != evilSectorLoc.Deadline {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("accepted evil proof")
|
||||||
|
|
||||||
|
// Make sure the evil node didn't lose any power.
|
||||||
|
p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)))
|
||||||
|
|
||||||
|
// OBJECTION! The good miner files a DISPUTE!!!!
|
||||||
|
{
|
||||||
|
params := &minerActor.DisputeWindowedPoStParams{
|
||||||
|
Deadline: evilSectorLoc.Deadline,
|
||||||
|
PoStIndex: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, aerr := actors.SerializeParams(params)
|
||||||
|
require.NoError(t, aerr)
|
||||||
|
|
||||||
|
msg := &types.Message{
|
||||||
|
To: evilMinerAddr,
|
||||||
|
Method: minerActor.Methods.DisputeWindowedPoSt,
|
||||||
|
Params: enc,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
From: defaultFrom,
|
||||||
|
}
|
||||||
|
sm, err := client.MpoolPushMessage(ctx, msg, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
fmt.Println("waiting dispute")
|
||||||
|
rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Zero(t, rec.Receipt.ExitCode, "dispute not accepted: %s", rec.Receipt.ExitCode.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Objection SUSTAINED!
|
||||||
|
// Make sure the evil node lost power.
|
||||||
|
p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, p.MinerPower.RawBytePower.IsZero())
|
||||||
|
|
||||||
|
// Now we begin the redemption arc.
|
||||||
|
require.True(t, p.MinerPower.RawBytePower.IsZero())
|
||||||
|
|
||||||
|
// First, recover the sector.
|
||||||
|
|
||||||
|
{
|
||||||
|
minerInfo, err := client.StateMinerInfo(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
params := &minerActor.DeclareFaultsRecoveredParams{
|
||||||
|
Recoveries: []minerActor.RecoveryDeclaration{{
|
||||||
|
Deadline: evilSectorLoc.Deadline,
|
||||||
|
Partition: evilSectorLoc.Partition,
|
||||||
|
Sectors: bitfield.NewFromSet([]uint64{uint64(evilSectorNo)}),
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, aerr := actors.SerializeParams(params)
|
||||||
|
require.NoError(t, aerr)
|
||||||
|
|
||||||
|
msg := &types.Message{
|
||||||
|
To: evilMinerAddr,
|
||||||
|
Method: minerActor.Methods.DeclareFaultsRecovered,
|
||||||
|
Params: enc,
|
||||||
|
Value: types.FromFil(30), // repay debt.
|
||||||
|
From: minerInfo.Owner,
|
||||||
|
}
|
||||||
|
sm, err := client.MpoolPushMessage(ctx, msg, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Zero(t, rec.Receipt.ExitCode, "recovery not accepted: %s", rec.Receipt.ExitCode.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then wait for the deadline.
|
||||||
|
for {
|
||||||
|
di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if di.Index == evilSectorLoc.Deadline {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now try to be evil again
|
||||||
|
err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "message execution failed: exit 16, reason: window post failed: invalid PoSt")
|
||||||
|
|
||||||
|
// It didn't work because we're recovering.
|
||||||
|
}
|
||||||
|
|
||||||
|
func submitBadProof(
|
||||||
|
ctx context.Context,
|
||||||
|
client api.FullNode, maddr address.Address,
|
||||||
|
di *dline.Info, dlIdx, partIdx uint64,
|
||||||
|
) error {
|
||||||
|
head, err := client.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
from, err := client.WalletDefaultAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
minerInfo, err := client.StateMinerInfo(ctx, maddr, head.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
commEpoch := di.Open
|
||||||
|
commRand, err := client.ChainGetRandomnessFromTickets(
|
||||||
|
ctx, head.Key(), crypto.DomainSeparationTag_PoStChainCommit,
|
||||||
|
commEpoch, nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params := &minerActor.SubmitWindowedPoStParams{
|
||||||
|
ChainCommitEpoch: commEpoch,
|
||||||
|
ChainCommitRand: commRand,
|
||||||
|
Deadline: dlIdx,
|
||||||
|
Partitions: []minerActor.PoStPartition{{Index: partIdx}},
|
||||||
|
Proofs: []proof3.PoStProof{{
|
||||||
|
PoStProof: minerInfo.WindowPoStProofType,
|
||||||
|
ProofBytes: []byte("I'm soooo very evil."),
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, aerr := actors.SerializeParams(params)
|
||||||
|
if aerr != nil {
|
||||||
|
return aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := &types.Message{
|
||||||
|
To: maddr,
|
||||||
|
Method: minerActor.Methods.SubmitWindowedPoSt,
|
||||||
|
Params: enc,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
From: from,
|
||||||
|
}
|
||||||
|
sm, err := client.MpoolPushMessage(ctx, msg, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rec.Receipt.ExitCode.IsError() {
|
||||||
|
return rec.Receipt.ExitCode
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWindowPostDisputeFails(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(2)}, OneMiner)
|
||||||
|
|
||||||
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
|
miner := sn[0]
|
||||||
|
|
||||||
|
{
|
||||||
|
addrinfo, err := client.NetAddrsListen(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultFrom, err := client.WalletDefaultAddress(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
maddr, err := miner.ActorAddress(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
build.Clock.Sleep(time.Second)
|
||||||
|
|
||||||
|
// Mine with the _second_ node (the good one).
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(done)
|
||||||
|
for ctx.Err() == nil {
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
if err := miner.MineOne(ctx, MineNext); err != nil {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
// context was canceled, ignore the error.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
defer func() {
|
||||||
|
cancel()
|
||||||
|
<-done
|
||||||
|
}()
|
||||||
|
|
||||||
|
pledgeSectors(t, ctx, miner, 10, 0, nil)
|
||||||
|
|
||||||
|
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
fmt.Printf("Running one proving period\n")
|
||||||
|
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod*2)
|
||||||
|
|
||||||
|
for {
|
||||||
|
head, err := client.ChainHead(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod*2 {
|
||||||
|
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
ssz, err := miner.ActorSectorSize(ctx, maddr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expectedPower := types.NewInt(uint64(ssz) * (GenesisPreseals + 10))
|
||||||
|
|
||||||
|
p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// make sure it has gained power.
|
||||||
|
require.Equal(t, p.MinerPower.RawBytePower, expectedPower)
|
||||||
|
|
||||||
|
// Wait until a proof has been submitted.
|
||||||
|
var targetDeadline uint64
|
||||||
|
waitForProof:
|
||||||
|
for {
|
||||||
|
deadlines, err := client.StateMinerDeadlines(ctx, maddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
for dlIdx, dl := range deadlines {
|
||||||
|
nonEmpty, err := dl.PostSubmissions.IsEmpty()
|
||||||
|
require.NoError(t, err)
|
||||||
|
if nonEmpty {
|
||||||
|
targetDeadline = uint64(dlIdx)
|
||||||
|
break waitForProof
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
// wait until the deadline finishes.
|
||||||
|
if di.Index == ((targetDeadline + 1) % di.WPoStPeriodDeadlines) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to object to the proof. This should fail.
|
||||||
|
{
|
||||||
|
params := &minerActor.DisputeWindowedPoStParams{
|
||||||
|
Deadline: targetDeadline,
|
||||||
|
PoStIndex: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, aerr := actors.SerializeParams(params)
|
||||||
|
require.NoError(t, aerr)
|
||||||
|
|
||||||
|
msg := &types.Message{
|
||||||
|
To: maddr,
|
||||||
|
Method: minerActor.Methods.DisputeWindowedPoSt,
|
||||||
|
Params: enc,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
From: defaultFrom,
|
||||||
|
}
|
||||||
|
_, err := client.MpoolPushMessage(ctx, msg, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "failed to dispute valid post (RetCode=16)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,6 +27,8 @@ const UpgradePersianHeight = 25
|
|||||||
const UpgradeOrangeHeight = 27
|
const UpgradeOrangeHeight = 27
|
||||||
const UpgradeClausHeight = 30
|
const UpgradeClausHeight = 30
|
||||||
|
|
||||||
|
const UpgradeActorsV3Height = 35
|
||||||
|
|
||||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||||
0: DrandMainnet,
|
0: DrandMainnet,
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,9 @@ const UpgradeClausHeight = 161386
|
|||||||
// 2021-01-17T19:00:00Z
|
// 2021-01-17T19:00:00Z
|
||||||
const UpgradeOrangeHeight = 250666
|
const UpgradeOrangeHeight = 250666
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
const UpgradeActorsV3Height = 99999999
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 30))
|
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 30))
|
||||||
policy.SetSupportedProofTypes(
|
policy.SetSupportedProofTypes(
|
||||||
|
@ -50,6 +50,9 @@ const UpgradeOrangeHeight = 336458
|
|||||||
// 2020-12-22T02:00:00Z
|
// 2020-12-22T02:00:00Z
|
||||||
const UpgradeClausHeight = 343200
|
const UpgradeClausHeight = 343200
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
const UpgradeActorsV3Height = 999999999
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
||||||
|
|
||||||
|
@ -90,8 +90,9 @@ var (
|
|||||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||||
UpgradeCalicoHeight abi.ChainEpoch = -7
|
UpgradeCalicoHeight abi.ChainEpoch = -7
|
||||||
UpgradePersianHeight abi.ChainEpoch = -8
|
UpgradePersianHeight abi.ChainEpoch = -8
|
||||||
UpgradeClausHeight abi.ChainEpoch = -9
|
UpgradeOrangeHeight abi.ChainEpoch = -9
|
||||||
UpgradeOrangeHeight abi.ChainEpoch = -10
|
UpgradeClausHeight abi.ChainEpoch = -10
|
||||||
|
UpgradeActorsV3Height abi.ChainEpoch = -11
|
||||||
|
|
||||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||||
0: DrandMainnet,
|
0: DrandMainnet,
|
||||||
|
@ -2,16 +2,9 @@ package adt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Map interface {
|
type Map interface {
|
||||||
@ -24,26 +17,6 @@ type Map interface {
|
|||||||
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func AsMap(store Store, root cid.Cid, version actors.Version) (Map, error) {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.AsMap(store, root)
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.AsMap(store, root)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMap(store Store, version actors.Version) (Map, error) {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.MakeEmptyMap(store), nil
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.MakeEmptyMap(store), nil
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Array interface {
|
type Array interface {
|
||||||
Root() (cid.Cid, error)
|
Root() (cid.Cid, error)
|
||||||
|
|
||||||
@ -54,23 +27,3 @@ type Array interface {
|
|||||||
|
|
||||||
ForEach(v cbor.Unmarshaler, fn func(idx int64) error) error
|
ForEach(v cbor.Unmarshaler, fn func(idx int64) error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) {
|
|
||||||
switch actors.VersionForNetwork(version) {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.AsArray(store, root)
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.AsArray(store, root)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewArray(store Store, version actors.Version) (Array, error) {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.MakeEmptyArray(store), nil
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.MakeEmptyArray(store), nil
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -22,9 +23,12 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var Methods = builtin2.MethodsAccount
|
var Methods = builtin3.MethodsAccount
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
@ -32,6 +36,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.AccountActorCodeID:
|
case builtin2.AccountActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.AccountActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
30
chain/actors/builtin/account/v3.go
Normal file
30
chain/actors/builtin/account/v3.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
account3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/account"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
account3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) PubkeyAddress() (address.Address, error) {
|
||||||
|
return s.Address, nil
|
||||||
|
}
|
@ -2,12 +2,12 @@ package builtin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
@ -15,9 +15,12 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
|
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||||
|
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||||
|
smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing"
|
||||||
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var SystemActorAddr = builtin0.SystemActorAddr
|
var SystemActorAddr = builtin0.SystemActorAddr
|
||||||
@ -38,11 +41,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MethodSend = builtin2.MethodSend
|
MethodSend = builtin3.MethodSend
|
||||||
MethodConstructor = builtin2.MethodConstructor
|
MethodConstructor = builtin3.MethodConstructor
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Why does actors have 2 different versions of this?
|
// These are all just type aliases across actor versions 0, 2, & 3. In the future, that might change
|
||||||
|
// and we might need to do something fancier.
|
||||||
type SectorInfo = proof0.SectorInfo
|
type SectorInfo = proof0.SectorInfo
|
||||||
type PoStProof = proof0.PoStProof
|
type PoStProof = proof0.PoStProof
|
||||||
type FilterEstimate = smoothing0.FilterEstimate
|
type FilterEstimate = smoothing0.FilterEstimate
|
||||||
@ -51,13 +55,17 @@ func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
|||||||
return (FilterEstimate)(v0)
|
return (FilterEstimate)(v0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doesn't change between actors v0 and v1
|
// Doesn't change between actors v0, v2, and v3.
|
||||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||||
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromV2FilterEstimate(v1 smoothing2.FilterEstimate) FilterEstimate {
|
func FromV2FilterEstimate(v2 smoothing2.FilterEstimate) FilterEstimate {
|
||||||
return (FilterEstimate)(v1)
|
return (FilterEstimate)(v2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromV3FilterEstimate(v3 smoothing3.FilterEstimate) FilterEstimate {
|
||||||
|
return (FilterEstimate)(v3)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
|
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
|
||||||
@ -82,30 +90,42 @@ func ActorNameByCode(c cid.Cid) string {
|
|||||||
return builtin0.ActorNameByCode(c)
|
return builtin0.ActorNameByCode(c)
|
||||||
case builtin2.IsBuiltinActor(c):
|
case builtin2.IsBuiltinActor(c):
|
||||||
return builtin2.ActorNameByCode(c)
|
return builtin2.ActorNameByCode(c)
|
||||||
|
case builtin3.IsBuiltinActor(c):
|
||||||
|
return builtin3.ActorNameByCode(c)
|
||||||
default:
|
default:
|
||||||
return "<unknown>"
|
return "<unknown>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsBuiltinActor(c cid.Cid) bool {
|
func IsBuiltinActor(c cid.Cid) bool {
|
||||||
return builtin0.IsBuiltinActor(c) || builtin2.IsBuiltinActor(c)
|
return builtin0.IsBuiltinActor(c) ||
|
||||||
|
builtin2.IsBuiltinActor(c) ||
|
||||||
|
builtin3.IsBuiltinActor(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsAccountActor(c cid.Cid) bool {
|
func IsAccountActor(c cid.Cid) bool {
|
||||||
return c == builtin0.AccountActorCodeID || c == builtin2.AccountActorCodeID
|
return c == builtin0.AccountActorCodeID ||
|
||||||
|
c == builtin2.AccountActorCodeID ||
|
||||||
|
c == builtin3.AccountActorCodeID
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsStorageMinerActor(c cid.Cid) bool {
|
func IsStorageMinerActor(c cid.Cid) bool {
|
||||||
return c == builtin0.StorageMinerActorCodeID || c == builtin2.StorageMinerActorCodeID
|
return c == builtin0.StorageMinerActorCodeID ||
|
||||||
|
c == builtin2.StorageMinerActorCodeID ||
|
||||||
|
c == builtin3.StorageMinerActorCodeID
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsMultisigActor(c cid.Cid) bool {
|
func IsMultisigActor(c cid.Cid) bool {
|
||||||
return c == builtin0.MultisigActorCodeID || c == builtin2.MultisigActorCodeID
|
return c == builtin0.MultisigActorCodeID ||
|
||||||
|
c == builtin2.MultisigActorCodeID ||
|
||||||
|
c == builtin3.MultisigActorCodeID
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsPaymentChannelActor(c cid.Cid) bool {
|
func IsPaymentChannelActor(c cid.Cid) bool {
|
||||||
return c == builtin0.PaymentChannelActorCodeID || c == builtin2.PaymentChannelActorCodeID
|
return c == builtin0.PaymentChannelActorCodeID ||
|
||||||
|
c == builtin2.PaymentChannelActorCodeID ||
|
||||||
|
c == builtin3.PaymentChannelActorCodeID
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeAddress(addr string) address.Address {
|
func makeAddress(addr string) address.Address {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package cron
|
package cron
|
||||||
|
|
||||||
import (
|
import (
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Address = builtin2.CronActorAddr
|
Address = builtin3.CronActorAddr
|
||||||
Methods = builtin2.MethodsCron
|
Methods = builtin3.MethodsCron
|
||||||
)
|
)
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -24,11 +25,14 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Address = builtin2.InitActorAddr
|
Address = builtin3.InitActorAddr
|
||||||
Methods = builtin2.MethodsInit
|
Methods = builtin3.MethodsInit
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
@ -37,6 +41,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.InitActorCodeID:
|
case builtin2.InitActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.InitActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
86
chain/actors/builtin/init/v3.go
Normal file
86
chain/actors/builtin/init/v3.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package init
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
|
||||||
|
init3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/init"
|
||||||
|
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
init3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
||||||
|
return s.State.ResolveAddress(s.store, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) MapAddressToNewID(address address.Address) (address.Address, error) {
|
||||||
|
return s.State.MapAddressToNewID(s.store, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
|
||||||
|
addrs, err := adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth)
|
||||||
|
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 *state3) NetworkName() (dtypes.NetworkName, error) {
|
||||||
|
return dtypes.NetworkName(s.State.NetworkName), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) SetNetworkName(name string) error {
|
||||||
|
s.State.NetworkName = name
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) Remove(addrs ...address.Address) (err error) {
|
||||||
|
m, err := adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) addressMap() (adt.Map, error) {
|
||||||
|
return adt3.AsMap(s.store, s.AddressMap, builtin3.DefaultHamtBitwidth)
|
||||||
|
}
|
@ -12,6 +12,7 @@ import (
|
|||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
@ -25,11 +26,14 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Address = builtin2.StorageMarketActorAddr
|
Address = builtin3.StorageMarketActorAddr
|
||||||
Methods = builtin2.MethodsMarket
|
Methods = builtin3.MethodsMarket
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||||
@ -38,6 +42,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.StorageMarketActorCodeID:
|
case builtin2.StorageMarketActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.StorageMarketActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
205
chain/actors/builtin/market/v3.go
Normal file
205
chain/actors/builtin/market/v3.go
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
package market
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"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"
|
||||||
|
|
||||||
|
market3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/market"
|
||||||
|
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
market3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) TotalLocked() (abi.TokenAmount, error) {
|
||||||
|
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
||||||
|
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
||||||
|
return fml, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) BalancesChanged(otherState State) (bool, error) {
|
||||||
|
otherState2, ok := otherState.(*state3)
|
||||||
|
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(otherState2.State.EscrowTable) || !s.State.LockedTable.Equals(otherState2.State.LockedTable), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) StatesChanged(otherState State) (bool, error) {
|
||||||
|
otherState2, ok := otherState.(*state3)
|
||||||
|
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(otherState2.State.States), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) States() (DealStates, error) {
|
||||||
|
stateArray, err := adt3.AsArray(s.store, s.State.States, market3.StatesAmtBitwidth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &dealStates3{stateArray}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ProposalsChanged(otherState State) (bool, error) {
|
||||||
|
otherState2, ok := otherState.(*state3)
|
||||||
|
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(otherState2.State.Proposals), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) Proposals() (DealProposals, error) {
|
||||||
|
proposalArray, err := adt3.AsArray(s.store, s.State.Proposals, market3.ProposalsAmtBitwidth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &dealProposals3{proposalArray}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) EscrowTable() (BalanceTable, error) {
|
||||||
|
bt, err := adt3.AsBalanceTable(s.store, s.State.EscrowTable)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &balanceTable3{bt}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) LockedTable() (BalanceTable, error) {
|
||||||
|
bt, err := adt3.AsBalanceTable(s.store, s.State.LockedTable)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &balanceTable3{bt}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) VerifyDealsForActivation(
|
||||||
|
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||||
|
) (weight, verifiedWeight abi.DealWeight, err error) {
|
||||||
|
w, vw, _, err := market3.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||||
|
return w, vw, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceTable3 struct {
|
||||||
|
*adt3.BalanceTable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bt *balanceTable3) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
|
||||||
|
asMap := (*adt3.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 dealStates3 struct {
|
||||||
|
adt.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates3) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||||
|
var deal2 market3.DealState
|
||||||
|
found, err := s.Array.Get(uint64(dealID), &deal2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
deal := fromV3DealState(deal2)
|
||||||
|
return &deal, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates3) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||||
|
var ds1 market3.DealState
|
||||||
|
return s.Array.ForEach(&ds1, func(idx int64) error {
|
||||||
|
return cb(abi.DealID(idx), fromV3DealState(ds1))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates3) decode(val *cbg.Deferred) (*DealState, error) {
|
||||||
|
var ds1 market3.DealState
|
||||||
|
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ds := fromV3DealState(ds1)
|
||||||
|
return &ds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates3) array() adt.Array {
|
||||||
|
return s.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV3DealState(v1 market3.DealState) DealState {
|
||||||
|
return (DealState)(v1)
|
||||||
|
}
|
||||||
|
|
||||||
|
type dealProposals3 struct {
|
||||||
|
adt.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals3) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||||
|
var proposal2 market3.DealProposal
|
||||||
|
found, err := s.Array.Get(uint64(dealID), &proposal2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
proposal := fromV3DealProposal(proposal2)
|
||||||
|
return &proposal, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals3) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||||
|
var dp1 market3.DealProposal
|
||||||
|
return s.Array.ForEach(&dp1, func(idx int64) error {
|
||||||
|
return cb(abi.DealID(idx), fromV3DealProposal(dp1))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals3) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||||
|
var dp1 market3.DealProposal
|
||||||
|
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dp := fromV3DealProposal(dp1)
|
||||||
|
return &dp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals3) array() adt.Array {
|
||||||
|
return s.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV3DealProposal(v1 market3.DealProposal) DealProposal {
|
||||||
|
return (DealProposal)(v1)
|
||||||
|
}
|
@ -2,6 +2,7 @@ package miner
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@ -21,6 +22,8 @@ import (
|
|||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -30,11 +33,14 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var Methods = builtin2.MethodsMiner
|
var Methods = builtin3.MethodsMiner
|
||||||
|
|
||||||
// Unchanged between v0 and v2 actors
|
// Unchanged between v0, v2, and v3 actors
|
||||||
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
||||||
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
|
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
|
||||||
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
|
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
|
||||||
@ -53,6 +59,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.StorageMinerActorCodeID:
|
case builtin2.StorageMinerActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.StorageMinerActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@ -96,9 +104,10 @@ type State interface {
|
|||||||
type Deadline interface {
|
type Deadline interface {
|
||||||
LoadPartition(idx uint64) (Partition, error)
|
LoadPartition(idx uint64) (Partition, error)
|
||||||
ForEachPartition(cb func(idx uint64, part Partition) error) error
|
ForEachPartition(cb func(idx uint64, part Partition) error) error
|
||||||
PostSubmissions() (bitfield.BitField, error)
|
PartitionsPoSted() (bitfield.BitField, error)
|
||||||
|
|
||||||
PartitionsChanged(Deadline) (bool, error)
|
PartitionsChanged(Deadline) (bool, error)
|
||||||
|
DisputableProofCount() (uint64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Partition interface {
|
type Partition interface {
|
||||||
@ -142,6 +151,60 @@ type DeclareFaultsParams = miner0.DeclareFaultsParams
|
|||||||
type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams
|
type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams
|
||||||
type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams
|
type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams
|
||||||
type ProveCommitSectorParams = miner0.ProveCommitSectorParams
|
type ProveCommitSectorParams = miner0.ProveCommitSectorParams
|
||||||
|
type DisputeWindowedPoStParams = miner3.DisputeWindowedPoStParams
|
||||||
|
|
||||||
|
func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredSealProof, error) {
|
||||||
|
// We added support for the new proofs in network version 7, and removed support for the old
|
||||||
|
// ones in network version 8.
|
||||||
|
if nver < network.Version7 {
|
||||||
|
switch proof {
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg2KiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg8MiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg512MiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg32GiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg64GiBV1, nil
|
||||||
|
default:
|
||||||
|
return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch proof {
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
|
||||||
|
return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
|
||||||
|
default:
|
||||||
|
return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WinningPoStProofTypeFromWindowPoStProofType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredPoStProof, error) {
|
||||||
|
switch proof {
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWinning8MiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWinning512MiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWinning32GiBV1, nil
|
||||||
|
case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
|
||||||
|
return abi.RegisteredPoStProof_StackedDrgWinning64GiBV1, nil
|
||||||
|
default:
|
||||||
|
return -1, xerrors.Errorf("unknown proof type %d", proof)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type MinerInfo struct {
|
type MinerInfo struct {
|
||||||
Owner address.Address // Must be an ID-address.
|
Owner address.Address // Must be an ID-address.
|
||||||
@ -151,7 +214,7 @@ type MinerInfo struct {
|
|||||||
WorkerChangeEpoch abi.ChainEpoch
|
WorkerChangeEpoch abi.ChainEpoch
|
||||||
PeerId *peer.ID
|
PeerId *peer.ID
|
||||||
Multiaddrs []abi.Multiaddrs
|
Multiaddrs []abi.Multiaddrs
|
||||||
SealProofType abi.RegisteredSealProof
|
WindowPoStProofType abi.RegisteredPoStProof
|
||||||
SectorSize abi.SectorSize
|
SectorSize abi.SectorSize
|
||||||
WindowPoStPartitionSectors uint64
|
WindowPoStPartitionSectors uint64
|
||||||
ConsensusFaultElapsed abi.ChainEpoch
|
ConsensusFaultElapsed abi.ChainEpoch
|
||||||
|
@ -297,6 +297,11 @@ func (s *state0) Info() (MinerInfo, error) {
|
|||||||
pid = &peerID
|
pid = &peerID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpp, err := info.SealProofType.RegisteredWindowPoStProof()
|
||||||
|
if err != nil {
|
||||||
|
return MinerInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
mi := MinerInfo{
|
mi := MinerInfo{
|
||||||
Owner: info.Owner,
|
Owner: info.Owner,
|
||||||
Worker: info.Worker,
|
Worker: info.Worker,
|
||||||
@ -307,7 +312,7 @@ func (s *state0) Info() (MinerInfo, error) {
|
|||||||
|
|
||||||
PeerId: pid,
|
PeerId: pid,
|
||||||
Multiaddrs: info.Multiaddrs,
|
Multiaddrs: info.Multiaddrs,
|
||||||
SealProofType: info.SealProofType,
|
WindowPoStProofType: wpp,
|
||||||
SectorSize: info.SectorSize,
|
SectorSize: info.SectorSize,
|
||||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||||
ConsensusFaultElapsed: -1,
|
ConsensusFaultElapsed: -1,
|
||||||
@ -382,10 +387,15 @@ func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
|
|||||||
return !d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
|
return !d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
|
func (d *deadline0) PartitionsPoSted() (bitfield.BitField, error) {
|
||||||
return d.Deadline.PostSubmissions, nil
|
return d.Deadline.PostSubmissions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *deadline0) DisputableProofCount() (uint64, error) {
|
||||||
|
// field doesn't exist until v3
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *partition0) AllSectors() (bitfield.BitField, error) {
|
func (p *partition0) AllSectors() (bitfield.BitField, error) {
|
||||||
return p.Partition.Sectors, nil
|
return p.Partition.Sectors, nil
|
||||||
}
|
}
|
||||||
|
@ -296,6 +296,11 @@ func (s *state2) Info() (MinerInfo, error) {
|
|||||||
pid = &peerID
|
pid = &peerID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpp, err := info.SealProofType.RegisteredWindowPoStProof()
|
||||||
|
if err != nil {
|
||||||
|
return MinerInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
mi := MinerInfo{
|
mi := MinerInfo{
|
||||||
Owner: info.Owner,
|
Owner: info.Owner,
|
||||||
Worker: info.Worker,
|
Worker: info.Worker,
|
||||||
@ -306,7 +311,7 @@ func (s *state2) Info() (MinerInfo, error) {
|
|||||||
|
|
||||||
PeerId: pid,
|
PeerId: pid,
|
||||||
Multiaddrs: info.Multiaddrs,
|
Multiaddrs: info.Multiaddrs,
|
||||||
SealProofType: info.SealProofType,
|
WindowPoStProofType: wpp,
|
||||||
SectorSize: info.SectorSize,
|
SectorSize: info.SectorSize,
|
||||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||||
ConsensusFaultElapsed: info.ConsensusFaultElapsed,
|
ConsensusFaultElapsed: info.ConsensusFaultElapsed,
|
||||||
@ -381,10 +386,15 @@ func (d *deadline2) PartitionsChanged(other Deadline) (bool, error) {
|
|||||||
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deadline2) PostSubmissions() (bitfield.BitField, error) {
|
func (d *deadline2) PartitionsPoSted() (bitfield.BitField, error) {
|
||||||
return d.Deadline.PostSubmissions, nil
|
return d.Deadline.PostSubmissions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *deadline2) DisputableProofCount() (uint64, error) {
|
||||||
|
// field doesn't exist until v3
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *partition2) AllSectors() (bitfield.BitField, error) {
|
func (p *partition2) AllSectors() (bitfield.BitField, error) {
|
||||||
return p.Partition.Sectors, nil
|
return p.Partition.Sectors, nil
|
||||||
}
|
}
|
||||||
|
434
chain/actors/builtin/miner/v3.go
Normal file
434
chain/actors/builtin/miner/v3.go
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
package miner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
"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/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||||
|
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
miner3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
type deadline3 struct {
|
||||||
|
miner3.Deadline
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
type partition3 struct {
|
||||||
|
miner3.Partition
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = xerrors.Errorf("failed to get available balance: %w", r)
|
||||||
|
available = abi.NewTokenAmount(0)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||||
|
available, err = s.GetAvailableBalance(bal)
|
||||||
|
return available, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||||
|
return s.CheckVestedFunds(s.store, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) LockedFunds() (LockedFunds, error) {
|
||||||
|
return LockedFunds{
|
||||||
|
VestingFunds: s.State.LockedFunds,
|
||||||
|
InitialPledgeRequirement: s.State.InitialPledge,
|
||||||
|
PreCommitDeposits: s.State.PreCommitDeposits,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) FeeDebt() (abi.TokenAmount, error) {
|
||||||
|
return s.State.FeeDebt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) InitialPledge() (abi.TokenAmount, error) {
|
||||||
|
return s.State.InitialPledge, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) PreCommitDeposits() (abi.TokenAmount, error) {
|
||||||
|
return s.State.PreCommitDeposits, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
|
||||||
|
info, ok, err := s.State.GetSector(s.store, num)
|
||||||
|
if !ok || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := fromV3SectorOnChainInfo(*info)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) 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 *state3) 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 *miner3.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 does not expire early, the Early expiration field is 0.
|
||||||
|
func (s *state3) 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 *miner3.Deadline) error {
|
||||||
|
partitions, err := dl.PartitionsArray(s.store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
quant := s.State.QuantSpecForDeadline(dlIdx)
|
||||||
|
var part miner3.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 := miner3.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant, miner3.PartitionExpirationAmtBitwidth)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var exp miner3.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, xerrors.Errorf("failed to find sector %d", num)
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
|
||||||
|
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
|
||||||
|
if !ok || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := fromV3SectorPreCommitOnChainInfo(*info)
|
||||||
|
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
|
||||||
|
sectors, err := miner3.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 info2 miner3.SectorOnChainInfo
|
||||||
|
if err := sectors.ForEach(&info2, func(_ int64) error {
|
||||||
|
info := fromV3SectorOnChainInfo(info2)
|
||||||
|
infos = append(infos, &info)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return infos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, load selected.
|
||||||
|
infos2, err := sectors.Load(*snos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
infos := make([]*SectorOnChainInfo, len(infos2))
|
||||||
|
for i, info2 := range infos2 {
|
||||||
|
info := fromV3SectorOnChainInfo(*info2)
|
||||||
|
infos[i] = &info
|
||||||
|
}
|
||||||
|
return infos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) 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 *state3) 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 &deadline3{*dl, s.store}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) 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 *miner3.Deadline) error {
|
||||||
|
return cb(i, &deadline3{*dl, s.store})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) NumDeadlines() (uint64, error) {
|
||||||
|
return miner3.WPoStPeriodDeadlines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) DeadlinesChanged(other State) (bool, error) {
|
||||||
|
other2, ok := other.(*state3)
|
||||||
|
if !ok {
|
||||||
|
// treat an upgrade as a change, always
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return !s.State.Deadlines.Equals(other2.Deadlines), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) MinerInfoChanged(other State) (bool, error) {
|
||||||
|
other0, ok := other.(*state3)
|
||||||
|
if !ok {
|
||||||
|
// treat an upgrade as a change, always
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return !s.State.Info.Equals(other0.State.Info), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) 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,
|
||||||
|
WindowPoStProofType: info.WindowPoStProofType,
|
||||||
|
SectorSize: info.SectorSize,
|
||||||
|
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||||
|
ConsensusFaultElapsed: info.ConsensusFaultElapsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.PendingWorkerKey != nil {
|
||||||
|
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||||
|
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||||
|
}
|
||||||
|
|
||||||
|
return mi, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
|
||||||
|
return s.State.DeadlineInfo(epoch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) sectors() (adt.Array, error) {
|
||||||
|
return adt3.AsArray(s.store, s.Sectors, miner3.SectorsAmtBitwidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
|
||||||
|
var si miner3.SectorOnChainInfo
|
||||||
|
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
|
if err != nil {
|
||||||
|
return SectorOnChainInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromV3SectorOnChainInfo(si), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) precommits() (adt.Map, error) {
|
||||||
|
return adt3.AsMap(s.store, s.PreCommittedSectors, builtin3.DefaultHamtBitwidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
|
||||||
|
var sp miner3.SectorPreCommitOnChainInfo
|
||||||
|
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
|
if err != nil {
|
||||||
|
return SectorPreCommitOnChainInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromV3SectorPreCommitOnChainInfo(sp), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline3) LoadPartition(idx uint64) (Partition, error) {
|
||||||
|
p, err := d.Deadline.LoadPartition(d.store, idx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &partition3{*p, d.store}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline3) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||||
|
ps, err := d.Deadline.PartitionsArray(d.store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var part miner3.Partition
|
||||||
|
return ps.ForEach(&part, func(i int64) error {
|
||||||
|
return cb(uint64(i), &partition3{part, d.store})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline3) PartitionsChanged(other Deadline) (bool, error) {
|
||||||
|
other2, ok := other.(*deadline3)
|
||||||
|
if !ok {
|
||||||
|
// treat an upgrade as a change, always
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline3) PartitionsPoSted() (bitfield.BitField, error) {
|
||||||
|
return d.Deadline.PartitionsPoSted, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline3) DisputableProofCount() (uint64, error) {
|
||||||
|
ops, err := d.OptimisticProofsSnapshotArray(d.store)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ops.Length(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *partition3) AllSectors() (bitfield.BitField, error) {
|
||||||
|
return p.Partition.Sectors, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *partition3) FaultySectors() (bitfield.BitField, error) {
|
||||||
|
return p.Partition.Faults, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *partition3) RecoveringSectors() (bitfield.BitField, error) {
|
||||||
|
return p.Partition.Recoveries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV3SectorOnChainInfo(v3 miner3.SectorOnChainInfo) SectorOnChainInfo {
|
||||||
|
return SectorOnChainInfo{
|
||||||
|
SectorNumber: v3.SectorNumber,
|
||||||
|
SealProof: v3.SealProof,
|
||||||
|
SealedCID: v3.SealedCID,
|
||||||
|
DealIDs: v3.DealIDs,
|
||||||
|
Activation: v3.Activation,
|
||||||
|
Expiration: v3.Expiration,
|
||||||
|
DealWeight: v3.DealWeight,
|
||||||
|
VerifiedDealWeight: v3.VerifiedDealWeight,
|
||||||
|
InitialPledge: v3.InitialPledge,
|
||||||
|
ExpectedDayReward: v3.ExpectedDayReward,
|
||||||
|
ExpectedStoragePledge: v3.ExpectedStoragePledge,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||||
|
return SectorPreCommitOnChainInfo{
|
||||||
|
Info: (SectorPreCommitInfo)(v3.Info),
|
||||||
|
PreCommitDeposit: v3.PreCommitDeposit,
|
||||||
|
PreCommitEpoch: v3.PreCommitEpoch,
|
||||||
|
DealWeight: v3.DealWeight,
|
||||||
|
VerifiedDealWeight: v3.VerifiedDealWeight,
|
||||||
|
}
|
||||||
|
}
|
@ -9,14 +9,14 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
multisig3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/multisig"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Methods = builtin2.MethodsMultisig
|
var Methods = builtin3.MethodsMultisig
|
||||||
|
|
||||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||||
switch version {
|
switch version {
|
||||||
@ -24,6 +24,8 @@ func Message(version actors.Version, from address.Address) MessageBuilder {
|
|||||||
return message0{from}
|
return message0{from}
|
||||||
case actors.Version2:
|
case actors.Version2:
|
||||||
return message2{message0{from}}
|
return message2{message0{from}}
|
||||||
|
case actors.Version3:
|
||||||
|
return message3{message0{from}}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||||
}
|
}
|
||||||
@ -47,11 +49,11 @@ type MessageBuilder interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this type is the same between v0 and v2
|
// this type is the same between v0 and v2
|
||||||
type ProposalHashData = multisig2.ProposalHashData
|
type ProposalHashData = multisig3.ProposalHashData
|
||||||
type ProposeReturn = multisig2.ProposeReturn
|
type ProposeReturn = multisig3.ProposeReturn
|
||||||
|
|
||||||
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
|
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
|
||||||
params := multisig2.TxnIDParams{ID: multisig2.TxnID(id)}
|
params := multisig3.TxnIDParams{ID: multisig3.TxnID(id)}
|
||||||
if data != nil {
|
if data != nil {
|
||||||
if data.Requester.Protocol() != address.ID {
|
if data.Requester.Protocol() != address.ID {
|
||||||
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
|
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
|
||||||
|
71
chain/actors/builtin/multisig/message3.go
Normal file
71
chain/actors/builtin/multisig/message3.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package multisig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
init3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/init"
|
||||||
|
multisig3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/multisig"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type message3 struct{ message0 }
|
||||||
|
|
||||||
|
func (m message3) Create(
|
||||||
|
signers []address.Address, threshold uint64,
|
||||||
|
unlockStart, unlockDuration abi.ChainEpoch,
|
||||||
|
initialAmount abi.TokenAmount,
|
||||||
|
) (*types.Message, error) {
|
||||||
|
|
||||||
|
lenAddrs := uint64(len(signers))
|
||||||
|
|
||||||
|
if lenAddrs < threshold {
|
||||||
|
return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
|
||||||
|
}
|
||||||
|
|
||||||
|
if threshold == 0 {
|
||||||
|
threshold = lenAddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.from == address.Undef {
|
||||||
|
return nil, xerrors.Errorf("must provide source address")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up constructor parameters for multisig
|
||||||
|
msigParams := &multisig3.ConstructorParams{
|
||||||
|
Signers: signers,
|
||||||
|
NumApprovalsThreshold: threshold,
|
||||||
|
UnlockDuration: unlockDuration,
|
||||||
|
StartEpoch: unlockStart,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, actErr := actors.SerializeParams(msigParams)
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// new actors are created by invoking 'exec' on the init actor with the constructor params
|
||||||
|
execParams := &init3.ExecParams{
|
||||||
|
CodeCID: builtin3.MultisigActorCodeID,
|
||||||
|
ConstructorParams: enc,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, actErr = actors.SerializeParams(execParams)
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: init_.Address,
|
||||||
|
From: m.from,
|
||||||
|
Method: builtin3.MethodsInit.Exec,
|
||||||
|
Params: enc,
|
||||||
|
Value: initialAmount,
|
||||||
|
}, nil
|
||||||
|
}
|
@ -12,6 +12,7 @@ import (
|
|||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
@ -25,6 +26,9 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
@ -33,6 +37,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.MultisigActorCodeID:
|
case builtin2.MultisigActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.MultisigActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
multisig0 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
95
chain/actors/builtin/multisig/state3.go
Normal file
95
chain/actors/builtin/multisig/state3.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package multisig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
msig3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/multisig"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
msig3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||||
|
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) StartEpoch() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.StartEpoch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) UnlockDuration() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.UnlockDuration, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) InitialBalance() (abi.TokenAmount, error) {
|
||||||
|
return s.State.InitialBalance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) Threshold() (uint64, error) {
|
||||||
|
return s.State.NumApprovalsThreshold, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) Signers() ([]address.Address, error) {
|
||||||
|
return s.State.Signers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
||||||
|
arr, err := adt3.AsMap(s.store, s.State.PendingTxns, builtin3.DefaultHamtBitwidth)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var out msig3.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))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) PendingTxnChanged(other State) (bool, error) {
|
||||||
|
other2, ok := other.(*state3)
|
||||||
|
if !ok {
|
||||||
|
// treat an upgrade as a change, always
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) transactions() (adt.Map, error) {
|
||||||
|
return adt3.AsMap(s.store, s.PendingTxns, builtin3.DefaultHamtBitwidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
|
||||||
|
var tx msig3.Transaction
|
||||||
|
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
|
return Transaction{}, err
|
||||||
|
}
|
||||||
|
return tx, nil
|
||||||
|
}
|
@ -8,10 +8,10 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Methods = builtin2.MethodsPaych
|
var Methods = builtin3.MethodsPaych
|
||||||
|
|
||||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||||
switch version {
|
switch version {
|
||||||
@ -19,6 +19,8 @@ func Message(version actors.Version, from address.Address) MessageBuilder {
|
|||||||
return message0{from}
|
return message0{from}
|
||||||
case actors.Version2:
|
case actors.Version2:
|
||||||
return message2{from}
|
return message2{from}
|
||||||
|
case actors.Version3:
|
||||||
|
return message3{from}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||||
}
|
}
|
||||||
|
74
chain/actors/builtin/paych/message3.go
Normal file
74
chain/actors/builtin/paych/message3.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package paych
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
init3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/init"
|
||||||
|
paych3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/paych"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type message3 struct{ from address.Address }
|
||||||
|
|
||||||
|
func (m message3) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
|
||||||
|
params, aerr := actors.SerializeParams(&paych3.ConstructorParams{From: m.from, To: to})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
enc, aerr := actors.SerializeParams(&init3.ExecParams{
|
||||||
|
CodeCID: builtin3.PaymentChannelActorCodeID,
|
||||||
|
ConstructorParams: params,
|
||||||
|
})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: init_.Address,
|
||||||
|
From: m.from,
|
||||||
|
Value: initialAmount,
|
||||||
|
Method: builtin3.MethodsInit.Exec,
|
||||||
|
Params: enc,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message3) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) {
|
||||||
|
params, aerr := actors.SerializeParams(&paych3.UpdateChannelStateParams{
|
||||||
|
Sv: *sv,
|
||||||
|
Secret: secret,
|
||||||
|
})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin3.MethodsPaych.UpdateChannelState,
|
||||||
|
Params: params,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message3) Settle(paych address.Address) (*types.Message, error) {
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin3.MethodsPaych.Settle,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message3) Collect(paych address.Address) (*types.Message, error) {
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin3.MethodsPaych.Collect,
|
||||||
|
}, nil
|
||||||
|
}
|
@ -15,6 +15,7 @@ import (
|
|||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
@ -28,6 +29,9 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
||||||
@ -37,6 +41,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.PaymentChannelActorCodeID:
|
case builtin2.PaymentChannelActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.PaymentChannelActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
104
chain/actors/builtin/paych/state3.go
Normal file
104
chain/actors/builtin/paych/state3.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package paych
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"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/adt"
|
||||||
|
|
||||||
|
paych3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/paych"
|
||||||
|
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
paych3.State
|
||||||
|
store adt.Store
|
||||||
|
lsAmt *adt3.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel owner, who has funded the actor
|
||||||
|
func (s *state3) From() (address.Address, error) {
|
||||||
|
return s.State.From, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recipient of payouts from channel
|
||||||
|
func (s *state3) To() (address.Address, error) {
|
||||||
|
return s.State.To, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Height at which the channel can be `Collected`
|
||||||
|
func (s *state3) SettlingAt() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.SettlingAt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||||
|
func (s *state3) ToSend() (abi.TokenAmount, error) {
|
||||||
|
return s.State.ToSend, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) getOrLoadLsAmt() (*adt3.Array, error) {
|
||||||
|
if s.lsAmt != nil {
|
||||||
|
return s.lsAmt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the lane state from the chain
|
||||||
|
lsamt, err := adt3.AsArray(s.store, s.State.LaneStates, paych3.LaneStatesAmtBitwidth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.lsAmt = lsamt
|
||||||
|
return lsamt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get total number of lanes
|
||||||
|
func (s *state3) LaneCount() (uint64, error) {
|
||||||
|
lsamt, err := s.getOrLoadLsAmt()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return lsamt.Length(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate lane states
|
||||||
|
func (s *state3) 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 paych3.LaneState
|
||||||
|
return lsamt.ForEach(&ls, func(i int64) error {
|
||||||
|
return cb(uint64(i), &laneState3{ls})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type laneState3 struct {
|
||||||
|
paych3.LaneState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls *laneState3) Redeemed() (big.Int, error) {
|
||||||
|
return ls.LaneState.Redeemed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls *laneState3) Nonce() (uint64, error) {
|
||||||
|
return ls.LaneState.Nonce, nil
|
||||||
|
}
|
@ -16,6 +16,7 @@ import (
|
|||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -25,11 +26,14 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Address = builtin2.StoragePowerActorAddr
|
Address = builtin3.StoragePowerActorAddr
|
||||||
Methods = builtin2.MethodsPower
|
Methods = builtin3.MethodsPower
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||||
@ -38,6 +42,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.StoragePowerActorCodeID:
|
case builtin2.StoragePowerActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.StoragePowerActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
149
chain/actors/builtin/power/v3.go
Normal file
149
chain/actors/builtin/power/v3.go
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
package power
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"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/actors/builtin"
|
||||||
|
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
power3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/power"
|
||||||
|
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
power3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) TotalLocked() (abi.TokenAmount, error) {
|
||||||
|
return s.TotalPledgeCollateral, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) 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 *state3) TotalCommitted() (Claim, error) {
|
||||||
|
return Claim{
|
||||||
|
RawBytePower: s.TotalBytesCommitted,
|
||||||
|
QualityAdjPower: s.TotalQABytesCommitted,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||||
|
claims, err := s.claims()
|
||||||
|
if err != nil {
|
||||||
|
return Claim{}, false, err
|
||||||
|
}
|
||||||
|
var claim power3.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 *state3) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
|
||||||
|
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
|
||||||
|
return builtin.FromV3FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) MinerCounts() (uint64, uint64, error) {
|
||||||
|
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ListAllMiners() ([]address.Address, error) {
|
||||||
|
claims, err := 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
||||||
|
claims, err := s.claims()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var claim power3.Claim
|
||||||
|
return claims.ForEach(&claim, func(k string) error {
|
||||||
|
a, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cb(a, Claim{
|
||||||
|
RawBytePower: claim.RawBytePower,
|
||||||
|
QualityAdjPower: claim.QualityAdjPower,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ClaimsChanged(other State) (bool, error) {
|
||||||
|
other2, ok := other.(*state3)
|
||||||
|
if !ok {
|
||||||
|
// treat an upgrade as a change, always
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return !s.State.Claims.Equals(other2.State.Claims), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) claims() (adt.Map, error) {
|
||||||
|
return adt3.AsMap(s.store, s.Claims, builtin3.DefaultHamtBitwidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) decodeClaim(val *cbg.Deferred) (Claim, error) {
|
||||||
|
var ci power3.Claim
|
||||||
|
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
|
return Claim{}, err
|
||||||
|
}
|
||||||
|
return fromV3Claim(ci), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV3Claim(v3 power3.Claim) Claim {
|
||||||
|
return Claim{
|
||||||
|
RawBytePower: v3.RawBytePower,
|
||||||
|
QualityAdjPower: v3.QualityAdjPower,
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
@ -22,11 +23,14 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Address = builtin2.RewardActorAddr
|
Address = builtin3.RewardActorAddr
|
||||||
Methods = builtin2.MethodsReward
|
Methods = builtin3.MethodsReward
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||||
@ -35,6 +39,8 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.RewardActorCodeID:
|
case builtin2.RewardActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.RewardActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
86
chain/actors/builtin/reward/v3.go
Normal file
86
chain/actors/builtin/reward/v3.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package reward
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
|
|
||||||
|
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||||
|
reward3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/reward"
|
||||||
|
smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
reward3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ThisEpochReward() (abi.TokenAmount, error) {
|
||||||
|
return s.State.ThisEpochReward, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||||
|
return builtin.FilterEstimate{
|
||||||
|
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
|
||||||
|
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||||
|
return s.State.ThisEpochBaselinePower, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) TotalStoragePowerReward() (abi.TokenAmount, error) {
|
||||||
|
return s.State.TotalStoragePowerReward, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) EffectiveBaselinePower() (abi.StoragePower, error) {
|
||||||
|
return s.State.EffectiveBaselinePower, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.EffectiveNetworkTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) CumsumBaseline() (reward3.Spacetime, error) {
|
||||||
|
return s.State.CumsumBaseline, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) CumsumRealized() (reward3.Spacetime, error) {
|
||||||
|
return s.State.CumsumRealized, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||||
|
return miner3.InitialPledgeForPower(
|
||||||
|
qaPower,
|
||||||
|
s.State.ThisEpochBaselinePower,
|
||||||
|
s.State.ThisEpochRewardSmoothed,
|
||||||
|
smoothing3.FilterEstimate{
|
||||||
|
PositionEstimate: networkQAPower.PositionEstimate,
|
||||||
|
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||||
|
},
|
||||||
|
circSupply,
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
||||||
|
return miner3.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
||||||
|
smoothing3.FilterEstimate{
|
||||||
|
PositionEstimate: networkQAPower.PositionEstimate,
|
||||||
|
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||||
|
},
|
||||||
|
sectorWeight), nil
|
||||||
|
}
|
@ -6,16 +6,21 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getDataCap(store adt.Store, ver actors.Version, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) {
|
// taking this as a function instead of asking the caller to call it helps reduce some of the error
|
||||||
|
// checking boilerplate.
|
||||||
|
//
|
||||||
|
// "go made me do it"
|
||||||
|
type rootFunc func() (adt.Map, error)
|
||||||
|
|
||||||
|
// Assumes that the bitwidth for v3 HAMTs is the DefaultHamtBitwidth
|
||||||
|
func getDataCap(store adt.Store, ver actors.Version, root rootFunc, addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
if addr.Protocol() != address.ID {
|
if addr.Protocol() != address.ID {
|
||||||
return false, big.Zero(), xerrors.Errorf("can only look up ID addresses")
|
return false, big.Zero(), xerrors.Errorf("can only look up ID addresses")
|
||||||
}
|
}
|
||||||
|
vh, err := root()
|
||||||
vh, err := adt.AsMap(store, root, ver)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err)
|
return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err)
|
||||||
}
|
}
|
||||||
@ -30,8 +35,9 @@ func getDataCap(store adt.Store, ver actors.Version, root cid.Cid, addr address.
|
|||||||
return true, dcap, nil
|
return true, dcap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func forEachCap(store adt.Store, ver actors.Version, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
// Assumes that the bitwidth for v3 HAMTs is the DefaultHamtBitwidth
|
||||||
vh, err := adt.AsMap(store, root, ver)
|
func forEachCap(store adt.Store, ver actors.Version, root rootFunc, cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
|
vh, err := root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("loading verified clients: %w", err)
|
return xerrors.Errorf("loading verified clients: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
@ -32,17 +33,25 @@ func (s *state0) RootKey() (address.Address, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
return getDataCap(s.store, actors.Version0, s.State.VerifiedClients, addr)
|
return getDataCap(s.store, actors.Version0, s.verifiedClients, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
return getDataCap(s.store, actors.Version0, s.State.Verifiers, addr)
|
return getDataCap(s.store, actors.Version0, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version0, s.State.Verifiers, cb)
|
return forEachCap(s.store, actors.Version0, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version0, s.State.VerifiedClients, cb)
|
return forEachCap(s.store, actors.Version0, s.verifiedClients, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state0) verifiedClients() (adt.Map, error) {
|
||||||
|
return adt0.AsMap(s.store, s.VerifiedClients)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state0) verifiers() (adt.Map, error) {
|
||||||
|
return adt0.AsMap(s.store, s.Verifiers)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
var _ State = (*state2)(nil)
|
||||||
@ -32,17 +33,25 @@ func (s *state2) RootKey() (address.Address, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *state2) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
func (s *state2) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
return getDataCap(s.store, actors.Version2, s.State.VerifiedClients, addr)
|
return getDataCap(s.store, actors.Version2, s.verifiedClients, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state2) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
func (s *state2) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
return getDataCap(s.store, actors.Version2, s.State.Verifiers, addr)
|
return getDataCap(s.store, actors.Version2, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state2) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state2) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version2, s.State.Verifiers, cb)
|
return forEachCap(s.store, actors.Version2, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state2) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state2) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version2, s.State.VerifiedClients, cb)
|
return forEachCap(s.store, actors.Version2, s.verifiedClients, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) verifiedClients() (adt.Map, error) {
|
||||||
|
return adt2.AsMap(s.store, s.VerifiedClients)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) verifiers() (adt.Map, error) {
|
||||||
|
return adt2.AsMap(s.store, s.Verifiers)
|
||||||
}
|
}
|
||||||
|
58
chain/actors/builtin/verifreg/v3.go
Normal file
58
chain/actors/builtin/verifreg/v3.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package verifreg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
verifreg3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/verifreg"
|
||||||
|
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state3)(nil)
|
||||||
|
|
||||||
|
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state3{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state3 struct {
|
||||||
|
verifreg3.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) RootKey() (address.Address, error) {
|
||||||
|
return s.State.RootKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
|
return getDataCap(s.store, actors.Version3, s.verifiedClients, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
|
return getDataCap(s.store, actors.Version3, s.verifiers, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
|
return forEachCap(s.store, actors.Version3, s.verifiers, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
|
return forEachCap(s.store, actors.Version3, s.verifiedClients, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) verifiedClients() (adt.Map, error) {
|
||||||
|
return adt3.AsMap(s.store, s.VerifiedClients, builtin3.DefaultHamtBitwidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state3) verifiers() (adt.Map, error) {
|
||||||
|
return adt3.AsMap(s.store, s.Verifiers, builtin3.DefaultHamtBitwidth)
|
||||||
|
}
|
@ -3,6 +3,7 @@ package verifreg
|
|||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -22,11 +23,14 @@ func init() {
|
|||||||
builtin.RegisterActorState(builtin2.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
builtin.RegisterActorState(builtin2.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
return load2(store, root)
|
return load2(store, root)
|
||||||
})
|
})
|
||||||
|
builtin.RegisterActorState(builtin3.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load3(store, root)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Address = builtin2.VerifiedRegistryActorAddr
|
Address = builtin3.VerifiedRegistryActorAddr
|
||||||
Methods = builtin2.MethodsVerifiedRegistry
|
Methods = builtin3.MethodsVerifiedRegistry
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
@ -35,6 +39,8 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
|||||||
return load0(store, act.Head)
|
return load0(store, act.Head)
|
||||||
case builtin2.VerifiedRegistryActorCodeID:
|
case builtin2.VerifiedRegistryActorCodeID:
|
||||||
return load2(store, act.Head)
|
return load2(store, act.Head)
|
||||||
|
case builtin3.VerifiedRegistryActorCodeID:
|
||||||
|
return load3(store, act.Head)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
@ -6,21 +6,28 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
|
||||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||||
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
|
|
||||||
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
||||||
|
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
market3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/market"
|
||||||
|
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||||
|
paych3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/paych"
|
||||||
|
verifreg3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/verifreg"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ChainFinality = miner0.ChainFinality
|
ChainFinality = miner3.ChainFinality
|
||||||
SealRandomnessLookback = ChainFinality
|
SealRandomnessLookback = ChainFinality
|
||||||
PaychSettleDelay = paych2.SettleDelay
|
PaychSettleDelay = paych3.SettleDelay
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
||||||
@ -31,6 +38,10 @@ func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
|||||||
miner2.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
|
miner2.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
|
||||||
miner2.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
miner2.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||||
|
|
||||||
|
miner3.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||||
|
miner3.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
|
||||||
|
miner3.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||||
|
|
||||||
AddSupportedProofTypes(types...)
|
AddSupportedProofTypes(types...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +60,13 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
|||||||
miner2.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
miner2.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||||
|
|
||||||
miner2.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
miner2.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||||
|
|
||||||
|
miner3.PreCommitSealProofTypesV0[t] = struct{}{}
|
||||||
|
|
||||||
|
miner3.PreCommitSealProofTypesV7[t] = struct{}{}
|
||||||
|
miner3.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||||
|
|
||||||
|
miner3.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +76,7 @@ func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
|
|||||||
// Set for all miner versions.
|
// Set for all miner versions.
|
||||||
miner0.PreCommitChallengeDelay = delay
|
miner0.PreCommitChallengeDelay = delay
|
||||||
miner2.PreCommitChallengeDelay = delay
|
miner2.PreCommitChallengeDelay = delay
|
||||||
|
miner3.PreCommitChallengeDelay = delay
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
|
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
|
||||||
@ -73,6 +92,10 @@ func SetConsensusMinerMinPower(p abi.StoragePower) {
|
|||||||
for _, policy := range builtin2.SealProofPolicies {
|
for _, policy := range builtin2.SealProofPolicies {
|
||||||
policy.ConsensusMinerMinPower = p
|
policy.ConsensusMinerMinPower = p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, policy := range builtin3.PoStProofPolicies {
|
||||||
|
policy.ConsensusMinerMinPower = p
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
|
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
|
||||||
@ -80,6 +103,7 @@ func SetConsensusMinerMinPower(p abi.StoragePower) {
|
|||||||
func SetMinVerifiedDealSize(size abi.StoragePower) {
|
func SetMinVerifiedDealSize(size abi.StoragePower) {
|
||||||
verifreg0.MinVerifiedDealSize = size
|
verifreg0.MinVerifiedDealSize = size
|
||||||
verifreg2.MinVerifiedDealSize = size
|
verifreg2.MinVerifiedDealSize = size
|
||||||
|
verifreg3.MinVerifiedDealSize = size
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch {
|
func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch {
|
||||||
@ -88,6 +112,8 @@ func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) ab
|
|||||||
return miner0.MaxSealDuration[t]
|
return miner0.MaxSealDuration[t]
|
||||||
case actors.Version2:
|
case actors.Version2:
|
||||||
return miner2.MaxProveCommitDuration[t]
|
return miner2.MaxProveCommitDuration[t]
|
||||||
|
case actors.Version3:
|
||||||
|
return miner3.MaxProveCommitDuration[t]
|
||||||
default:
|
default:
|
||||||
panic("unsupported actors version")
|
panic("unsupported actors version")
|
||||||
}
|
}
|
||||||
@ -103,6 +129,8 @@ func DealProviderCollateralBounds(
|
|||||||
return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer)
|
return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer)
|
||||||
case actors.Version2:
|
case actors.Version2:
|
||||||
return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
||||||
|
case actors.Version3:
|
||||||
|
return market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
||||||
default:
|
default:
|
||||||
panic("unsupported network version")
|
panic("unsupported network version")
|
||||||
}
|
}
|
||||||
@ -116,6 +144,12 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) {
|
|||||||
|
|
||||||
miner2.WPoStChallengeWindow = period
|
miner2.WPoStChallengeWindow = period
|
||||||
miner2.WPoStProvingPeriod = period * abi.ChainEpoch(miner2.WPoStPeriodDeadlines)
|
miner2.WPoStProvingPeriod = period * abi.ChainEpoch(miner2.WPoStPeriodDeadlines)
|
||||||
|
|
||||||
|
miner3.WPoStChallengeWindow = period
|
||||||
|
miner3.WPoStProvingPeriod = period * abi.ChainEpoch(miner3.WPoStPeriodDeadlines)
|
||||||
|
// by default, this is 2x finality which is 30 periods.
|
||||||
|
// scale it if we're scaling the challenge period.
|
||||||
|
miner3.WPoStDisputeWindow = period * 30
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
|
func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
|
||||||
@ -132,17 +166,17 @@ func GetMaxSectorExpirationExtension() abi.ChainEpoch {
|
|||||||
|
|
||||||
// TODO: we'll probably need to abstract over this better in the future.
|
// TODO: we'll probably need to abstract over this better in the future.
|
||||||
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
|
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
|
||||||
sectorsPerPart, err := builtin2.PoStProofWindowPoStPartitionSectors(p)
|
sectorsPerPart, err := builtin3.PoStProofWindowPoStPartitionSectors(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return int(miner2.AddressedSectorsMax / sectorsPerPart), nil
|
return int(miner3.AddressedSectorsMax / sectorsPerPart), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDefaultSectorSize() abi.SectorSize {
|
func GetDefaultSectorSize() abi.SectorSize {
|
||||||
// supported sector sizes are the same across versions.
|
// supported sector sizes are the same across versions.
|
||||||
szs := make([]abi.SectorSize, 0, len(miner2.PreCommitSealProofTypesV8))
|
szs := make([]abi.SectorSize, 0, len(miner3.PreCommitSealProofTypesV8))
|
||||||
for spt := range miner2.PreCommitSealProofTypesV8 {
|
for spt := range miner3.PreCommitSealProofTypesV8 {
|
||||||
ss, err := spt.SectorSize()
|
ss, err := spt.SectorSize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -11,6 +11,7 @@ type Version int
|
|||||||
const (
|
const (
|
||||||
Version0 Version = 0
|
Version0 Version = 0
|
||||||
Version2 Version = 2
|
Version2 Version = 2
|
||||||
|
Version3 Version = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// Converts a network version into an actors adt version.
|
// Converts a network version into an actors adt version.
|
||||||
@ -20,6 +21,8 @@ func VersionForNetwork(version network.Version) Version {
|
|||||||
return Version0
|
return Version0
|
||||||
case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9:
|
case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9:
|
||||||
return Version2
|
return Version2
|
||||||
|
case network.Version10:
|
||||||
|
return Version3
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,10 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
|
states0 "github.com/filecoin-project/specs-actors/actors/states"
|
||||||
|
states2 "github.com/filecoin-project/specs-actors/v2/actors/states"
|
||||||
|
states3 "github.com/filecoin-project/specs-actors/v3/actors/states"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("statetree")
|
var log = logging.Logger("statetree")
|
||||||
@ -144,23 +148,12 @@ func VersionForNetwork(ver network.Version) types.StateTreeVersion {
|
|||||||
return types.StateTreeVersion1
|
return types.StateTreeVersion1
|
||||||
}
|
}
|
||||||
|
|
||||||
func adtForSTVersion(ver types.StateTreeVersion) actors.Version {
|
|
||||||
switch ver {
|
|
||||||
case types.StateTreeVersion0:
|
|
||||||
return actors.Version0
|
|
||||||
case types.StateTreeVersion1:
|
|
||||||
return actors.Version2
|
|
||||||
default:
|
|
||||||
panic("unhandled state tree version")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, error) {
|
func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, error) {
|
||||||
var info cid.Cid
|
var info cid.Cid
|
||||||
switch ver {
|
switch ver {
|
||||||
case types.StateTreeVersion0:
|
case types.StateTreeVersion0:
|
||||||
// info is undefined
|
// info is undefined
|
||||||
case types.StateTreeVersion1:
|
case types.StateTreeVersion1, types.StateTreeVersion2:
|
||||||
var err error
|
var err error
|
||||||
info, err = cst.Put(context.TODO(), new(types.StateInfo0))
|
info, err = cst.Put(context.TODO(), new(types.StateInfo0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -169,13 +162,34 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e
|
|||||||
default:
|
default:
|
||||||
return nil, xerrors.Errorf("unsupported state tree version: %d", ver)
|
return nil, xerrors.Errorf("unsupported state tree version: %d", ver)
|
||||||
}
|
}
|
||||||
root, err := adt.NewMap(adt.WrapStore(context.TODO(), cst), adtForSTVersion(ver))
|
|
||||||
if err != nil {
|
store := adt.WrapStore(context.TODO(), cst)
|
||||||
return nil, err
|
var hamt adt.Map
|
||||||
|
switch ver {
|
||||||
|
case types.StateTreeVersion0:
|
||||||
|
tree, err := states0.NewTree(store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to create state tree: %w", err)
|
||||||
|
}
|
||||||
|
hamt = tree.Map
|
||||||
|
case types.StateTreeVersion1:
|
||||||
|
tree, err := states2.NewTree(store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to create state tree: %w", err)
|
||||||
|
}
|
||||||
|
hamt = tree.Map
|
||||||
|
case types.StateTreeVersion2:
|
||||||
|
tree, err := states3.NewTree(store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to create state tree: %w", err)
|
||||||
|
}
|
||||||
|
hamt = tree.Map
|
||||||
|
default:
|
||||||
|
return nil, xerrors.Errorf("unsupported state tree version: %d", ver)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := &StateTree{
|
s := &StateTree{
|
||||||
root: root,
|
root: hamt,
|
||||||
info: info,
|
info: info,
|
||||||
version: ver,
|
version: ver,
|
||||||
Store: cst,
|
Store: cst,
|
||||||
@ -194,30 +208,49 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
|||||||
root.Version = types.StateTreeVersion0
|
root.Version = types.StateTreeVersion0
|
||||||
}
|
}
|
||||||
|
|
||||||
switch root.Version {
|
store := adt.WrapStore(context.TODO(), cst)
|
||||||
case types.StateTreeVersion0, types.StateTreeVersion1:
|
|
||||||
// Load the actual state-tree HAMT.
|
|
||||||
nd, err := adt.AsMap(
|
|
||||||
adt.WrapStore(context.TODO(), cst), root.Actors,
|
|
||||||
adtForSTVersion(root.Version),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("loading hamt node %s failed: %s", c, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &StateTree{
|
var (
|
||||||
root: nd,
|
hamt adt.Map
|
||||||
info: root.Info,
|
err error
|
||||||
version: root.Version,
|
)
|
||||||
Store: cst,
|
switch root.Version {
|
||||||
snaps: newStateSnaps(),
|
case types.StateTreeVersion0:
|
||||||
|
var tree *states0.Tree
|
||||||
|
tree, err = states0.LoadTree(store, root.Actors)
|
||||||
|
if tree != nil {
|
||||||
|
hamt = tree.Map
|
||||||
|
}
|
||||||
|
case types.StateTreeVersion1:
|
||||||
|
var tree *states2.Tree
|
||||||
|
tree, err = states2.LoadTree(store, root.Actors)
|
||||||
|
if tree != nil {
|
||||||
|
hamt = tree.Map
|
||||||
|
}
|
||||||
|
case types.StateTreeVersion2:
|
||||||
|
var tree *states3.Tree
|
||||||
|
tree, err = states3.LoadTree(store, root.Actors)
|
||||||
|
if tree != nil {
|
||||||
|
hamt = tree.Map
|
||||||
}
|
}
|
||||||
s.lookupIDFun = s.lookupIDinternal
|
|
||||||
return s, nil
|
|
||||||
default:
|
default:
|
||||||
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version)
|
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version)
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to load state tree: %s", err)
|
||||||
|
return nil, xerrors.Errorf("failed to load state tree: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &StateTree{
|
||||||
|
root: hamt,
|
||||||
|
info: root.Info,
|
||||||
|
version: root.Version,
|
||||||
|
Store: cst,
|
||||||
|
snaps: newStateSnaps(),
|
||||||
|
}
|
||||||
|
s.lookupIDFun = s.lookupIDinternal
|
||||||
|
|
||||||
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error {
|
func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error {
|
||||||
|
@ -4,7 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math"
|
|
||||||
|
"github.com/filecoin-project/go-state-types/rt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
"github.com/filecoin-project/specs-actors/v2/actors/migration/nv4"
|
"github.com/filecoin-project/specs-actors/v2/actors/migration/nv4"
|
||||||
"github.com/filecoin-project/specs-actors/v2/actors/migration/nv7"
|
"github.com/filecoin-project/specs-actors/v2/actors/migration/nv7"
|
||||||
|
"github.com/filecoin-project/specs-actors/v3/actors/migration/nv10"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@ -52,6 +54,21 @@ type Upgrade struct {
|
|||||||
|
|
||||||
type UpgradeSchedule []Upgrade
|
type UpgradeSchedule []Upgrade
|
||||||
|
|
||||||
|
type migrationLogger struct{}
|
||||||
|
|
||||||
|
func (ml migrationLogger) Log(level rt.LogLevel, msg string, args ...interface{}) {
|
||||||
|
switch level {
|
||||||
|
case rt.DEBUG:
|
||||||
|
log.Debugf(msg, args...)
|
||||||
|
case rt.INFO:
|
||||||
|
log.Infof(msg, args...)
|
||||||
|
case rt.WARN:
|
||||||
|
log.Warnf(msg, args...)
|
||||||
|
case rt.ERROR:
|
||||||
|
log.Errorf(msg, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func DefaultUpgradeSchedule() UpgradeSchedule {
|
func DefaultUpgradeSchedule() UpgradeSchedule {
|
||||||
var us UpgradeSchedule
|
var us UpgradeSchedule
|
||||||
|
|
||||||
@ -100,32 +117,13 @@ func DefaultUpgradeSchedule() UpgradeSchedule {
|
|||||||
Height: build.UpgradeOrangeHeight,
|
Height: build.UpgradeOrangeHeight,
|
||||||
Network: network.Version9,
|
Network: network.Version9,
|
||||||
Migration: nil,
|
Migration: nil,
|
||||||
|
}, {
|
||||||
|
Height: build.UpgradeActorsV3Height,
|
||||||
|
Network: network.Version10,
|
||||||
|
Migration: UpgradeActorsV3,
|
||||||
|
Expensive: true,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade
|
|
||||||
updates = []Upgrade{{
|
|
||||||
Height: build.UpgradeBreezeHeight,
|
|
||||||
Network: network.Version1,
|
|
||||||
Migration: UpgradeFaucetBurnRecovery,
|
|
||||||
}, {
|
|
||||||
Height: build.UpgradeSmokeHeight,
|
|
||||||
Network: network.Version2,
|
|
||||||
Migration: nil,
|
|
||||||
}, {
|
|
||||||
Height: build.UpgradeIgnitionHeight,
|
|
||||||
Network: network.Version3,
|
|
||||||
Migration: UpgradeIgnition,
|
|
||||||
}, {
|
|
||||||
Height: build.UpgradeRefuelHeight,
|
|
||||||
Network: network.Version3,
|
|
||||||
Migration: UpgradeRefuel,
|
|
||||||
}, {
|
|
||||||
Height: build.UpgradeLiftoffHeight,
|
|
||||||
Network: network.Version3,
|
|
||||||
Migration: UpgradeLiftoff,
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, u := range updates {
|
for _, u := range updates {
|
||||||
if u.Height < 0 {
|
if u.Height < 0 {
|
||||||
// upgrade disabled
|
// upgrade disabled
|
||||||
@ -704,6 +702,73 @@ func UpgradeCalico(ctx context.Context, sm *StateManager, cb ExecCallback, root
|
|||||||
return newRoot, nil
|
return newRoot, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpgradeActorsV3(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
|
||||||
|
buf := bufbstore.NewTieredBstore(sm.cs.Blockstore(), bstore.NewTemporarySync())
|
||||||
|
store := store.ActorStore(ctx, buf)
|
||||||
|
|
||||||
|
// Load the state root.
|
||||||
|
|
||||||
|
var stateRoot types.StateRoot
|
||||||
|
if err := store.Get(ctx, root, &stateRoot); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stateRoot.Version != types.StateTreeVersion1 {
|
||||||
|
return cid.Undef, xerrors.Errorf(
|
||||||
|
"expected state root version 1 for actors v3 upgrade, got %d",
|
||||||
|
stateRoot.Version,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the migration
|
||||||
|
|
||||||
|
// TODO: store this somewhere and pre-migrate
|
||||||
|
cache := nv10.NewMemMigrationCache()
|
||||||
|
// TODO: tune this.
|
||||||
|
config := nv10.Config{MaxWorkers: 1}
|
||||||
|
newHamtRoot, err := nv10.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist the result.
|
||||||
|
|
||||||
|
newRoot, err := store.Put(ctx, &types.StateRoot{
|
||||||
|
Version: types.StateTreeVersion2,
|
||||||
|
Actors: newHamtRoot,
|
||||||
|
Info: stateRoot.Info,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the result.
|
||||||
|
|
||||||
|
// perform some basic sanity checks to make sure everything still works.
|
||||||
|
if newSm, err := state.LoadStateTree(store, newRoot); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err)
|
||||||
|
} else if newRoot2, err := newSm.Flush(ctx); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("state tree sanity flush failed: %w", err)
|
||||||
|
} else if newRoot2 != newRoot {
|
||||||
|
return cid.Undef, xerrors.Errorf("state-root mismatch: %s != %s", newRoot, newRoot2)
|
||||||
|
} else if _, err := newSm.GetActor(init_.Address); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist the new tree.
|
||||||
|
|
||||||
|
{
|
||||||
|
from := buf
|
||||||
|
to := buf.Read()
|
||||||
|
|
||||||
|
if err := vm.Copy(ctx, from, to, newRoot); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newRoot, nil
|
||||||
|
}
|
||||||
|
|
||||||
func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, name string) error {
|
func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, name string) error {
|
||||||
ia, err := tree.GetActor(builtin0.InitActorAddr)
|
ia, err := tree.GetActor(builtin0.InitActorAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,6 +21,9 @@ import (
|
|||||||
// Used for genesis.
|
// Used for genesis.
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
|
||||||
|
// we use the same adt for all receipts
|
||||||
|
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
@ -42,6 +45,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const LookbackNoLimit = abi.ChainEpoch(-1)
|
const LookbackNoLimit = abi.ChainEpoch(-1)
|
||||||
|
const ReceiptAmtBitwidth = 3
|
||||||
|
|
||||||
var log = logging.Logger("statemgr")
|
var log = logging.Logger("statemgr")
|
||||||
|
|
||||||
@ -384,11 +388,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
|||||||
return cid.Cid{}, cid.Cid{}, err
|
return cid.Cid{}, cid.Cid{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: Is the height correct? Or should it be epoch-1?
|
rectarr := blockadt.MakeEmptyArray(sm.cs.Store(ctx))
|
||||||
rectarr, err := adt.NewArray(sm.cs.Store(ctx), actors.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 {
|
for i, receipt := range receipts {
|
||||||
if err := rectarr.Set(uint64(i), receipt); err != nil {
|
if err := rectarr.Set(uint64(i), receipt); err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err)
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported"
|
exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported"
|
||||||
exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported"
|
exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported"
|
||||||
|
exported3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/exported"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
@ -207,17 +208,17 @@ func GetSectorsForWinningPoSt(ctx context.Context, nv network.Version, pv ffiwra
|
|||||||
return nil, xerrors.Errorf("getting miner info: %w", err)
|
return nil, xerrors.Errorf("getting miner info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wpt, err := info.SealProofType.RegisteredWinningPoStProof()
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("getting window proof type: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
mid, err := address.IDFromAddress(maddr)
|
mid, err := address.IDFromAddress(maddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting miner ID: %w", err)
|
return nil, xerrors.Errorf("getting miner ID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ids, err := pv.GenerateWinningPoStSectorChallenge(ctx, wpt, abi.ActorID(mid), rand, numProvSect)
|
proofType, err := miner.WinningPoStProofTypeFromWindowPoStProofType(nv, info.WindowPoStProofType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("determining winning post proof type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ids, err := pv.GenerateWinningPoStSectorChallenge(ctx, proofType, abi.ActorID(mid), rand, numProvSect)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("generating winning post challenges: %w", err)
|
return nil, xerrors.Errorf("generating winning post challenges: %w", err)
|
||||||
}
|
}
|
||||||
@ -560,6 +561,7 @@ func init() {
|
|||||||
var actors []rt.VMActor
|
var actors []rt.VMActor
|
||||||
actors = append(actors, exported0.BuiltinActors()...)
|
actors = append(actors, exported0.BuiltinActors()...)
|
||||||
actors = append(actors, exported2.BuiltinActors()...)
|
actors = append(actors, exported2.BuiltinActors()...)
|
||||||
|
actors = append(actors, exported3.BuiltinActors()...)
|
||||||
|
|
||||||
for _, actor := range actors {
|
for _, actor := range actors {
|
||||||
exports := actor.Exports()
|
exports := actor.Exports()
|
||||||
|
@ -150,8 +150,11 @@ func TestSyncManagerEdgeCase(t *testing.T) {
|
|||||||
t.Fatalf("Expected tipset %s to sync, but got %s", e1, last)
|
t.Fatalf("Expected tipset %s to sync, but got %s", e1, last)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sm.state) != 0 {
|
sm.mx.Lock()
|
||||||
t.Errorf("active syncs expected empty but got: %d", len(sm.state))
|
activeSyncs := len(sm.state)
|
||||||
|
sm.mx.Unlock()
|
||||||
|
if activeSyncs != 0 {
|
||||||
|
t.Errorf("active syncs expected empty but got: %d", activeSyncs)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,10 @@ type StateTreeVersion uint64
|
|||||||
const (
|
const (
|
||||||
// StateTreeVersion0 corresponds to actors < v2.
|
// StateTreeVersion0 corresponds to actors < v2.
|
||||||
StateTreeVersion0 StateTreeVersion = iota
|
StateTreeVersion0 StateTreeVersion = iota
|
||||||
// StateTreeVersion1 corresponds to actors >= v2.
|
// StateTreeVersion1 corresponds to actors v2
|
||||||
StateTreeVersion1
|
StateTreeVersion1
|
||||||
|
// StateTreeVersion2 corresponds to actors >= v3.
|
||||||
|
StateTreeVersion2
|
||||||
)
|
)
|
||||||
|
|
||||||
type StateRoot struct {
|
type StateRoot struct {
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported"
|
exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported"
|
||||||
exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported"
|
exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported"
|
||||||
vmr "github.com/filecoin-project/specs-actors/v2/actors/runtime"
|
vmr "github.com/filecoin-project/specs-actors/v2/actors/runtime"
|
||||||
|
exported3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/exported"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
@ -62,6 +63,7 @@ func NewActorRegistry() *ActorRegistry {
|
|||||||
// add builtInCode using: register(cid, singleton)
|
// add builtInCode using: register(cid, singleton)
|
||||||
inv.Register(ActorsVersionPredicate(actors.Version0), exported0.BuiltinActors()...)
|
inv.Register(ActorsVersionPredicate(actors.Version0), exported0.BuiltinActors()...)
|
||||||
inv.Register(ActorsVersionPredicate(actors.Version2), exported2.BuiltinActors()...)
|
inv.Register(ActorsVersionPredicate(actors.Version2), exported2.BuiltinActors()...)
|
||||||
|
inv.Register(ActorsVersionPredicate(actors.Version3), exported3.BuiltinActors()...)
|
||||||
|
|
||||||
return inv
|
return inv
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
@ -91,6 +92,8 @@ func newAccountActor(ver actors.Version) *types.Actor {
|
|||||||
code = builtin0.AccountActorCodeID
|
code = builtin0.AccountActorCodeID
|
||||||
case actors.Version2:
|
case actors.Version2:
|
||||||
code = builtin2.AccountActorCodeID
|
code = builtin2.AccountActorCodeID
|
||||||
|
case actors.Version3:
|
||||||
|
code = builtin3.AccountActorCodeID
|
||||||
default:
|
default:
|
||||||
panic("unsupported actors version")
|
panic("unsupported actors version")
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ var chainCmd = &cli.Command{
|
|||||||
chainInspectUsage,
|
chainInspectUsage,
|
||||||
chainDecodeCmd,
|
chainDecodeCmd,
|
||||||
chainEncodeCmd,
|
chainEncodeCmd,
|
||||||
|
chainDisputeSetCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
429
cli/disputer.go
Normal file
429
cli/disputer.go
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
|
||||||
|
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
lapi "github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Confidence = 10
|
||||||
|
|
||||||
|
type minerDeadline struct {
|
||||||
|
miner address.Address
|
||||||
|
index uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
var chainDisputeSetCmd = &cli.Command{
|
||||||
|
Name: "disputer",
|
||||||
|
Usage: "interact with the window post disputer",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "max-fee",
|
||||||
|
Usage: "Spend up to X FIL per DisputeWindowedPoSt message",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "from",
|
||||||
|
Usage: "optionally specify the account to send messages from",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
disputerStartCmd,
|
||||||
|
disputerMsgCmd,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var disputerMsgCmd = &cli.Command{
|
||||||
|
Name: "dispute",
|
||||||
|
Usage: "Send a specific DisputeWindowedPoSt message",
|
||||||
|
ArgsUsage: "[minerAddress index postIndex]",
|
||||||
|
Flags: []cli.Flag{},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.NArg() != 3 {
|
||||||
|
fmt.Println("Usage: dispute [minerAddress index postIndex]")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
toa, err := address.NewFromString(cctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("given 'miner' address %q was invalid: %w", cctx.Args().First(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
deadline, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
postIndex, err := strconv.ParseUint(cctx.Args().Get(2), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fromAddr, err := getSender(ctx, api, cctx.String("from"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dpp, aerr := actors.SerializeParams(&miner3.DisputeWindowedPoStParams{
|
||||||
|
Deadline: deadline,
|
||||||
|
PoStIndex: postIndex,
|
||||||
|
})
|
||||||
|
|
||||||
|
if aerr != nil {
|
||||||
|
return xerrors.Errorf("failed to serailize params: %w", aerr)
|
||||||
|
}
|
||||||
|
|
||||||
|
dmsg := &types.Message{
|
||||||
|
To: toa,
|
||||||
|
From: fromAddr,
|
||||||
|
Value: big.Zero(),
|
||||||
|
Method: builtin3.MethodsMiner.DisputeWindowedPoSt,
|
||||||
|
Params: dpp,
|
||||||
|
}
|
||||||
|
|
||||||
|
rslt, err := api.StateCall(ctx, dmsg, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to simulate dispute: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rslt.MsgRct.ExitCode == 0 {
|
||||||
|
mss, err := getMaxFee(cctx.String("max-fee"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sm, err := api.MpoolPushMessage(ctx, dmsg, mss)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("dispute message ", sm.Cid())
|
||||||
|
} else {
|
||||||
|
fmt.Println("dispute is unsuccessful")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var disputerStartCmd = &cli.Command{
|
||||||
|
Name: "start",
|
||||||
|
Usage: "Start the window post disputer",
|
||||||
|
ArgsUsage: "[minerAddress]",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.Uint64Flag{
|
||||||
|
Name: "start-epoch",
|
||||||
|
Usage: "only start disputing PoSts after this epoch ",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
fromAddr, err := getSender(ctx, api, cctx.String("from"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mss, err := getMaxFee(cctx.String("max-fee"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
startEpoch := abi.ChainEpoch(0)
|
||||||
|
if cctx.IsSet("height") {
|
||||||
|
startEpoch = abi.ChainEpoch(cctx.Uint64("height"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("checking sync status")
|
||||||
|
|
||||||
|
if err := SyncWait(ctx, api, false); err != nil {
|
||||||
|
return xerrors.Errorf("sync wait: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("setting up window post disputer")
|
||||||
|
|
||||||
|
// subscribe to head changes and validate the current value
|
||||||
|
|
||||||
|
headChanges, err := api.ChainNotify(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
head, ok := <-headChanges
|
||||||
|
if !ok {
|
||||||
|
return xerrors.Errorf("Notify stream was invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(head) != 1 {
|
||||||
|
return xerrors.Errorf("Notify first entry should have been one item")
|
||||||
|
}
|
||||||
|
|
||||||
|
if head[0].Type != store.HCCurrent {
|
||||||
|
return xerrors.Errorf("expected current head on Notify stream (got %s)", head[0].Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastEpoch := head[0].Val.Height()
|
||||||
|
lastStatusCheckEpoch := lastEpoch
|
||||||
|
|
||||||
|
// build initial deadlineMap
|
||||||
|
|
||||||
|
minerList, err := api.StateListMiners(ctx, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
knownMiners := make(map[address.Address]struct{})
|
||||||
|
deadlineMap := make(map[abi.ChainEpoch][]minerDeadline)
|
||||||
|
for _, miner := range minerList {
|
||||||
|
dClose, dl, err := makeMinerDeadline(ctx, api, miner)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("making deadline: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
deadlineMap[dClose+Confidence] = append(deadlineMap[dClose+Confidence], *dl)
|
||||||
|
|
||||||
|
knownMiners[miner] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// when this fires, check for newly created miners, and purge any "missed" epochs from deadlineMap
|
||||||
|
statusCheckTicker := time.NewTicker(time.Hour)
|
||||||
|
defer statusCheckTicker.Stop()
|
||||||
|
|
||||||
|
fmt.Println("starting up window post disputer")
|
||||||
|
|
||||||
|
applyTsk := func(tsk types.TipSetKey) error {
|
||||||
|
log.Infof("last checked height: %d", lastEpoch)
|
||||||
|
dls, ok := deadlineMap[lastEpoch]
|
||||||
|
delete(deadlineMap, lastEpoch)
|
||||||
|
if !ok || startEpoch >= lastEpoch {
|
||||||
|
// no deadlines closed at this epoch - Confidence, or we haven't reached the start cutoff yet
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dpmsgs := make([]*types.Message, 0)
|
||||||
|
|
||||||
|
// TODO: Parallelizeable
|
||||||
|
for _, dl := range dls {
|
||||||
|
fullDeadlines, err := api.StateMinerDeadlines(ctx, dl.miner, tsk)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to load deadlines: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(dl.index) >= len(fullDeadlines) {
|
||||||
|
return xerrors.Errorf("deadline index %d not found in deadlines", dl.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
ms, err := makeDisputeWindowedPosts(ctx, api, dl, fullDeadlines[dl.index].DisputableProofCount, fromAddr)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to check for disputes: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dpmsgs = append(dpmsgs, ms...)
|
||||||
|
|
||||||
|
dClose, dl, err := makeMinerDeadline(ctx, api, dl.miner)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("making deadline: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
deadlineMap[dClose+Confidence] = append(deadlineMap[dClose+Confidence], *dl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Parallelizeable / can be integrated into the previous deadline-iterating for loop
|
||||||
|
for _, dpmsg := range dpmsgs {
|
||||||
|
log.Infof("disputing a PoSt from miner %s", dpmsg.To)
|
||||||
|
m, err := api.MpoolPushMessage(ctx, dpmsg, mss)
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("failed to dispute post message: %s", err.Error())
|
||||||
|
} else {
|
||||||
|
log.Infof("disputed a PoSt in message: %s", m.Cid())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
disputeLoop := func() error {
|
||||||
|
select {
|
||||||
|
case notif, ok := <-headChanges:
|
||||||
|
if !ok {
|
||||||
|
return xerrors.Errorf("head change channel errored")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, val := range notif {
|
||||||
|
switch val.Type {
|
||||||
|
case store.HCApply:
|
||||||
|
for ; lastEpoch <= val.Val.Height(); lastEpoch++ {
|
||||||
|
err := applyTsk(val.Val.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case store.HCRevert:
|
||||||
|
// do nothing
|
||||||
|
default:
|
||||||
|
return xerrors.Errorf("unexpected head change type %s", val.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case <-statusCheckTicker.C:
|
||||||
|
log.Infof("Running status check: ")
|
||||||
|
|
||||||
|
minerList, err = api.StateListMiners(ctx, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting miner list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range minerList {
|
||||||
|
_, ok := knownMiners[m]
|
||||||
|
if !ok {
|
||||||
|
dClose, dl, err := makeMinerDeadline(ctx, api, m)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("making deadline: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
deadlineMap[dClose+Confidence] = append(deadlineMap[dClose+Confidence], *dl)
|
||||||
|
|
||||||
|
knownMiners[m] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ; lastStatusCheckEpoch < lastEpoch; lastStatusCheckEpoch++ {
|
||||||
|
// if an epoch got "skipped" from the deadlineMap somehow, just fry it now instead of letting it sit around forever
|
||||||
|
_, ok := deadlineMap[lastStatusCheckEpoch]
|
||||||
|
if ok {
|
||||||
|
log.Infof("epoch %d was skipped during execution, deleting it from deadlineMap")
|
||||||
|
delete(deadlineMap, lastStatusCheckEpoch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Status check complete")
|
||||||
|
case <-ctx.Done():
|
||||||
|
return xerrors.Errorf("context cancelled")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
err := disputeLoop()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("disputer shutting down: ", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// for a given miner, index, and maxPostIndex, tries to dispute posts from 0...postsSnapshotted-1
|
||||||
|
// returns a list of DisputeWindowedPoSt msgs that are expected to succeed if sent
|
||||||
|
func makeDisputeWindowedPosts(ctx context.Context, api lapi.FullNode, dl minerDeadline, postsSnapshotted uint64, sender address.Address) ([]*types.Message, error) {
|
||||||
|
disputes := make([]*types.Message, 0)
|
||||||
|
|
||||||
|
for i := uint64(0); i < postsSnapshotted; i++ {
|
||||||
|
|
||||||
|
dpp, aerr := actors.SerializeParams(&miner3.DisputeWindowedPoStParams{
|
||||||
|
Deadline: dl.index,
|
||||||
|
PoStIndex: i,
|
||||||
|
})
|
||||||
|
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to serailize params: %w", aerr)
|
||||||
|
}
|
||||||
|
|
||||||
|
dispute := &types.Message{
|
||||||
|
To: dl.miner,
|
||||||
|
From: sender,
|
||||||
|
Value: big.Zero(),
|
||||||
|
Method: builtin3.MethodsMiner.DisputeWindowedPoSt,
|
||||||
|
Params: dpp,
|
||||||
|
}
|
||||||
|
|
||||||
|
rslt, err := api.StateCall(ctx, dispute, types.EmptyTSK)
|
||||||
|
if err == nil && rslt.MsgRct.ExitCode == 0 {
|
||||||
|
disputes = append(disputes, dispute)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return disputes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeMinerDeadline(ctx context.Context, api lapi.FullNode, mAddr address.Address) (abi.ChainEpoch, *minerDeadline, error) {
|
||||||
|
dl, err := api.StateMinerProvingDeadline(ctx, mAddr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return -1, nil, xerrors.Errorf("getting proving index list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dl.Close, &minerDeadline{
|
||||||
|
miner: mAddr,
|
||||||
|
index: dl.Index,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSender(ctx context.Context, api lapi.FullNode, fromStr string) (address.Address, error) {
|
||||||
|
if fromStr == "" {
|
||||||
|
return api.WalletDefaultAddress(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
addr, err := address.NewFromString(fromStr)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
has, err := api.WalletHas(ctx, addr)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has {
|
||||||
|
return address.Undef, xerrors.Errorf("wallet doesn't contain: %s ", addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMaxFee(maxStr string) (*lapi.MessageSendSpec, error) {
|
||||||
|
if maxStr != "" {
|
||||||
|
maxFee, err := types.ParseFIL(maxStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("parsing max-fee: %w", err)
|
||||||
|
}
|
||||||
|
return &lapi.MessageSendSpec{
|
||||||
|
MaxFee: types.BigInt(maxFee),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -245,7 +245,7 @@ func startNodes(
|
|||||||
|
|
||||||
// Create a gateway server in front of the full node
|
// Create a gateway server in front of the full node
|
||||||
gapiImpl := newGatewayAPI(fullNode, lookbackCap, stateWaitLookbackLimit)
|
gapiImpl := newGatewayAPI(fullNode, lookbackCap, stateWaitLookbackLimit)
|
||||||
_, addr, err := builder.CreateRPCServer(gapiImpl)
|
_, addr, err := builder.CreateRPCServer(t, gapiImpl)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create a gateway client API that connects to the gateway server
|
// Create a gateway client API that connects to the gateway server
|
||||||
|
@ -120,7 +120,7 @@ var datastoreGetCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
ArgsUsage: "[namespace key]",
|
ArgsUsage: "[namespace key]",
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
logging.SetLogLevel("badger", "ERROR") // nolint:errchec
|
logging.SetLogLevel("badger", "ERROR") // nolint:errcheck
|
||||||
|
|
||||||
r, err := repo.NewFS(cctx.String("repo"))
|
r, err := repo.NewFS(cctx.String("repo"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,7 +50,7 @@ func TestWorkerKeyChange(t *testing.T) {
|
|||||||
|
|
||||||
blocktime := 1 * time.Millisecond
|
blocktime := 1 * time.Millisecond
|
||||||
|
|
||||||
n, sn := builder.MockSbBuilder(t, []test.FullNodeOpts{test.FullNodeWithActorsV2At(1), test.FullNodeWithActorsV2At(1)}, test.OneMiner)
|
n, sn := builder.MockSbBuilder(t, []test.FullNodeOpts{test.FullNodeWithActorsV3At(2), test.FullNodeWithActorsV3At(2)}, test.OneMiner)
|
||||||
|
|
||||||
client1 := n[0]
|
client1 := n[0]
|
||||||
client2 := n[1]
|
client2 := n[1]
|
||||||
|
@ -430,11 +430,6 @@ var provingCheckProvableCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pf, err := info.SealProofType.RegisteredWindowPoStProof()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
partitions, err := api.StateMinerPartitions(ctx, addr, dlIdx, types.EmptyTSK)
|
partitions, err := api.StateMinerPartitions(ctx, addr, dlIdx, types.EmptyTSK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -463,7 +458,7 @@ var provingCheckProvableCmd = &cli.Command{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
bad, err := sapi.CheckProvable(ctx, pf, tocheck, cctx.Bool("slow"))
|
bad, err := sapi.CheckProvable(ctx, info.WindowPoStProofType, tocheck, cctx.Bool("slow"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -4028,7 +4028,7 @@ Response:
|
|||||||
"WorkerChangeEpoch": 10101,
|
"WorkerChangeEpoch": 10101,
|
||||||
"PeerId": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
|
"PeerId": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
|
||||||
"Multiaddrs": null,
|
"Multiaddrs": null,
|
||||||
"SealProofType": 8,
|
"WindowPoStProofType": 8,
|
||||||
"SectorSize": 34359738368,
|
"SectorSize": 34359738368,
|
||||||
"WindowPoStPartitionSectors": 42,
|
"WindowPoStPartitionSectors": 42,
|
||||||
"ConsensusFaultElapsed": 10101
|
"ConsensusFaultElapsed": 10101
|
||||||
|
7
extern/storage-sealing/sealing.go
vendored
7
extern/storage-sealing/sealing.go
vendored
@ -475,7 +475,12 @@ func (m *Sealing) currentSealProof(ctx context.Context) (abi.RegisteredSealProof
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return mi.SealProofType, nil
|
ver, err := m.api.StateNetworkVersion(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return miner.PreferredSealProofTypeFromWindowPoStType(ver, mi.WindowPoStProofType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) minerSector(spt abi.RegisteredSealProof, num abi.SectorNumber) storage.SectorRef {
|
func (m *Sealing) minerSector(spt abi.RegisteredSealProof, num abi.SectorNumber) storage.SectorRef {
|
||||||
|
5
go.mod
5
go.mod
@ -38,12 +38,13 @@ require (
|
|||||||
github.com/filecoin-project/go-multistore v0.0.3
|
github.com/filecoin-project/go-multistore v0.0.3
|
||||||
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20
|
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20
|
||||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc
|
github.com/filecoin-project/go-state-types v0.0.0-20210119062722-4adba5aaea71
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe
|
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe
|
||||||
github.com/filecoin-project/go-statestore v0.1.0
|
github.com/filecoin-project/go-statestore v0.1.0
|
||||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
||||||
github.com/filecoin-project/specs-actors v0.9.13
|
github.com/filecoin-project/specs-actors v0.9.13
|
||||||
github.com/filecoin-project/specs-actors/v2 v2.3.3
|
github.com/filecoin-project/specs-actors/v2 v2.3.4
|
||||||
|
github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210122191213-c7ea99141c44
|
||||||
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506
|
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506
|
||||||
github.com/filecoin-project/test-vectors/schema v0.0.5
|
github.com/filecoin-project/test-vectors/schema v0.0.5
|
||||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||||
|
12
go.sum
12
go.sum
@ -246,6 +246,8 @@ github.com/filecoin-project/go-amt-ipld/v2 v2.1.0 h1:t6qDiuGYYngDqaLc2ZUvdtAg4UN
|
|||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs=
|
github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs=
|
||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 h1:pIuR0dnMD0i+as8wNnjjHyQrnhP5O5bmba/lmgQeRgU=
|
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 h1:pIuR0dnMD0i+as8wNnjjHyQrnhP5O5bmba/lmgQeRgU=
|
||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349/go.mod h1:vgmwKBkx+ca5OIeEvstiQgzAZnb7R6QaqE1oEDSqa6g=
|
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349/go.mod h1:vgmwKBkx+ca5OIeEvstiQgzAZnb7R6QaqE1oEDSqa6g=
|
||||||
|
github.com/filecoin-project/go-amt-ipld/v3 v3.0.0 h1:Ou/q82QeHGOhpkedvaxxzpBYuqTxLCcj5OChkDNx4qc=
|
||||||
|
github.com/filecoin-project/go-amt-ipld/v3 v3.0.0/go.mod h1:Qa95YNAbtoVCTSVtX38aAC1ptBnJfPma1R/zZsKmx4o=
|
||||||
github.com/filecoin-project/go-bitfield v0.2.0 h1:gCtLcjskIPtdg4NfN7gQZSQF9yrBQ7mkT0qCJxzGI2Q=
|
github.com/filecoin-project/go-bitfield v0.2.0 h1:gCtLcjskIPtdg4NfN7gQZSQF9yrBQ7mkT0qCJxzGI2Q=
|
||||||
github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
|
github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
|
||||||
github.com/filecoin-project/go-bitfield v0.2.3-0.20201110211213-fe2c1862e816 h1:RMdzMqe3mu2Z/3N3b9UEfkbGZxukstmZgNC024ybWhA=
|
github.com/filecoin-project/go-bitfield v0.2.3-0.20201110211213-fe2c1862e816 h1:RMdzMqe3mu2Z/3N3b9UEfkbGZxukstmZgNC024ybWhA=
|
||||||
@ -273,6 +275,8 @@ github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3
|
|||||||
github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24=
|
github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24=
|
||||||
github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM=
|
github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM=
|
||||||
github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+eEvrDCGJoPLxFpDynFjYfBjI=
|
github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+eEvrDCGJoPLxFpDynFjYfBjI=
|
||||||
|
github.com/filecoin-project/go-hamt-ipld/v3 v3.0.0 h1:aEOgJxSMbJ7XtuX3WxXvbpkBDp4Sqn3jyx/umGyL8s4=
|
||||||
|
github.com/filecoin-project/go-hamt-ipld/v3 v3.0.0/go.mod h1:gXpNmr3oQx8l3o7qkGyDjJjYSRX7hp/FGOStdqrWyDI=
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.2 h1:MTebUawBHLxxY9gDi1WXuGc89TWIDmsgoDqeZSk9KRw=
|
github.com/filecoin-project/go-jsonrpc v0.1.2 h1:MTebUawBHLxxY9gDi1WXuGc89TWIDmsgoDqeZSk9KRw=
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.2/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4=
|
github.com/filecoin-project/go-jsonrpc v0.1.2/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4=
|
||||||
github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI=
|
github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI=
|
||||||
@ -286,6 +290,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go
|
|||||||
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc h1:+hbMY4Pcx2oizrfH08VWXwrj5mU8aJT6g0UNxGHFCGU=
|
github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc h1:+hbMY4Pcx2oizrfH08VWXwrj5mU8aJT6g0UNxGHFCGU=
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||||
|
github.com/filecoin-project/go-state-types v0.0.0-20210119062722-4adba5aaea71 h1:Cas/CUB4ybYpdxvW7LouaydE16cpwdq3vvS3qgZuU+Q=
|
||||||
|
github.com/filecoin-project/go-state-types v0.0.0-20210119062722-4adba5aaea71/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw=
|
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw=
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||||
github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ=
|
github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ=
|
||||||
@ -299,8 +305,10 @@ github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK
|
|||||||
github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY=
|
github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY=
|
||||||
github.com/filecoin-project/specs-actors/v2 v2.3.2 h1:2Vcf4CGa29kRh4JJ02m+FbvD/p3YNnLGsaHfw7Uj49g=
|
github.com/filecoin-project/specs-actors/v2 v2.3.2 h1:2Vcf4CGa29kRh4JJ02m+FbvD/p3YNnLGsaHfw7Uj49g=
|
||||||
github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y=
|
github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y=
|
||||||
github.com/filecoin-project/specs-actors/v2 v2.3.3 h1:5Pd6pjU7VjUye+Hz4gYBCPAFdBxtEbHsgGYvWmfc83w=
|
github.com/filecoin-project/specs-actors/v2 v2.3.4 h1:NZK2oMCcA71wNsUzDBmLQyRMzcCnX9tDGvwZ53G67j8=
|
||||||
github.com/filecoin-project/specs-actors/v2 v2.3.3/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y=
|
github.com/filecoin-project/specs-actors/v2 v2.3.4/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y=
|
||||||
|
github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210122191213-c7ea99141c44 h1:QYCM/E0u5XJVJENnegPR7I7meciI3CITylc9BzyoiFE=
|
||||||
|
github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210122191213-c7ea99141c44/go.mod h1:aVf248CfjfyCmVel4UuFAA3u+9UQjqtqHpgfYv+M+9U=
|
||||||
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw=
|
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw=
|
||||||
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
|
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
|
||||||
github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=
|
github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/events"
|
"github.com/filecoin-project/lotus/chain/events"
|
||||||
"github.com/filecoin-project/lotus/chain/events/state"
|
"github.com/filecoin-project/lotus/chain/events/state"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -156,30 +157,36 @@ func (n *ProviderNodeAdapter) VerifySignature(ctx context.Context, sig crypto.Si
|
|||||||
return err == nil, err
|
return err == nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *ProviderNodeAdapter) GetMinerWorkerAddress(ctx context.Context, miner address.Address, tok shared.TipSetToken) (address.Address, error) {
|
func (n *ProviderNodeAdapter) GetMinerWorkerAddress(ctx context.Context, maddr address.Address, tok shared.TipSetToken) (address.Address, error) {
|
||||||
tsk, err := types.TipSetKeyFromBytes(tok)
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mi, err := n.StateMinerInfo(ctx, miner, tsk)
|
mi, err := n.StateMinerInfo(ctx, maddr, tsk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Address{}, err
|
return address.Address{}, err
|
||||||
}
|
}
|
||||||
return mi.Worker, nil
|
return mi.Worker, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *ProviderNodeAdapter) GetProofType(ctx context.Context, miner address.Address, tok shared.TipSetToken) (abi.RegisteredSealProof, error) {
|
func (n *ProviderNodeAdapter) GetProofType(ctx context.Context, maddr address.Address, tok shared.TipSetToken) (abi.RegisteredSealProof, error) {
|
||||||
tsk, err := types.TipSetKeyFromBytes(tok)
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mi, err := n.StateMinerInfo(ctx, miner, tsk)
|
mi, err := n.StateMinerInfo(ctx, maddr, tsk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return mi.SealProofType, nil
|
|
||||||
|
nver, err := n.StateNetworkVersion(ctx, tsk)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return miner.PreferredSealProofTypeFromWindowPoStType(nver, mi.WindowPoStProofType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *ProviderNodeAdapter) SignBytes(ctx context.Context, signer address.Address, b []byte) (*crypto.Signature, error) {
|
func (n *ProviderNodeAdapter) SignBytes(ctx context.Context, signer address.Address, b []byte) (*crypto.Signature, error) {
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-padreader"
|
"github.com/filecoin-project/go-padreader"
|
||||||
@ -157,6 +159,16 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams)
|
|||||||
dealStart = ts.Height() + abi.ChainEpoch(dealStartBufferHours*blocksPerHour) // TODO: Get this from storage ask
|
dealStart = ts.Height() + abi.ChainEpoch(dealStartBufferHours*blocksPerHour) // TODO: Get this from storage ask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
networkVersion, err := a.StateNetworkVersion(ctx, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to get network version: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
st, err := miner.PreferredSealProofTypeFromWindowPoStType(networkVersion, mi.WindowPoStProofType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to get seal proof type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
result, err := a.SMDealClient.ProposeStorageDeal(ctx, storagemarket.ProposeStorageDealParams{
|
result, err := a.SMDealClient.ProposeStorageDeal(ctx, storagemarket.ProposeStorageDealParams{
|
||||||
Addr: params.Wallet,
|
Addr: params.Wallet,
|
||||||
Info: &providerInfo,
|
Info: &providerInfo,
|
||||||
@ -165,7 +177,7 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams)
|
|||||||
EndEpoch: calcDealExpiration(params.MinBlocksDuration, md, dealStart),
|
EndEpoch: calcDealExpiration(params.MinBlocksDuration, md, dealStart),
|
||||||
Price: params.EpochPrice,
|
Price: params.EpochPrice,
|
||||||
Collateral: params.ProviderCollateral,
|
Collateral: params.ProviderCollateral,
|
||||||
Rt: mi.SealProofType,
|
Rt: st,
|
||||||
FastRetrieval: params.FastRetrieval,
|
FastRetrieval: params.FastRetrieval,
|
||||||
VerifiedDeal: params.VerifiedDeal,
|
VerifiedDeal: params.VerifiedDeal,
|
||||||
StoreID: storeID,
|
StoreID: storeID,
|
||||||
|
@ -140,15 +140,10 @@ func (m *StateModule) StateMinerInfo(ctx context.Context, actor address.Address,
|
|||||||
return miner.MinerInfo{}, xerrors.Errorf("failed to load miner actor state: %w", err)
|
return miner.MinerInfo{}, xerrors.Errorf("failed to load miner actor state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: You know, this is terrible.
|
|
||||||
// I mean, we _really_ shouldn't do this. Maybe we should convert somewhere else?
|
|
||||||
info, err := mas.Info()
|
info, err := mas.Info()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return miner.MinerInfo{}, err
|
return miner.MinerInfo{}, err
|
||||||
}
|
}
|
||||||
if m.StateManager.GetNtwkVersion(ctx, ts.Height()) >= network.Version7 && info.SealProofType < abi.RegisteredSealProof_StackedDrg2KiBV1_1 {
|
|
||||||
info.SealProofType += abi.RegisteredSealProof_StackedDrg2KiBV1_1
|
|
||||||
}
|
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,13 +165,19 @@ func (a *StateAPI) StateMinerDeadlines(ctx context.Context, m address.Address, t
|
|||||||
|
|
||||||
out := make([]api.Deadline, deadlines)
|
out := make([]api.Deadline, deadlines)
|
||||||
if err := mas.ForEachDeadline(func(i uint64, dl miner.Deadline) error {
|
if err := mas.ForEachDeadline(func(i uint64, dl miner.Deadline) error {
|
||||||
ps, err := dl.PostSubmissions()
|
ps, err := dl.PartitionsPoSted()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := dl.DisputableProofCount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i] = api.Deadline{
|
out[i] = api.Deadline{
|
||||||
PostSubmissions: ps,
|
PostSubmissions: ps,
|
||||||
|
DisputableProofCount: l,
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -58,6 +58,7 @@ import (
|
|||||||
lapi "github.com/filecoin-project/lotus/api"
|
lapi "github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/gen"
|
"github.com/filecoin-project/lotus/chain/gen"
|
||||||
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -66,7 +67,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/markets"
|
"github.com/filecoin-project/lotus/markets"
|
||||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||||
"github.com/filecoin-project/lotus/markets/retrievaladapter"
|
"github.com/filecoin-project/lotus/markets/retrievaladapter"
|
||||||
"github.com/filecoin-project/lotus/miner"
|
lotusminer "github.com/filecoin-project/lotus/miner"
|
||||||
"github.com/filecoin-project/lotus/node/config"
|
"github.com/filecoin-project/lotus/node/config"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/lotus/node/modules/helpers"
|
"github.com/filecoin-project/lotus/node/modules/helpers"
|
||||||
@ -127,8 +128,12 @@ func SealProofType(maddr dtypes.MinerAddress, fnapi lapi.FullNode) (abi.Register
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
networkVersion, err := fnapi.StateNetworkVersion(context.TODO(), types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
return mi.SealProofType, nil
|
return miner.PreferredSealProofTypeFromWindowPoStType(networkVersion, mi.WindowPoStProofType)
|
||||||
}
|
}
|
||||||
|
|
||||||
type sidsc struct {
|
type sidsc struct {
|
||||||
@ -419,13 +424,13 @@ func StagingGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.Stagi
|
|||||||
return gs
|
return gs
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*miner.Miner, error) {
|
func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*lotusminer.Miner, error) {
|
||||||
minerAddr, err := minerAddrFromDS(ds)
|
minerAddr, err := minerAddrFromDS(ds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
m := miner.NewMiner(api, epp, minerAddr, sf, j)
|
m := lotusminer.NewMiner(api, epp, minerAddr, sf, j)
|
||||||
|
|
||||||
lc.Append(fx.Hook{
|
lc.Append(fx.Hook{
|
||||||
OnStart: func(ctx context.Context) error {
|
OnStart: func(ctx context.Context) error {
|
||||||
|
@ -198,3 +198,29 @@ func TestPaymentChannels(t *testing.T) {
|
|||||||
|
|
||||||
test.TestPaymentChannels(t, builder.MockSbBuilder, 5*time.Millisecond)
|
test.TestPaymentChannels(t, builder.MockSbBuilder, 5*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWindowPostDispute(t *testing.T) {
|
||||||
|
if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" {
|
||||||
|
t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run")
|
||||||
|
}
|
||||||
|
logging.SetLogLevel("miner", "ERROR")
|
||||||
|
logging.SetLogLevel("chainstore", "ERROR")
|
||||||
|
logging.SetLogLevel("chain", "ERROR")
|
||||||
|
logging.SetLogLevel("sub", "ERROR")
|
||||||
|
logging.SetLogLevel("storageminer", "ERROR")
|
||||||
|
|
||||||
|
test.TestWindowPostDispute(t, builder.MockSbBuilder, 2*time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWindowPostDisputeFails(t *testing.T) {
|
||||||
|
if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" {
|
||||||
|
t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run")
|
||||||
|
}
|
||||||
|
logging.SetLogLevel("miner", "ERROR")
|
||||||
|
logging.SetLogLevel("chainstore", "ERROR")
|
||||||
|
logging.SetLogLevel("chain", "ERROR")
|
||||||
|
logging.SetLogLevel("sub", "ERROR")
|
||||||
|
logging.SetLogLevel("storageminer", "ERROR")
|
||||||
|
|
||||||
|
test.TestWindowPostDisputeFails(t, builder.MockSbBuilder, 2*time.Millisecond)
|
||||||
|
}
|
||||||
|
@ -148,7 +148,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return test.TestStorageNode{StorageMiner: minerapi, MineOne: mineOne}
|
return test.TestStorageNode{StorageMiner: minerapi, MineOne: mineOne, Stop: stop}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Builder(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) {
|
func Builder(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) {
|
||||||
@ -491,34 +491,40 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fullRpc(t *testing.T, nd test.TestNode) test.TestNode {
|
func fullRpc(t *testing.T, nd test.TestNode) test.TestNode {
|
||||||
ma, listenAddr, err := CreateRPCServer(nd)
|
ma, listenAddr, err := CreateRPCServer(t, nd)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var stop func()
|
||||||
var full test.TestNode
|
var full test.TestNode
|
||||||
full.FullNode, _, err = client.NewFullNodeRPC(context.Background(), listenAddr, nil)
|
full.FullNode, stop, err = client.NewFullNodeRPC(context.Background(), listenAddr, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(stop)
|
||||||
|
|
||||||
full.ListenAddr = ma
|
full.ListenAddr = ma
|
||||||
return full
|
return full
|
||||||
}
|
}
|
||||||
|
|
||||||
func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode {
|
func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode {
|
||||||
ma, listenAddr, err := CreateRPCServer(nd)
|
ma, listenAddr, err := CreateRPCServer(t, nd)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var stop func()
|
||||||
var storer test.TestStorageNode
|
var storer test.TestStorageNode
|
||||||
storer.StorageMiner, _, err = client.NewStorageMinerRPC(context.Background(), listenAddr, nil)
|
storer.StorageMiner, stop, err = client.NewStorageMinerRPC(context.Background(), listenAddr, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(stop)
|
||||||
|
|
||||||
storer.ListenAddr = ma
|
storer.ListenAddr = ma
|
||||||
storer.MineOne = nd.MineOne
|
storer.MineOne = nd.MineOne
|
||||||
return storer
|
return storer
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateRPCServer(handler interface{}) (multiaddr.Multiaddr, string, error) {
|
func CreateRPCServer(t *testing.T, handler interface{}) (multiaddr.Multiaddr, string, error) {
|
||||||
rpcServer := jsonrpc.NewServer()
|
rpcServer := jsonrpc.NewServer()
|
||||||
rpcServer.Register("Filecoin", handler)
|
rpcServer.Register("Filecoin", handler)
|
||||||
testServ := httptest.NewServer(rpcServer) // todo: close
|
testServ := httptest.NewServer(rpcServer) // todo: close
|
||||||
|
t.Cleanup(testServ.Close)
|
||||||
|
t.Cleanup(testServ.CloseClientConnections)
|
||||||
|
|
||||||
addr := testServ.Listener.Addr()
|
addr := testServ.Listener.Addr()
|
||||||
listenAddr := "ws://" + addr.String()
|
listenAddr := "ws://" + addr.String()
|
||||||
|
@ -225,18 +225,13 @@ func NewWinningPoStProver(api api.FullNode, prover storage.Prover, verifier ffiw
|
|||||||
return nil, xerrors.Errorf("getting sector size: %w", err)
|
return nil, xerrors.Errorf("getting sector size: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wpt, err := mi.SealProofType.RegisteredWinningPoStProof()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if build.InsecurePoStValidation {
|
if build.InsecurePoStValidation {
|
||||||
log.Warn("*****************************************************************************")
|
log.Warn("*****************************************************************************")
|
||||||
log.Warn(" Generating fake PoSt proof! You should only see this while running tests! ")
|
log.Warn(" Generating fake PoSt proof! You should only see this while running tests! ")
|
||||||
log.Warn("*****************************************************************************")
|
log.Warn("*****************************************************************************")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &StorageWpp{prover, verifier, abi.ActorID(miner), wpt}, nil
|
return &StorageWpp{prover, verifier, abi.ActorID(miner), mi.WindowPoStProofType}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ gen.WinningPoStProver = (*StorageWpp)(nil)
|
var _ gen.WinningPoStProver = (*StorageWpp)(nil)
|
||||||
|
@ -47,18 +47,13 @@ func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, as
|
|||||||
return nil, xerrors.Errorf("getting sector size: %w", err)
|
return nil, xerrors.Errorf("getting sector size: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rt, err := mi.SealProofType.RegisteredWindowPoStProof()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &WindowPoStScheduler{
|
return &WindowPoStScheduler{
|
||||||
api: api,
|
api: api,
|
||||||
feeCfg: fc,
|
feeCfg: fc,
|
||||||
addrSel: as,
|
addrSel: as,
|
||||||
prover: sb,
|
prover: sb,
|
||||||
faultTracker: ft,
|
faultTracker: ft,
|
||||||
proofType: rt,
|
proofType: mi.WindowPoStProofType,
|
||||||
partitionSectors: mi.WindowPoStPartitionSectors,
|
partitionSectors: mi.WindowPoStPartitionSectors,
|
||||||
|
|
||||||
actor: actor,
|
actor: actor,
|
||||||
|
Loading…
Reference in New Issue
Block a user