Merge pull request #6108 from filecoin-project/feat/actors-codegen

wip actor wrapper codegen
This commit is contained in:
Aayush Rajasekaran 2021-05-10 20:12:57 -04:00 committed by GitHub
commit bf10b051ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 3752 additions and 370 deletions

View File

@ -333,6 +333,10 @@ type-gen: api-gen
method-gen: api-gen
(cd ./lotuspond/front/src/chain && go run ./methodgen.go)
actors-gen:
go run ./chain/actors/agen
go fmt ./...
api-gen:
go run ./gen/api
goimports -w api
@ -341,9 +345,9 @@ api-gen:
docsgen: docsgen-md docsgen-openrpc
docsgen-md-bin: api-gen
docsgen-md-bin: api-gen actors-gen
go build $(GOFLAGS) -o docgen-md ./api/docgen/cmd
docsgen-openrpc-bin: api-gen
docsgen-openrpc-bin: api-gen actors-gen
go build $(GOFLAGS) -o docgen-openrpc ./api/docgen-openrpc/cmd
docsgen-md: docsgen-md-full docsgen-md-storage docsgen-md-worker
@ -367,7 +371,7 @@ docsgen-openrpc-worker: docsgen-openrpc-bin
.PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin
gen: type-gen method-gen docsgen api-gen
gen: actors-gen type-gen method-gen docsgen api-gen
@echo ">>> IF YOU'VE MODIFIED THE CLI, REMEMBER TO ALSO MAKE docsgen-cli"
.PHONY: gen

View File

@ -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) {
ctx := context.Background()
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(upgradeHeight)}, OneMiner)
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]

View File

@ -63,7 +63,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(upgradeH)}, OneMiner)
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeH)}, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
minerA := sn[0]

View File

@ -206,7 +206,7 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
func (ts *testSuite) testNonGenesisMiner(t *testing.T) {
ctx := context.Background()
n, sn := ts.makeNodes(t, []FullNodeOpts{
FullNodeWithActorsV4At(-1),
FullNodeWithLatestActorsAt(-1),
}, []StorageMiner{
{Full: 0, Preseal: PresealGenesis},
})

View File

@ -121,7 +121,7 @@ var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
var OneFull = DefaultFullOpts(1)
var TwoFull = DefaultFullOpts(2)
var FullNodeWithActorsV4At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
var FullNodeWithLatestActorsAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
if upgradeHeight == -1 {
upgradeHeight = 3
}

View File

@ -223,7 +223,7 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(upgradeHeight)}, OneMiner)
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
@ -442,7 +442,7 @@ func TestTerminate(t *testing.T, b APIBuilder, blocktime time.Duration) {
nSectors := uint64(2)
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(-1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}})
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}})
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
@ -617,7 +617,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration)
///
// Then we're going to manually submit bad proofs.
n, sn := b(t, []FullNodeOpts{
FullNodeWithActorsV4At(-1),
FullNodeWithLatestActorsAt(-1),
}, []StorageMiner{
{Full: 0, Preseal: PresealGenesis},
{Full: 0},
@ -900,7 +900,7 @@ func TestWindowPostDisputeFails(t *testing.T, b APIBuilder, blocktime time.Durat
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(-1)}, OneMiner)
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]

218
chain/actors/agen/main.go Normal file
View File

@ -0,0 +1,218 @@
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"text/template"
"golang.org/x/xerrors"
)
var latestVersion = 4
var versions = []int{0, 2, 3, latestVersion}
var versionImports = map[int]string{
0: "/",
2: "/v2/",
3: "/v3/",
latestVersion: "/v4/",
}
var actors = map[string][]int{
"account": versions,
"cron": versions,
"init": versions,
"market": versions,
"miner": versions,
"multisig": versions,
"paych": versions,
"power": versions,
"reward": versions,
"verifreg": versions,
}
func main() {
if err := generateAdapters(); err != nil {
fmt.Println(err)
return
}
if err := generatePolicy("chain/actors/policy/policy.go"); err != nil {
fmt.Println(err)
return
}
if err := generateBuiltin("chain/actors/builtin/builtin.go"); err != nil {
fmt.Println(err)
return
}
}
func generateAdapters() error {
for act, versions := range actors {
actDir := filepath.Join("chain/actors/builtin", act)
if err := generateState(actDir); err != nil {
return err
}
if err := generateMessages(actDir); err != nil {
return err
}
{
af, err := ioutil.ReadFile(filepath.Join(actDir, "actor.go.template"))
if err != nil {
return xerrors.Errorf("loading actor template: %w", err)
}
tpl := template.Must(template.New("").Funcs(template.FuncMap{
"import": func(v int) string { return versionImports[v] },
}).Parse(string(af)))
var b bytes.Buffer
err = tpl.Execute(&b, map[string]interface{}{
"versions": versions,
"latestVersion": latestVersion,
})
if err != nil {
return err
}
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("%s.go", act)), b.Bytes(), 0666); err != nil {
return err
}
}
}
return nil
}
func generateState(actDir string) error {
af, err := ioutil.ReadFile(filepath.Join(actDir, "state.go.template"))
if err != nil {
if os.IsNotExist(err) {
return nil // skip
}
return xerrors.Errorf("loading state adapter template: %w", err)
}
for _, version := range versions {
tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af)))
var b bytes.Buffer
err := tpl.Execute(&b, map[string]interface{}{
"v": version,
"import": versionImports[version],
})
if err != nil {
return err
}
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("v%d.go", version)), b.Bytes(), 0666); err != nil {
return err
}
}
return nil
}
func generateMessages(actDir string) error {
af, err := ioutil.ReadFile(filepath.Join(actDir, "message.go.template"))
if err != nil {
if os.IsNotExist(err) {
return nil // skip
}
return xerrors.Errorf("loading message adapter template: %w", err)
}
for _, version := range versions {
tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af)))
var b bytes.Buffer
err := tpl.Execute(&b, map[string]interface{}{
"v": version,
"import": versionImports[version],
})
if err != nil {
return err
}
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("message%d.go", version)), b.Bytes(), 0666); err != nil {
return err
}
}
return nil
}
func generatePolicy(policyPath string) error {
pf, err := ioutil.ReadFile(policyPath + ".template")
if err != nil {
if os.IsNotExist(err) {
return nil // skip
}
return xerrors.Errorf("loading policy template file: %w", err)
}
tpl := template.Must(template.New("").Funcs(template.FuncMap{
"import": func(v int) string { return versionImports[v] },
}).Parse(string(pf)))
var b bytes.Buffer
err = tpl.Execute(&b, map[string]interface{}{
"versions": versions,
"latestVersion": latestVersion,
})
if err != nil {
return err
}
if err := ioutil.WriteFile(policyPath, b.Bytes(), 0666); err != nil {
return err
}
return nil
}
func generateBuiltin(builtinPath string) error {
bf, err := ioutil.ReadFile(builtinPath + ".template")
if err != nil {
if os.IsNotExist(err) {
return nil // skip
}
return xerrors.Errorf("loading builtin template file: %w", err)
}
tpl := template.Must(template.New("").Funcs(template.FuncMap{
"import": func(v int) string { return versionImports[v] },
}).Parse(string(bf)))
var b bytes.Buffer
err = tpl.Execute(&b, map[string]interface{}{
"versions": versions,
"latestVersion": latestVersion,
})
if err != nil {
return err
}
if err := ioutil.WriteFile(builtinPath, b.Bytes(), 0666); err != nil {
return err
}
return nil
}

View File

@ -12,21 +12,28 @@ import (
"github.com/filecoin-project/lotus/chain/types"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
)
func init() {
builtin.RegisterActorState(builtin0.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
@ -36,14 +43,19 @@ var Methods = builtin4.MethodsAccount
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.AccountActorCodeID:
return load0(store, act.Head)
case builtin2.AccountActorCodeID:
return load2(store, act.Head)
case builtin3.AccountActorCodeID:
return load3(store, act.Head)
case builtin4.AccountActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}

View File

@ -0,0 +1,41 @@
package account
import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}}
var Methods = builtin4.MethodsAccount
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.AccountActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
PubkeyAddress() (address.Address, error)
}

View 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"
account{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/account"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
account{{.v}}.State
store adt.Store
}
func (s *state{{.v}}) PubkeyAddress() (address.Address, error) {
return s.Address, nil
}

View File

@ -6,9 +6,16 @@ import (
"golang.org/x/xerrors"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
@ -16,30 +23,25 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
"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"
smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
proof4 "github.com/filecoin-project/specs-actors/v4/actors/runtime/proof"
)
var SystemActorAddr = builtin0.SystemActorAddr
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
var CronActorAddr = builtin0.CronActorAddr
var SystemActorAddr = builtin4.SystemActorAddr
var BurntFundsActorAddr = builtin4.BurntFundsActorAddr
var CronActorAddr = builtin4.CronActorAddr
var SaftAddress = makeAddress("t0122")
var ReserveAddress = makeAddress("t090")
var RootVerifierAddress = makeAddress("t080")
var (
ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch
ExpectedLeadersPerEpoch = builtin4.ExpectedLeadersPerEpoch
)
const (
EpochDurationSeconds = builtin0.EpochDurationSeconds
EpochsInDay = builtin0.EpochsInDay
SecondsInDay = builtin0.SecondsInDay
EpochDurationSeconds = builtin4.EpochDurationSeconds
EpochsInDay = builtin4.EpochsInDay
SecondsInDay = builtin4.SecondsInDay
)
const (
@ -47,31 +49,38 @@ const (
MethodConstructor = builtin4.MethodConstructor
)
// These are all just type aliases across actor versions 0, 2, & 3. In the future, that might change
// These are all just type aliases across actor versions. In the future, that might change
// and we might need to do something fancier.
type SectorInfo = proof0.SectorInfo
type PoStProof = proof0.PoStProof
type SectorInfo = proof4.SectorInfo
type PoStProof = proof4.PoStProof
type FilterEstimate = smoothing0.FilterEstimate
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
return (FilterEstimate)(v0) //nolint:unconvert
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
return miner4.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
}
// Doesn't change between actors v0, v2, and v3.
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
return (FilterEstimate)(v0) //nolint:unconvert
}
func FromV2FilterEstimate(v2 smoothing2.FilterEstimate) FilterEstimate {
return (FilterEstimate)(v2)
}
func FromV3FilterEstimate(v3 smoothing3.FilterEstimate) FilterEstimate {
return (FilterEstimate)(v3)
}
func FromV4FilterEstimate(v4 smoothing4.FilterEstimate) FilterEstimate {
return (FilterEstimate)(v4)
}
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
@ -92,52 +101,127 @@ func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) {
func ActorNameByCode(c cid.Cid) string {
switch {
case builtin0.IsBuiltinActor(c):
return builtin0.ActorNameByCode(c)
case builtin2.IsBuiltinActor(c):
return builtin2.ActorNameByCode(c)
case builtin3.IsBuiltinActor(c):
return builtin3.ActorNameByCode(c)
case builtin4.IsBuiltinActor(c):
return builtin4.ActorNameByCode(c)
default:
return "<unknown>"
}
}
func IsBuiltinActor(c cid.Cid) bool {
return builtin0.IsBuiltinActor(c) ||
builtin2.IsBuiltinActor(c) ||
builtin3.IsBuiltinActor(c) ||
builtin4.IsBuiltinActor(c)
if builtin0.IsBuiltinActor(c) {
return true
}
if builtin2.IsBuiltinActor(c) {
return true
}
if builtin3.IsBuiltinActor(c) {
return true
}
if builtin4.IsBuiltinActor(c) {
return true
}
return false
}
func IsAccountActor(c cid.Cid) bool {
return c == builtin0.AccountActorCodeID ||
c == builtin2.AccountActorCodeID ||
c == builtin3.AccountActorCodeID ||
c == builtin4.AccountActorCodeID
if c == builtin0.AccountActorCodeID {
return true
}
if c == builtin2.AccountActorCodeID {
return true
}
if c == builtin3.AccountActorCodeID {
return true
}
if c == builtin4.AccountActorCodeID {
return true
}
return false
}
func IsStorageMinerActor(c cid.Cid) bool {
return c == builtin0.StorageMinerActorCodeID ||
c == builtin2.StorageMinerActorCodeID ||
c == builtin3.StorageMinerActorCodeID ||
c == builtin4.StorageMinerActorCodeID
if c == builtin0.StorageMinerActorCodeID {
return true
}
if c == builtin2.StorageMinerActorCodeID {
return true
}
if c == builtin3.StorageMinerActorCodeID {
return true
}
if c == builtin4.StorageMinerActorCodeID {
return true
}
return false
}
func IsMultisigActor(c cid.Cid) bool {
return c == builtin0.MultisigActorCodeID ||
c == builtin2.MultisigActorCodeID ||
c == builtin3.MultisigActorCodeID ||
c == builtin4.MultisigActorCodeID
if c == builtin0.MultisigActorCodeID {
return true
}
if c == builtin2.MultisigActorCodeID {
return true
}
if c == builtin3.MultisigActorCodeID {
return true
}
if c == builtin4.MultisigActorCodeID {
return true
}
return false
}
func IsPaymentChannelActor(c cid.Cid) bool {
return c == builtin0.PaymentChannelActorCodeID ||
c == builtin2.PaymentChannelActorCodeID ||
c == builtin3.PaymentChannelActorCodeID ||
c == builtin4.PaymentChannelActorCodeID
if c == builtin0.PaymentChannelActorCodeID {
return true
}
if c == builtin2.PaymentChannelActorCodeID {
return true
}
if c == builtin3.PaymentChannelActorCodeID {
return true
}
if c == builtin4.PaymentChannelActorCodeID {
return true
}
return false
}
func makeAddress(addr string) address.Address {

View File

@ -0,0 +1,144 @@
package builtin
import (
"github.com/filecoin-project/go-address"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing"
{{end}}
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/types"
miner{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/miner"
proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof"
)
var SystemActorAddr = builtin{{.latestVersion}}.SystemActorAddr
var BurntFundsActorAddr = builtin{{.latestVersion}}.BurntFundsActorAddr
var CronActorAddr = builtin{{.latestVersion}}.CronActorAddr
var SaftAddress = makeAddress("t0122")
var ReserveAddress = makeAddress("t090")
var RootVerifierAddress = makeAddress("t080")
var (
ExpectedLeadersPerEpoch = builtin{{.latestVersion}}.ExpectedLeadersPerEpoch
)
const (
EpochDurationSeconds = builtin{{.latestVersion}}.EpochDurationSeconds
EpochsInDay = builtin{{.latestVersion}}.EpochsInDay
SecondsInDay = builtin{{.latestVersion}}.SecondsInDay
)
const (
MethodSend = builtin{{.latestVersion}}.MethodSend
MethodConstructor = builtin{{.latestVersion}}.MethodConstructor
)
// These are all just type aliases across actor versions. In the future, that might change
// and we might need to do something fancier.
type SectorInfo = proof{{.latestVersion}}.SectorInfo
type PoStProof = proof{{.latestVersion}}.PoStProof
type FilterEstimate = smoothing0.FilterEstimate
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
return miner{{.latestVersion}}.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
}
{{range .versions}}
func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate {
{{if (eq . 0)}}
return (FilterEstimate)(v{{.}}) //nolint:unconvert
{{else}}
return (FilterEstimate)(v{{.}})
{{end}}
}
{{end}}
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
var ActorStateLoaders = make(map[cid.Cid]ActorStateLoader)
func RegisterActorState(code cid.Cid, loader ActorStateLoader) {
ActorStateLoaders[code] = loader
}
func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) {
loader, found := ActorStateLoaders[act.Code]
if !found {
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
return loader(store, act.Head)
}
func ActorNameByCode(c cid.Cid) string {
switch {
{{range .versions}}
case builtin{{.}}.IsBuiltinActor(c):
return builtin{{.}}.ActorNameByCode(c)
{{end}}
default:
return "<unknown>"
}
}
func IsBuiltinActor(c cid.Cid) bool {
{{range .versions}}
if builtin{{.}}.IsBuiltinActor(c) {
return true
}
{{end}}
return false
}
func IsAccountActor(c cid.Cid) bool {
{{range .versions}}
if c == builtin{{.}}.AccountActorCodeID {
return true
}
{{end}}
return false
}
func IsStorageMinerActor(c cid.Cid) bool {
{{range .versions}}
if c == builtin{{.}}.StorageMinerActorCodeID {
return true
}
{{end}}
return false
}
func IsMultisigActor(c cid.Cid) bool {
{{range .versions}}
if c == builtin{{.}}.MultisigActorCodeID {
return true
}
{{end}}
return false
}
func IsPaymentChannelActor(c cid.Cid) bool {
{{range .versions}}
if c == builtin{{.}}.PaymentChannelActorCodeID {
return true
}
{{end}}
return false
}
func makeAddress(addr string) address.Address {
ret, err := address.NewFromString(addr)
if err != nil {
panic(err)
}
return ret
}

View File

@ -0,0 +1,10 @@
package cron
import (
builtin{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin"
)
var (
Address = builtin{{.latestVersion}}.CronActorAddr
Methods = builtin{{.latestVersion}}.MethodsCron
)

View File

@ -0,0 +1,60 @@
package init
import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}}
var (
Address = builtin{{.latestVersion}}.InitActorAddr
Methods = builtin{{.latestVersion}}.MethodsInit
)
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.InitActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
ResolveAddress(address address.Address) (address.Address, bool, error)
MapAddressToNewID(address address.Address) (address.Address, error)
NetworkName() (dtypes.NetworkName, error)
ForEachActor(func(id abi.ActorID, address address.Address) error) error
// Remove exists to support tooling that manipulates state for testing.
// It should not be used in production code, as init actor entries are
// immutable.
Remove(addrs ...address.Address) error
// Sets the network's name. This should only be used on upgrade/fork.
SetNetworkName(name string) error
addressMap() (adt.Map, error)
}

View File

@ -14,21 +14,28 @@ import (
"github.com/filecoin-project/lotus/node/modules/dtypes"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
)
func init() {
builtin.RegisterActorState(builtin0.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
@ -41,14 +48,19 @@ var (
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.InitActorCodeID:
return load0(store, act.Head)
case builtin2.InitActorCodeID:
return load2(store, act.Head)
case builtin3.InitActorCodeID:
return load3(store, act.Head)
case builtin4.InitActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}

View File

@ -0,0 +1,89 @@
package init
import (
"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"
"github.com/filecoin-project/lotus/node/modules/dtypes"
{{if (ge .v 3)}}
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
{{end}}
init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init"
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
init{{.v}}.State
store adt.Store
}
func (s *state{{.v}}) ResolveAddress(address address.Address) (address.Address, bool, error) {
return s.State.ResolveAddress(s.store, address)
}
func (s *state{{.v}}) MapAddressToNewID(address address.Address) (address.Address, error) {
return s.State.MapAddressToNewID(s.store, address)
}
func (s *state{{.v}}) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
addrs, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
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 *state{{.v}}) NetworkName() (dtypes.NetworkName, error) {
return dtypes.NetworkName(s.State.NetworkName), nil
}
func (s *state{{.v}}) SetNetworkName(name string) error {
s.State.NetworkName = name
return nil
}
func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) {
m, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
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 *state{{.v}}) addressMap() (adt.Map, error) {
return adt{{.v}}.AsMap(s.store, s.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
}

View File

@ -3,7 +3,6 @@ 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"
@ -11,6 +10,8 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/node/modules/dtypes"
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
init3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/init"
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
)

View File

@ -3,7 +3,6 @@ package init
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
@ -11,6 +10,8 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/node/modules/dtypes"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
init4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/init"
adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
)

View File

@ -0,0 +1,159 @@
package market
import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}}
var (
Address = builtin{{.latestVersion}}.StorageMarketActorAddr
Methods = builtin{{.latestVersion}}.MethodsMarket
)
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.StorageMarketActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
BalancesChanged(State) (bool, error)
EscrowTable() (BalanceTable, error)
LockedTable() (BalanceTable, error)
TotalLocked() (abi.TokenAmount, error)
StatesChanged(State) (bool, error)
States() (DealStates, error)
ProposalsChanged(State) (bool, error)
Proposals() (DealProposals, error)
VerifyDealsForActivation(
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
) (weight, verifiedWeight abi.DealWeight, err error)
NextID() (abi.DealID, error)
}
type BalanceTable interface {
ForEach(cb func(address.Address, abi.TokenAmount) error) error
Get(key address.Address) (abi.TokenAmount, error)
}
type DealStates interface {
ForEach(cb func(id abi.DealID, ds DealState) error) error
Get(id abi.DealID) (*DealState, bool, error)
array() adt.Array
decode(*cbg.Deferred) (*DealState, error)
}
type DealProposals interface {
ForEach(cb func(id abi.DealID, dp DealProposal) error) error
Get(id abi.DealID) (*DealProposal, bool, error)
array() adt.Array
decode(*cbg.Deferred) (*DealProposal, error)
}
type PublishStorageDealsParams = market0.PublishStorageDealsParams
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
type WithdrawBalanceParams = market0.WithdrawBalanceParams
type ClientDealProposal = market0.ClientDealProposal
type DealState struct {
SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector
LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated
SlashEpoch abi.ChainEpoch // -1 if deal never slashed
}
type DealProposal struct {
PieceCID cid.Cid
PieceSize abi.PaddedPieceSize
VerifiedDeal bool
Client address.Address
Provider address.Address
Label string
StartEpoch abi.ChainEpoch
EndEpoch abi.ChainEpoch
StoragePricePerEpoch abi.TokenAmount
ProviderCollateral abi.TokenAmount
ClientCollateral abi.TokenAmount
}
type DealStateChanges struct {
Added []DealIDState
Modified []DealStateChange
Removed []DealIDState
}
type DealIDState struct {
ID abi.DealID
Deal DealState
}
// DealStateChange is a change in deal state from -> to
type DealStateChange struct {
ID abi.DealID
From *DealState
To *DealState
}
type DealProposalChanges struct {
Added []ProposalIDState
Removed []ProposalIDState
}
type ProposalIDState struct {
ID abi.DealID
Proposal DealProposal
}
func EmptyDealState() *DealState {
return &DealState{
SectorStartEpoch: -1,
SlashEpoch: -1,
LastUpdatedEpoch: -1,
}
}
// returns the earned fees and pending fees for a given deal
func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) {
tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch)))
ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch)))
if ef.LessThan(big.Zero()) {
ef = big.Zero()
}
if ef.GreaterThan(tf) {
ef = tf
}
return ef, big.Sub(tf, ef)
}

View File

@ -1,19 +1,23 @@
package market
import (
"github.com/filecoin-project/go-state-types/big"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/adt"
@ -22,15 +26,19 @@ import (
)
func init() {
builtin.RegisterActorState(builtin0.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
@ -41,16 +49,21 @@ var (
Methods = builtin4.MethodsMarket
)
func Load(store adt.Store, act *types.Actor) (st State, err error) {
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.StorageMarketActorCodeID:
return load0(store, act.Head)
case builtin2.StorageMarketActorCodeID:
return load2(store, act.Head)
case builtin3.StorageMarketActorCodeID:
return load3(store, act.Head)
case builtin4.StorageMarketActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}

View File

@ -0,0 +1,209 @@
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"
market{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/market"
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
market{{.v}}.State
store adt.Store
}
func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) {
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
fml = types.BigAdd(fml, s.TotalClientStorageFee)
return fml, nil
}
func (s *state{{.v}}) BalancesChanged(otherState State) (bool, error) {
otherState{{.v}}, ok := otherState.(*state{{.v}})
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(otherState{{.v}}.State.EscrowTable) || !s.State.LockedTable.Equals(otherState{{.v}}.State.LockedTable), nil
}
func (s *state{{.v}}) StatesChanged(otherState State) (bool, error) {
otherState{{.v}}, ok := otherState.(*state{{.v}})
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(otherState{{.v}}.State.States), nil
}
func (s *state{{.v}}) States() (DealStates, error) {
stateArray, err := adt{{.v}}.AsArray(s.store, s.State.States{{if (ge .v 3)}}, market{{.v}}.StatesAmtBitwidth{{end}})
if err != nil {
return nil, err
}
return &dealStates{{.v}}{stateArray}, nil
}
func (s *state{{.v}}) ProposalsChanged(otherState State) (bool, error) {
otherState{{.v}}, ok := otherState.(*state{{.v}})
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(otherState{{.v}}.State.Proposals), nil
}
func (s *state{{.v}}) Proposals() (DealProposals, error) {
proposalArray, err := adt{{.v}}.AsArray(s.store, s.State.Proposals{{if (ge .v 3)}}, market{{.v}}.ProposalsAmtBitwidth{{end}})
if err != nil {
return nil, err
}
return &dealProposals{{.v}}{proposalArray}, nil
}
func (s *state{{.v}}) EscrowTable() (BalanceTable, error) {
bt, err := adt{{.v}}.AsBalanceTable(s.store, s.State.EscrowTable)
if err != nil {
return nil, err
}
return &balanceTable{{.v}}{bt}, nil
}
func (s *state{{.v}}) LockedTable() (BalanceTable, error) {
bt, err := adt{{.v}}.AsBalanceTable(s.store, s.State.LockedTable)
if err != nil {
return nil, err
}
return &balanceTable{{.v}}{bt}, nil
}
func (s *state{{.v}}) VerifyDealsForActivation(
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
) (weight, verifiedWeight abi.DealWeight, err error) {
w, vw{{if (ge .v 2)}}, _{{end}}, err := market{{.v}}.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
return w, vw, err
}
func (s *state{{.v}}) NextID() (abi.DealID, error) {
return s.State.NextID, nil
}
type balanceTable{{.v}} struct {
*adt{{.v}}.BalanceTable
}
func (bt *balanceTable{{.v}}) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
asMap := (*adt{{.v}}.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 dealStates{{.v}} struct {
adt.Array
}
func (s *dealStates{{.v}}) Get(dealID abi.DealID) (*DealState, bool, error) {
var deal{{.v}} market{{.v}}.DealState
found, err := s.Array.Get(uint64(dealID), &deal{{.v}})
if err != nil {
return nil, false, err
}
if !found {
return nil, false, nil
}
deal := fromV{{.v}}DealState(deal{{.v}})
return &deal, true, nil
}
func (s *dealStates{{.v}}) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
var ds{{.v}} market{{.v}}.DealState
return s.Array.ForEach(&ds{{.v}}, func(idx int64) error {
return cb(abi.DealID(idx), fromV{{.v}}DealState(ds{{.v}}))
})
}
func (s *dealStates{{.v}}) decode(val *cbg.Deferred) (*DealState, error) {
var ds{{.v}} market{{.v}}.DealState
if err := ds{{.v}}.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
ds := fromV{{.v}}DealState(ds{{.v}})
return &ds, nil
}
func (s *dealStates{{.v}}) array() adt.Array {
return s.Array
}
func fromV{{.v}}DealState(v{{.v}} market{{.v}}.DealState) DealState {
return (DealState)(v{{.v}})
}
type dealProposals{{.v}} struct {
adt.Array
}
func (s *dealProposals{{.v}}) Get(dealID abi.DealID) (*DealProposal, bool, error) {
var proposal{{.v}} market{{.v}}.DealProposal
found, err := s.Array.Get(uint64(dealID), &proposal{{.v}})
if err != nil {
return nil, false, err
}
if !found {
return nil, false, nil
}
proposal := fromV{{.v}}DealProposal(proposal{{.v}})
return &proposal, true, nil
}
func (s *dealProposals{{.v}}) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
var dp{{.v}} market{{.v}}.DealProposal
return s.Array.ForEach(&dp{{.v}}, func(idx int64) error {
return cb(abi.DealID(idx), fromV{{.v}}DealProposal(dp{{.v}}))
})
}
func (s *dealProposals{{.v}}) decode(val *cbg.Deferred) (*DealProposal, error) {
var dp{{.v}} market{{.v}}.DealProposal
if err := dp{{.v}}.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
dp := fromV{{.v}}DealProposal(dp{{.v}})
return &dp, nil
}
func (s *dealProposals{{.v}}) array() adt.Array {
return s.Array
}
func fromV{{.v}}DealProposal(v{{.v}} market{{.v}}.DealProposal) DealProposal {
return (DealProposal)(v{{.v}})
}

View File

@ -102,7 +102,8 @@ func (s *state0) LockedTable() (BalanceTable, error) {
func (s *state0) VerifyDealsForActivation(
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
) (weight, verifiedWeight abi.DealWeight, err error) {
return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
w, vw, err := market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
return w, vw, err
}
func (s *state0) NextID() (abi.DealID, error) {

View File

@ -144,18 +144,18 @@ func (s *dealStates2) Get(dealID abi.DealID) (*DealState, bool, error) {
}
func (s *dealStates2) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
var ds1 market2.DealState
return s.Array.ForEach(&ds1, func(idx int64) error {
return cb(abi.DealID(idx), fromV2DealState(ds1))
var ds2 market2.DealState
return s.Array.ForEach(&ds2, func(idx int64) error {
return cb(abi.DealID(idx), fromV2DealState(ds2))
})
}
func (s *dealStates2) decode(val *cbg.Deferred) (*DealState, error) {
var ds1 market2.DealState
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
var ds2 market2.DealState
if err := ds2.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
ds := fromV2DealState(ds1)
ds := fromV2DealState(ds2)
return &ds, nil
}
@ -163,8 +163,8 @@ func (s *dealStates2) array() adt.Array {
return s.Array
}
func fromV2DealState(v1 market2.DealState) DealState {
return (DealState)(v1)
func fromV2DealState(v2 market2.DealState) DealState {
return (DealState)(v2)
}
type dealProposals2 struct {
@ -185,18 +185,18 @@ func (s *dealProposals2) Get(dealID abi.DealID) (*DealProposal, bool, error) {
}
func (s *dealProposals2) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
var dp1 market2.DealProposal
return s.Array.ForEach(&dp1, func(idx int64) error {
return cb(abi.DealID(idx), fromV2DealProposal(dp1))
var dp2 market2.DealProposal
return s.Array.ForEach(&dp2, func(idx int64) error {
return cb(abi.DealID(idx), fromV2DealProposal(dp2))
})
}
func (s *dealProposals2) decode(val *cbg.Deferred) (*DealProposal, error) {
var dp1 market2.DealProposal
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
var dp2 market2.DealProposal
if err := dp2.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
dp := fromV2DealProposal(dp1)
dp := fromV2DealProposal(dp2)
return &dp, nil
}
@ -204,6 +204,6 @@ func (s *dealProposals2) array() adt.Array {
return s.Array
}
func fromV2DealProposal(v1 market2.DealProposal) DealProposal {
return (DealProposal)(v1)
func fromV2DealProposal(v2 market2.DealProposal) DealProposal {
return (DealProposal)(v2)
}

View File

@ -38,23 +38,23 @@ func (s *state3) TotalLocked() (abi.TokenAmount, error) {
}
func (s *state3) BalancesChanged(otherState State) (bool, error) {
otherState2, ok := otherState.(*state3)
otherState3, 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
return !s.State.EscrowTable.Equals(otherState3.State.EscrowTable) || !s.State.LockedTable.Equals(otherState3.State.LockedTable), nil
}
func (s *state3) StatesChanged(otherState State) (bool, error) {
otherState2, ok := otherState.(*state3)
otherState3, 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
return !s.State.States.Equals(otherState3.State.States), nil
}
func (s *state3) States() (DealStates, error) {
@ -66,13 +66,13 @@ func (s *state3) States() (DealStates, error) {
}
func (s *state3) ProposalsChanged(otherState State) (bool, error) {
otherState2, ok := otherState.(*state3)
otherState3, 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
return !s.State.Proposals.Equals(otherState3.State.Proposals), nil
}
func (s *state3) Proposals() (DealProposals, error) {
@ -131,31 +131,31 @@ type dealStates3 struct {
}
func (s *dealStates3) Get(dealID abi.DealID) (*DealState, bool, error) {
var deal2 market3.DealState
found, err := s.Array.Get(uint64(dealID), &deal2)
var deal3 market3.DealState
found, err := s.Array.Get(uint64(dealID), &deal3)
if err != nil {
return nil, false, err
}
if !found {
return nil, false, nil
}
deal := fromV3DealState(deal2)
deal := fromV3DealState(deal3)
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))
var ds3 market3.DealState
return s.Array.ForEach(&ds3, func(idx int64) error {
return cb(abi.DealID(idx), fromV3DealState(ds3))
})
}
func (s *dealStates3) decode(val *cbg.Deferred) (*DealState, error) {
var ds1 market3.DealState
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
var ds3 market3.DealState
if err := ds3.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
ds := fromV3DealState(ds1)
ds := fromV3DealState(ds3)
return &ds, nil
}
@ -163,8 +163,8 @@ func (s *dealStates3) array() adt.Array {
return s.Array
}
func fromV3DealState(v1 market3.DealState) DealState {
return (DealState)(v1)
func fromV3DealState(v3 market3.DealState) DealState {
return (DealState)(v3)
}
type dealProposals3 struct {
@ -172,31 +172,31 @@ type dealProposals3 struct {
}
func (s *dealProposals3) Get(dealID abi.DealID) (*DealProposal, bool, error) {
var proposal2 market3.DealProposal
found, err := s.Array.Get(uint64(dealID), &proposal2)
var proposal3 market3.DealProposal
found, err := s.Array.Get(uint64(dealID), &proposal3)
if err != nil {
return nil, false, err
}
if !found {
return nil, false, nil
}
proposal := fromV3DealProposal(proposal2)
proposal := fromV3DealProposal(proposal3)
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))
var dp3 market3.DealProposal
return s.Array.ForEach(&dp3, func(idx int64) error {
return cb(abi.DealID(idx), fromV3DealProposal(dp3))
})
}
func (s *dealProposals3) decode(val *cbg.Deferred) (*DealProposal, error) {
var dp1 market3.DealProposal
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
var dp3 market3.DealProposal
if err := dp3.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
dp := fromV3DealProposal(dp1)
dp := fromV3DealProposal(dp3)
return &dp, nil
}
@ -204,6 +204,6 @@ func (s *dealProposals3) array() adt.Array {
return s.Array
}
func fromV3DealProposal(v1 market3.DealProposal) DealProposal {
return (DealProposal)(v1)
func fromV3DealProposal(v3 market3.DealProposal) DealProposal {
return (DealProposal)(v3)
}

View File

@ -38,23 +38,23 @@ func (s *state4) TotalLocked() (abi.TokenAmount, error) {
}
func (s *state4) BalancesChanged(otherState State) (bool, error) {
otherState2, ok := otherState.(*state4)
otherState4, ok := otherState.(*state4)
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
return !s.State.EscrowTable.Equals(otherState4.State.EscrowTable) || !s.State.LockedTable.Equals(otherState4.State.LockedTable), nil
}
func (s *state4) StatesChanged(otherState State) (bool, error) {
otherState2, ok := otherState.(*state4)
otherState4, ok := otherState.(*state4)
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
return !s.State.States.Equals(otherState4.State.States), nil
}
func (s *state4) States() (DealStates, error) {
@ -66,13 +66,13 @@ func (s *state4) States() (DealStates, error) {
}
func (s *state4) ProposalsChanged(otherState State) (bool, error) {
otherState2, ok := otherState.(*state4)
otherState4, ok := otherState.(*state4)
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
return !s.State.Proposals.Equals(otherState4.State.Proposals), nil
}
func (s *state4) Proposals() (DealProposals, error) {
@ -131,31 +131,31 @@ type dealStates4 struct {
}
func (s *dealStates4) Get(dealID abi.DealID) (*DealState, bool, error) {
var deal2 market4.DealState
found, err := s.Array.Get(uint64(dealID), &deal2)
var deal4 market4.DealState
found, err := s.Array.Get(uint64(dealID), &deal4)
if err != nil {
return nil, false, err
}
if !found {
return nil, false, nil
}
deal := fromV4DealState(deal2)
deal := fromV4DealState(deal4)
return &deal, true, nil
}
func (s *dealStates4) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
var ds1 market4.DealState
return s.Array.ForEach(&ds1, func(idx int64) error {
return cb(abi.DealID(idx), fromV4DealState(ds1))
var ds4 market4.DealState
return s.Array.ForEach(&ds4, func(idx int64) error {
return cb(abi.DealID(idx), fromV4DealState(ds4))
})
}
func (s *dealStates4) decode(val *cbg.Deferred) (*DealState, error) {
var ds1 market4.DealState
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
var ds4 market4.DealState
if err := ds4.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
ds := fromV4DealState(ds1)
ds := fromV4DealState(ds4)
return &ds, nil
}
@ -172,31 +172,31 @@ type dealProposals4 struct {
}
func (s *dealProposals4) Get(dealID abi.DealID) (*DealProposal, bool, error) {
var proposal2 market4.DealProposal
found, err := s.Array.Get(uint64(dealID), &proposal2)
var proposal4 market4.DealProposal
found, err := s.Array.Get(uint64(dealID), &proposal4)
if err != nil {
return nil, false, err
}
if !found {
return nil, false, nil
}
proposal := fromV4DealProposal(proposal2)
proposal := fromV4DealProposal(proposal4)
return &proposal, true, nil
}
func (s *dealProposals4) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
var dp1 market4.DealProposal
return s.Array.ForEach(&dp1, func(idx int64) error {
return cb(abi.DealID(idx), fromV4DealProposal(dp1))
var dp4 market4.DealProposal
return s.Array.ForEach(&dp4, func(idx int64) error {
return cb(abi.DealID(idx), fromV4DealProposal(dp4))
})
}
func (s *dealProposals4) decode(val *cbg.Deferred) (*DealProposal, error) {
var dp1 market4.DealProposal
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
var dp4 market4.DealProposal
if err := dp4.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return nil, err
}
dp := fromV4DealProposal(dp1)
dp := fromV4DealProposal(dp4)
return &dp, nil
}

View File

@ -0,0 +1,270 @@
package miner
import (
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/network"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/go-state-types/dline"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}
}
var Methods = builtin{{.latestVersion}}.MethodsMiner
// Unchanged between v0, v2, v3, and v4 actors
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
var WPoStChallengeLookback = miner0.WPoStChallengeLookback
var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff
const MinSectorExpiration = miner0.MinSectorExpiration
// Not used / checked in v0
// TODO: Abstract over network versions
var DeclarationsMax = miner2.DeclarationsMax
var AddressedSectorsMax = miner2.AddressedSectorsMax
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.StorageMinerActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
// Total available balance to spend.
AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error)
// Funds that will vest by the given epoch.
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
// Funds locked for various reasons.
LockedFunds() (LockedFunds, error)
FeeDebt() (abi.TokenAmount, error)
GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
FindSector(abi.SectorNumber) (*SectorLocation, error)
GetSectorExpiration(abi.SectorNumber) (*SectorExpiration, error)
GetPrecommittedSector(abi.SectorNumber) (*SectorPreCommitOnChainInfo, error)
LoadSectors(sectorNos *bitfield.BitField) ([]*SectorOnChainInfo, error)
NumLiveSectors() (uint64, error)
IsAllocated(abi.SectorNumber) (bool, error)
LoadDeadline(idx uint64) (Deadline, error)
ForEachDeadline(cb func(idx uint64, dl Deadline) error) error
NumDeadlines() (uint64, error)
DeadlinesChanged(State) (bool, error)
Info() (MinerInfo, error)
MinerInfoChanged(State) (bool, error)
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
DeadlineCronActive() (bool, error)
// Diff helpers. Used by Diff* functions internally.
sectors() (adt.Array, error)
decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error)
precommits() (adt.Map, error)
decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error)
}
type Deadline interface {
LoadPartition(idx uint64) (Partition, error)
ForEachPartition(cb func(idx uint64, part Partition) error) error
PartitionsPoSted() (bitfield.BitField, error)
PartitionsChanged(Deadline) (bool, error)
DisputableProofCount() (uint64, error)
}
type Partition interface {
AllSectors() (bitfield.BitField, error)
FaultySectors() (bitfield.BitField, error)
RecoveringSectors() (bitfield.BitField, error)
LiveSectors() (bitfield.BitField, error)
ActiveSectors() (bitfield.BitField, error)
}
type SectorOnChainInfo struct {
SectorNumber abi.SectorNumber
SealProof abi.RegisteredSealProof
SealedCID cid.Cid
DealIDs []abi.DealID
Activation abi.ChainEpoch
Expiration abi.ChainEpoch
DealWeight abi.DealWeight
VerifiedDealWeight abi.DealWeight
InitialPledge abi.TokenAmount
ExpectedDayReward abi.TokenAmount
ExpectedStoragePledge abi.TokenAmount
}
type SectorPreCommitInfo = miner0.SectorPreCommitInfo
type SectorPreCommitOnChainInfo struct {
Info SectorPreCommitInfo
PreCommitDeposit abi.TokenAmount
PreCommitEpoch abi.ChainEpoch
DealWeight abi.DealWeight
VerifiedDealWeight abi.DealWeight
}
type PoStPartition = miner0.PoStPartition
type RecoveryDeclaration = miner0.RecoveryDeclaration
type FaultDeclaration = miner0.FaultDeclaration
// Params
type DeclareFaultsParams = miner0.DeclareFaultsParams
type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams
type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams
type ProveCommitSectorParams = miner0.ProveCommitSectorParams
type 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 {
Owner address.Address // Must be an ID-address.
Worker address.Address // Must be an ID-address.
NewWorker address.Address // Must be an ID-address.
ControlAddresses []address.Address // Must be an ID-addresses.
WorkerChangeEpoch abi.ChainEpoch
PeerId *peer.ID
Multiaddrs []abi.Multiaddrs
WindowPoStProofType abi.RegisteredPoStProof
SectorSize abi.SectorSize
WindowPoStPartitionSectors uint64
ConsensusFaultElapsed abi.ChainEpoch
}
func (mi MinerInfo) IsController(addr address.Address) bool {
if addr == mi.Owner || addr == mi.Worker {
return true
}
for _, ca := range mi.ControlAddresses {
if addr == ca {
return true
}
}
return false
}
type SectorExpiration struct {
OnTime abi.ChainEpoch
// non-zero if sector is faulty, epoch at which it will be permanently
// removed if it doesn't recover
Early abi.ChainEpoch
}
type SectorLocation struct {
Deadline uint64
Partition uint64
}
type SectorChanges struct {
Added []SectorOnChainInfo
Extended []SectorExtensions
Removed []SectorOnChainInfo
}
type SectorExtensions struct {
From SectorOnChainInfo
To SectorOnChainInfo
}
type PreCommitChanges struct {
Added []SectorPreCommitOnChainInfo
Removed []SectorPreCommitOnChainInfo
}
type LockedFunds struct {
VestingFunds abi.TokenAmount
InitialPledgeRequirement abi.TokenAmount
PreCommitDeposits abi.TokenAmount
}
func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount {
return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits))
}

View File

@ -18,28 +18,37 @@ import (
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
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"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
)
func init() {
builtin.RegisterActorState(builtin0.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
}
var Methods = builtin4.MethodsMiner
@ -58,16 +67,21 @@ const MinSectorExpiration = miner0.MinSectorExpiration
var DeclarationsMax = miner2.DeclarationsMax
var AddressedSectorsMax = miner2.AddressedSectorsMax
func Load(store adt.Store, act *types.Actor) (st State, err error) {
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.StorageMinerActorCodeID:
return load0(store, act.Head)
case builtin2.StorageMinerActorCodeID:
return load2(store, act.Head)
case builtin3.StorageMinerActorCodeID:
return load3(store, act.Head)
case builtin4.StorageMinerActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}

View File

@ -0,0 +1,460 @@
package miner
import (
"bytes"
"errors"
{{if (le .v 1)}}
"github.com/filecoin-project/go-state-types/big"
{{end}}
"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"
{{if (ge .v 3)}}
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
{{end}}
miner{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/miner"
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
miner{{.v}}.State
store adt.Store
}
type deadline{{.v}} struct {
miner{{.v}}.Deadline
store adt.Store
}
type partition{{.v}} struct {
miner{{.v}}.Partition
store adt.Store
}
func (s *state{{.v}}) 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{{if (ge .v 2)}}, err{{end}} = s.GetAvailableBalance(bal)
return available, err
}
func (s *state{{.v}}) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
return s.CheckVestedFunds(s.store, epoch)
}
func (s *state{{.v}}) LockedFunds() (LockedFunds, error) {
return LockedFunds{
VestingFunds: s.State.LockedFunds,
InitialPledgeRequirement: s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}},
PreCommitDeposits: s.State.PreCommitDeposits,
}, nil
}
func (s *state{{.v}}) FeeDebt() (abi.TokenAmount, error) {
return {{if (ge .v 2)}}s.State.FeeDebt{{else}}big.Zero(){{end}}, nil
}
func (s *state{{.v}}) InitialPledge() (abi.TokenAmount, error) {
return s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}}, nil
}
func (s *state{{.v}}) PreCommitDeposits() (abi.TokenAmount, error) {
return s.State.PreCommitDeposits, nil
}
func (s *state{{.v}}) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
info, ok, err := s.State.GetSector(s.store, num)
if !ok || err != nil {
return nil, err
}
ret := fromV{{.v}}SectorOnChainInfo(*info)
return &ret, nil
}
func (s *state{{.v}}) 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 *state{{.v}}) 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 *miner{{.v}}.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 *state{{.v}}) 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 *miner{{.v}}.Deadline) error {
partitions, err := dl.PartitionsArray(s.store)
if err != nil {
return err
}
quant := s.State.QuantSpecForDeadline(dlIdx)
var part miner{{.v}}.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 := miner{{.v}}.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant{{if (ge .v 3)}}, miner{{.v}}.PartitionExpirationAmtBitwidth{{end}})
if err != nil {
return err
}
var exp miner{{.v}}.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 *state{{.v}}) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
if !ok || err != nil {
return nil, err
}
ret := fromV{{.v}}SectorPreCommitOnChainInfo(*info)
return &ret, nil
}
func (s *state{{.v}}) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
sectors, err := miner{{.v}}.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 info{{.v}} miner{{.v}}.SectorOnChainInfo
if err := sectors.ForEach(&info{{.v}}, func(_ int64) error {
info := fromV{{.v}}SectorOnChainInfo(info{{.v}})
infos = append(infos, &info)
return nil
}); err != nil {
return nil, err
}
return infos, nil
}
// Otherwise, load selected.
infos{{.v}}, err := sectors.Load(*snos)
if err != nil {
return nil, err
}
infos := make([]*SectorOnChainInfo, len(infos{{.v}}))
for i, info{{.v}} := range infos{{.v}} {
info := fromV{{.v}}SectorOnChainInfo(*info{{.v}})
infos[i] = &info
}
return infos, nil
}
func (s *state{{.v}}) 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 *state{{.v}}) 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 &deadline{{.v}}{*dl, s.store}, nil
}
func (s *state{{.v}}) 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 *miner{{.v}}.Deadline) error {
return cb(i, &deadline{{.v}}{*dl, s.store})
})
}
func (s *state{{.v}}) NumDeadlines() (uint64, error) {
return miner{{.v}}.WPoStPeriodDeadlines, nil
}
func (s *state{{.v}}) DeadlinesChanged(other State) (bool, error) {
other{{.v}}, ok := other.(*state{{.v}})
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Deadlines.Equals(other{{.v}}.Deadlines), nil
}
func (s *state{{.v}}) MinerInfoChanged(other State) (bool, error) {
other0, ok := other.(*state{{.v}})
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Info.Equals(other0.State.Info), nil
}
func (s *state{{.v}}) 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
}
{{if (le .v 2)}}
wpp, err := info.SealProofType.RegisteredWindowPoStProof()
if err != nil {
return MinerInfo{}, err
}
{{end}}
mi := MinerInfo{
Owner: info.Owner,
Worker: info.Worker,
ControlAddresses: info.ControlAddresses,
NewWorker: address.Undef,
WorkerChangeEpoch: -1,
PeerId: pid,
Multiaddrs: info.Multiaddrs,
WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}},
SectorSize: info.SectorSize,
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}},
}
if info.PendingWorkerKey != nil {
mi.NewWorker = info.PendingWorkerKey.NewWorker
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
}
return mi, nil
}
func (s *state{{.v}}) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
return s.State.{{if (ge .v 4)}}Recorded{{end}}DeadlineInfo(epoch), nil
}
func (s *state{{.v}}) DeadlineCronActive() (bool, error) {
return {{if (ge .v 4)}}s.State.DeadlineCronActive{{else}}true{{end}}, nil{{if (lt .v 4)}} // always active in this version{{end}}
}
func (s *state{{.v}}) sectors() (adt.Array, error) {
return adt{{.v}}.AsArray(s.store, s.Sectors{{if (ge .v 3)}}, miner{{.v}}.SectorsAmtBitwidth{{end}})
}
func (s *state{{.v}}) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
var si miner{{.v}}.SectorOnChainInfo
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return SectorOnChainInfo{}, err
}
return fromV{{.v}}SectorOnChainInfo(si), nil
}
func (s *state{{.v}}) precommits() (adt.Map, error) {
return adt{{.v}}.AsMap(s.store, s.PreCommittedSectors{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
}
func (s *state{{.v}}) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
var sp miner{{.v}}.SectorPreCommitOnChainInfo
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return SectorPreCommitOnChainInfo{}, err
}
return fromV{{.v}}SectorPreCommitOnChainInfo(sp), nil
}
func (d *deadline{{.v}}) LoadPartition(idx uint64) (Partition, error) {
p, err := d.Deadline.LoadPartition(d.store, idx)
if err != nil {
return nil, err
}
return &partition{{.v}}{*p, d.store}, nil
}
func (d *deadline{{.v}}) ForEachPartition(cb func(uint64, Partition) error) error {
ps, err := d.Deadline.PartitionsArray(d.store)
if err != nil {
return err
}
var part miner{{.v}}.Partition
return ps.ForEach(&part, func(i int64) error {
return cb(uint64(i), &partition{{.v}}{part, d.store})
})
}
func (d *deadline{{.v}}) PartitionsChanged(other Deadline) (bool, error) {
other{{.v}}, ok := other.(*deadline{{.v}})
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !d.Deadline.Partitions.Equals(other{{.v}}.Deadline.Partitions), nil
}
func (d *deadline{{.v}}) PartitionsPoSted() (bitfield.BitField, error) {
return d.Deadline.{{if (ge .v 3)}}PartitionsPoSted{{else}}PostSubmissions{{end}}, nil
}
func (d *deadline{{.v}}) DisputableProofCount() (uint64, error) {
{{if (ge .v 3)}}
ops, err := d.OptimisticProofsSnapshotArray(d.store)
if err != nil {
return 0, err
}
return ops.Length(), nil
{{else}}
// field doesn't exist until v3
return 0, nil
{{end}}
}
func (p *partition{{.v}}) AllSectors() (bitfield.BitField, error) {
return p.Partition.Sectors, nil
}
func (p *partition{{.v}}) FaultySectors() (bitfield.BitField, error) {
return p.Partition.Faults, nil
}
func (p *partition{{.v}}) RecoveringSectors() (bitfield.BitField, error) {
return p.Partition.Recoveries, nil
}
func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorOnChainInfo {
{{if (ge .v 2)}}
return SectorOnChainInfo{
SectorNumber: v{{.v}}.SectorNumber,
SealProof: v{{.v}}.SealProof,
SealedCID: v{{.v}}.SealedCID,
DealIDs: v{{.v}}.DealIDs,
Activation: v{{.v}}.Activation,
Expiration: v{{.v}}.Expiration,
DealWeight: v{{.v}}.DealWeight,
VerifiedDealWeight: v{{.v}}.VerifiedDealWeight,
InitialPledge: v{{.v}}.InitialPledge,
ExpectedDayReward: v{{.v}}.ExpectedDayReward,
ExpectedStoragePledge: v{{.v}}.ExpectedStoragePledge,
}
{{else}}
return (SectorOnChainInfo)(v0)
{{end}}
}
func fromV{{.v}}SectorPreCommitOnChainInfo(v{{.v}} miner{{.v}}.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
{{if (ge .v 2)}}
return SectorPreCommitOnChainInfo{
Info: (SectorPreCommitInfo)(v{{.v}}.Info),
PreCommitDeposit: v{{.v}}.PreCommitDeposit,
PreCommitEpoch: v{{.v}}.PreCommitEpoch,
DealWeight: v{{.v}}.DealWeight,
VerifiedDealWeight: v{{.v}}.VerifiedDealWeight,
}
{{else}}
return (SectorPreCommitOnChainInfo)(v0)
{{end}}
}

View File

@ -196,6 +196,7 @@ func (s *state0) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOn
}
ret := fromV0SectorPreCommitOnChainInfo(*info)
return &ret, nil
}
@ -396,8 +397,10 @@ func (d *deadline0) PartitionsPoSted() (bitfield.BitField, error) {
}
func (d *deadline0) DisputableProofCount() (uint64, error) {
// field doesn't exist until v3
return 0, nil
}
func (p *partition0) AllSectors() (bitfield.BitField, error) {
@ -413,9 +416,13 @@ func (p *partition0) RecoveringSectors() (bitfield.BitField, error) {
}
func fromV0SectorOnChainInfo(v0 miner0.SectorOnChainInfo) SectorOnChainInfo {
return (SectorOnChainInfo)(v0)
}
func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
return (SectorPreCommitOnChainInfo)(v0)
}

View File

@ -395,8 +395,10 @@ func (d *deadline2) PartitionsPoSted() (bitfield.BitField, error) {
}
func (d *deadline2) DisputableProofCount() (uint64, error) {
// field doesn't exist until v3
return 0, nil
}
func (p *partition2) AllSectors() (bitfield.BitField, error) {
@ -412,6 +414,7 @@ func (p *partition2) RecoveringSectors() (bitfield.BitField, error) {
}
func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo {
return SectorOnChainInfo{
SectorNumber: v2.SectorNumber,
SealProof: v2.SealProof,
@ -425,9 +428,11 @@ func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo {
ExpectedDayReward: v2.ExpectedDayReward,
ExpectedStoragePledge: v2.ExpectedStoragePledge,
}
}
func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
return SectorPreCommitOnChainInfo{
Info: (SectorPreCommitInfo)(v2.Info),
PreCommitDeposit: v2.PreCommitDeposit,
@ -435,4 +440,5 @@ func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) Sect
DealWeight: v2.DealWeight,
VerifiedDealWeight: v2.VerifiedDealWeight,
}
}

View File

@ -16,6 +16,7 @@ import (
"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"
)
@ -208,9 +209,9 @@ func (s *state3) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, 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)
var info3 miner3.SectorOnChainInfo
if err := sectors.ForEach(&info3, func(_ int64) error {
info := fromV3SectorOnChainInfo(info3)
infos = append(infos, &info)
return nil
}); err != nil {
@ -220,13 +221,13 @@ func (s *state3) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err
}
// Otherwise, load selected.
infos2, err := sectors.Load(*snos)
infos3, err := sectors.Load(*snos)
if err != nil {
return nil, err
}
infos := make([]*SectorOnChainInfo, len(infos2))
for i, info2 := range infos2 {
info := fromV3SectorOnChainInfo(*info2)
infos := make([]*SectorOnChainInfo, len(infos3))
for i, info3 := range infos3 {
info := fromV3SectorOnChainInfo(*info3)
infos[i] = &info
}
return infos, nil
@ -268,13 +269,13 @@ func (s *state3) NumDeadlines() (uint64, error) {
}
func (s *state3) DeadlinesChanged(other State) (bool, error) {
other2, ok := other.(*state3)
other3, ok := other.(*state3)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Deadlines.Equals(other2.Deadlines), nil
return !s.State.Deadlines.Equals(other3.Deadlines), nil
}
func (s *state3) MinerInfoChanged(other State) (bool, error) {
@ -377,13 +378,13 @@ func (d *deadline3) ForEachPartition(cb func(uint64, Partition) error) error {
}
func (d *deadline3) PartitionsChanged(other Deadline) (bool, error) {
other2, ok := other.(*deadline3)
other3, ok := other.(*deadline3)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
return !d.Deadline.Partitions.Equals(other3.Deadline.Partitions), nil
}
func (d *deadline3) PartitionsPoSted() (bitfield.BitField, error) {
@ -391,12 +392,14 @@ func (d *deadline3) PartitionsPoSted() (bitfield.BitField, error) {
}
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) {
@ -412,6 +415,7 @@ func (p *partition3) RecoveringSectors() (bitfield.BitField, error) {
}
func fromV3SectorOnChainInfo(v3 miner3.SectorOnChainInfo) SectorOnChainInfo {
return SectorOnChainInfo{
SectorNumber: v3.SectorNumber,
SealProof: v3.SealProof,
@ -425,9 +429,11 @@ func fromV3SectorOnChainInfo(v3 miner3.SectorOnChainInfo) SectorOnChainInfo {
ExpectedDayReward: v3.ExpectedDayReward,
ExpectedStoragePledge: v3.ExpectedStoragePledge,
}
}
func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
return SectorPreCommitOnChainInfo{
Info: (SectorPreCommitInfo)(v3.Info),
PreCommitDeposit: v3.PreCommitDeposit,
@ -435,4 +441,5 @@ func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) Sect
DealWeight: v3.DealWeight,
VerifiedDealWeight: v3.VerifiedDealWeight,
}
}

View File

@ -16,6 +16,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
)
@ -208,9 +209,9 @@ func (s *state4) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err
// If no sector numbers are specified, load all.
if snos == nil {
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
var info2 miner4.SectorOnChainInfo
if err := sectors.ForEach(&info2, func(_ int64) error {
info := fromV4SectorOnChainInfo(info2)
var info4 miner4.SectorOnChainInfo
if err := sectors.ForEach(&info4, func(_ int64) error {
info := fromV4SectorOnChainInfo(info4)
infos = append(infos, &info)
return nil
}); err != nil {
@ -220,13 +221,13 @@ func (s *state4) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err
}
// Otherwise, load selected.
infos2, err := sectors.Load(*snos)
infos4, err := sectors.Load(*snos)
if err != nil {
return nil, err
}
infos := make([]*SectorOnChainInfo, len(infos2))
for i, info2 := range infos2 {
info := fromV4SectorOnChainInfo(*info2)
infos := make([]*SectorOnChainInfo, len(infos4))
for i, info4 := range infos4 {
info := fromV4SectorOnChainInfo(*info4)
infos[i] = &info
}
return infos, nil
@ -268,13 +269,13 @@ func (s *state4) NumDeadlines() (uint64, error) {
}
func (s *state4) DeadlinesChanged(other State) (bool, error) {
other2, ok := other.(*state4)
other4, ok := other.(*state4)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Deadlines.Equals(other2.Deadlines), nil
return !s.State.Deadlines.Equals(other4.Deadlines), nil
}
func (s *state4) MinerInfoChanged(other State) (bool, error) {
@ -377,13 +378,13 @@ func (d *deadline4) ForEachPartition(cb func(uint64, Partition) error) error {
}
func (d *deadline4) PartitionsChanged(other Deadline) (bool, error) {
other2, ok := other.(*deadline4)
other4, ok := other.(*deadline4)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
return !d.Deadline.Partitions.Equals(other4.Deadline.Partitions), nil
}
func (d *deadline4) PartitionsPoSted() (bitfield.BitField, error) {
@ -391,12 +392,14 @@ func (d *deadline4) PartitionsPoSted() (bitfield.BitField, error) {
}
func (d *deadline4) DisputableProofCount() (uint64, error) {
ops, err := d.OptimisticProofsSnapshotArray(d.store)
if err != nil {
return 0, err
}
return ops.Length(), nil
}
func (p *partition4) AllSectors() (bitfield.BitField, error) {
@ -412,6 +415,7 @@ func (p *partition4) RecoveringSectors() (bitfield.BitField, error) {
}
func fromV4SectorOnChainInfo(v4 miner4.SectorOnChainInfo) SectorOnChainInfo {
return SectorOnChainInfo{
SectorNumber: v4.SectorNumber,
SealProof: v4.SealProof,
@ -425,9 +429,11 @@ func fromV4SectorOnChainInfo(v4 miner4.SectorOnChainInfo) SectorOnChainInfo {
ExpectedDayReward: v4.ExpectedDayReward,
ExpectedStoragePledge: v4.ExpectedStoragePledge,
}
}
func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
return SectorPreCommitOnChainInfo{
Info: (SectorPreCommitInfo)(v4.Info),
PreCommitDeposit: v4.PreCommitDeposit,
@ -435,4 +441,5 @@ func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) Sect
DealWeight: v4.DealWeight,
VerifiedDealWeight: v4.VerifiedDealWeight,
}
}

View File

@ -0,0 +1,117 @@
package multisig
import (
"fmt"
"github.com/minio/blake2b-simd"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
msig{{.latestVersion}} "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}}
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.MultisigActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
StartEpoch() (abi.ChainEpoch, error)
UnlockDuration() (abi.ChainEpoch, error)
InitialBalance() (abi.TokenAmount, error)
Threshold() (uint64, error)
Signers() ([]address.Address, error)
ForEachPendingTxn(func(id int64, txn Transaction) error) error
PendingTxnChanged(State) (bool, error)
transactions() (adt.Map, error)
decodeTransaction(val *cbg.Deferred) (Transaction, error)
}
type Transaction = msig{{.latestVersion}}.Transaction
var Methods = builtin{{.latestVersion}}.MethodsMultisig
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
{{range .versions}}
case actors.Version{{.}}:
return message{{.}}{{"{"}}{{if (ge . 2)}}message0{from}{{else}}from{{end}}}
{{end}} default:
panic(fmt.Sprintf("unsupported actors version: %d", version))
}
}
type MessageBuilder interface {
// Create a new multisig with the specified parameters.
Create(signers []address.Address, threshold uint64,
vestingStart, vestingDuration abi.ChainEpoch,
initialAmount abi.TokenAmount) (*types.Message, error)
// Propose a transaction to the given multisig.
Propose(msig, target address.Address, amt abi.TokenAmount,
method abi.MethodNum, params []byte) (*types.Message, error)
// Approve a multisig transaction. The "hash" is optional.
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
// Cancel a multisig transaction. The "hash" is optional.
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
}
// this type is the same between v0 and v2
type ProposalHashData = msig{{.latestVersion}}.ProposalHashData
type ProposeReturn = msig{{.latestVersion}}.ProposeReturn
type ProposeParams = msig{{.latestVersion}}.ProposeParams
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
params := msig{{.latestVersion}}.TxnIDParams{ID: msig{{.latestVersion}}.TxnID(id)}
if data != nil {
if data.Requester.Protocol() != address.ID {
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
}
if data.Value.Sign() == -1 {
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
}
if data.To == address.Undef {
return nil, xerrors.Errorf("proposed destination address must be set")
}
pser, err := data.Serialize()
if err != nil {
return nil, err
}
hash := blake2b.Sum256(pser)
params.ProposalHash = hash[:]
}
return actors.SerializeParams(&params)
}

View File

@ -1,79 +0,0 @@
package multisig
import (
"fmt"
"github.com/minio/blake2b-simd"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
multisig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
)
var Methods = builtin4.MethodsMultisig
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
case actors.Version0:
return message0{from}
case actors.Version2:
return message2{message0{from}}
case actors.Version3:
return message3{message0{from}}
case actors.Version4:
return message4{message0{from}}
default:
panic(fmt.Sprintf("unsupported actors version: %d", version))
}
}
type MessageBuilder interface {
// Create a new multisig with the specified parameters.
Create(signers []address.Address, threshold uint64,
vestingStart, vestingDuration abi.ChainEpoch,
initialAmount abi.TokenAmount) (*types.Message, error)
// Propose a transaction to the given multisig.
Propose(msig, target address.Address, amt abi.TokenAmount,
method abi.MethodNum, params []byte) (*types.Message, error)
// Approve a multisig transaction. The "hash" is optional.
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
// Cancel a multisig transaction. The "hash" is optional.
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
}
// this type is the same between v0 and v2
type ProposalHashData = multisig4.ProposalHashData
type ProposeReturn = multisig4.ProposeReturn
type ProposeParams = multisig4.ProposeParams
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
params := multisig4.TxnIDParams{ID: multisig4.TxnID(id)}
if data != nil {
if data.Requester.Protocol() != address.ID {
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
}
if data.Value.Sign() == -1 {
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
}
if data.To == address.Undef {
return nil, xerrors.Errorf("proposed destination address must be set")
}
pser, err := data.Serialize()
if err != nil {
return nil, err
}
hash := blake2b.Sum256(pser)
params.ProposalHash = hash[:]
}
return actors.SerializeParams(&params)
}

View File

@ -0,0 +1,146 @@
package multisig
import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init"
multisig{{.v}} "github.com/filecoin-project/specs-actors{{.import}}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 message{{.v}} struct{ {{if (ge .v 2)}}message0{{else}}from address.Address{{end}} }
func (m message{{.v}}) 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")
}
{{if (le .v 1)}}
if unlockStart != 0 {
return nil, xerrors.Errorf("actors v0 does not support a non-zero vesting start time")
}
{{end}}
// Set up constructor parameters for multisig
msigParams := &multisig{{.v}}.ConstructorParams{
Signers: signers,
NumApprovalsThreshold: threshold,
UnlockDuration: unlockDuration,{{if (ge .v 2)}}
StartEpoch: unlockStart,{{end}}
}
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 := &init{{.v}}.ExecParams{
CodeCID: builtin{{.v}}.MultisigActorCodeID,
ConstructorParams: enc,
}
enc, actErr = actors.SerializeParams(execParams)
if actErr != nil {
return nil, actErr
}
return &types.Message{
To: init_.Address,
From: m.from,
Method: builtin{{.v}}.MethodsInit.Exec,
Params: enc,
Value: initialAmount,
}, nil
}
{{if (le .v 1)}}
func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount,
method abi.MethodNum, params []byte) (*types.Message, error) {
if msig == address.Undef {
return nil, xerrors.Errorf("must provide a multisig address for proposal")
}
if to == address.Undef {
return nil, xerrors.Errorf("must provide a target address for proposal")
}
if amt.Sign() == -1 {
return nil, xerrors.Errorf("must provide a non-negative amount for proposed send")
}
if m.from == address.Undef {
return nil, xerrors.Errorf("must provide source address")
}
enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{
To: to,
Value: amt,
Method: method,
Params: params,
})
if actErr != nil {
return nil, xerrors.Errorf("failed to serialize parameters: %w", actErr)
}
return &types.Message{
To: msig,
From: m.from,
Value: abi.NewTokenAmount(0),
Method: builtin0.MethodsMultisig.Propose,
Params: enc,
}, nil
}
func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
enc, err := txnParams(txID, hashData)
if err != nil {
return nil, err
}
return &types.Message{
To: msig,
From: m.from,
Value: types.NewInt(0),
Method: builtin0.MethodsMultisig.Approve,
Params: enc,
}, nil
}
func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
enc, err := txnParams(txID, hashData)
if err != nil {
return nil, err
}
return &types.Message{
To: msig,
From: m.from,
Value: types.NewInt(0),
Method: builtin0.MethodsMultisig.Cancel,
Params: enc,
}, nil
}
{{end}}

View File

@ -0,0 +1,152 @@
package multisig
import (
"fmt"
"github.com/minio/blake2b-simd"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
msig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
}
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.MultisigActorCodeID:
return load0(store, act.Head)
case builtin2.MultisigActorCodeID:
return load2(store, act.Head)
case builtin3.MultisigActorCodeID:
return load3(store, act.Head)
case builtin4.MultisigActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
StartEpoch() (abi.ChainEpoch, error)
UnlockDuration() (abi.ChainEpoch, error)
InitialBalance() (abi.TokenAmount, error)
Threshold() (uint64, error)
Signers() ([]address.Address, error)
ForEachPendingTxn(func(id int64, txn Transaction) error) error
PendingTxnChanged(State) (bool, error)
transactions() (adt.Map, error)
decodeTransaction(val *cbg.Deferred) (Transaction, error)
}
type Transaction = msig4.Transaction
var Methods = builtin4.MethodsMultisig
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
case actors.Version0:
return message0{from}
case actors.Version2:
return message2{message0{from}}
case actors.Version3:
return message3{message0{from}}
case actors.Version4:
return message4{message0{from}}
default:
panic(fmt.Sprintf("unsupported actors version: %d", version))
}
}
type MessageBuilder interface {
// Create a new multisig with the specified parameters.
Create(signers []address.Address, threshold uint64,
vestingStart, vestingDuration abi.ChainEpoch,
initialAmount abi.TokenAmount) (*types.Message, error)
// Propose a transaction to the given multisig.
Propose(msig, target address.Address, amt abi.TokenAmount,
method abi.MethodNum, params []byte) (*types.Message, error)
// Approve a multisig transaction. The "hash" is optional.
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
// Cancel a multisig transaction. The "hash" is optional.
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
}
// this type is the same between v0 and v2
type ProposalHashData = msig4.ProposalHashData
type ProposeReturn = msig4.ProposeReturn
type ProposeParams = msig4.ProposeParams
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
params := msig4.TxnIDParams{ID: msig4.TxnID(id)}
if data != nil {
if data.Requester.Protocol() != address.ID {
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
}
if data.Value.Sign() == -1 {
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
}
if data.To == address.Undef {
return nil, xerrors.Errorf("proposed destination address must be set")
}
pser, err := data.Serialize()
if err != nil {
return nil, err
}
hash := blake2b.Sum256(pser)
params.ProposalHash = hash[:]
}
return actors.SerializeParams(&params)
}

View File

@ -1,69 +0,0 @@
package multisig
import (
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
}
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.MultisigActorCodeID:
return load0(store, act.Head)
case builtin2.MultisigActorCodeID:
return load2(store, act.Head)
case builtin3.MultisigActorCodeID:
return load3(store, act.Head)
case builtin4.MultisigActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
StartEpoch() (abi.ChainEpoch, error)
UnlockDuration() (abi.ChainEpoch, error)
InitialBalance() (abi.TokenAmount, error)
Threshold() (uint64, error)
Signers() ([]address.Address, error)
ForEachPendingTxn(func(id int64, txn Transaction) error) error
PendingTxnChanged(State) (bool, error)
transactions() (adt.Map, error)
decodeTransaction(val *cbg.Deferred) (Transaction, error)
}
type Transaction = msig0.Transaction

View File

@ -0,0 +1,97 @@
package multisig
import (
"bytes"
"encoding/binary"
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}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"
{{if (ge .v 3)}}
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
{{end}}
msig{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/multisig"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
msig{{.v}}.State
store adt.Store
}
func (s *state{{.v}}) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
}
func (s *state{{.v}}) StartEpoch() (abi.ChainEpoch, error) {
return s.State.StartEpoch, nil
}
func (s *state{{.v}}) UnlockDuration() (abi.ChainEpoch, error) {
return s.State.UnlockDuration, nil
}
func (s *state{{.v}}) InitialBalance() (abi.TokenAmount, error) {
return s.State.InitialBalance, nil
}
func (s *state{{.v}}) Threshold() (uint64, error) {
return s.State.NumApprovalsThreshold, nil
}
func (s *state{{.v}}) Signers() ([]address.Address, error) {
return s.State.Signers, nil
}
func (s *state{{.v}}) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
arr, err := adt{{.v}}.AsMap(s.store, s.State.PendingTxns{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
if err != nil {
return err
}
var out msig{{.v}}.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)) //nolint:unconvert
})
}
func (s *state{{.v}}) PendingTxnChanged(other State) (bool, error) {
other{{.v}}, ok := other.(*state{{.v}})
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.PendingTxns.Equals(other{{.v}}.PendingTxns), nil
}
func (s *state{{.v}}) transactions() (adt.Map, error) {
return adt{{.v}}.AsMap(s.store, s.PendingTxns{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
}
func (s *state{{.v}}) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
var tx msig{{.v}}.Transaction
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return Transaction{}, err
}
return tx, nil
}

View File

@ -4,6 +4,8 @@ import (
"bytes"
"encoding/binary"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
@ -13,8 +15,6 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
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"
)
var _ State = (*state0)(nil)
@ -86,7 +86,7 @@ func (s *state0) transactions() (adt.Map, error) {
}
func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
var tx multisig0.Transaction
var tx msig0.Transaction
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return Transaction{}, err
}

View File

@ -4,6 +4,8 @@ import (
"bytes"
"encoding/binary"
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
@ -13,7 +15,6 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
)
var _ State = (*state2)(nil)

View File

@ -15,6 +15,7 @@ import (
"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"
)
@ -74,12 +75,12 @@ func (s *state3) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
}
func (s *state3) PendingTxnChanged(other State) (bool, error) {
other2, ok := other.(*state3)
other3, ok := other.(*state3)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
return !s.State.PendingTxns.Equals(other3.PendingTxns), nil
}
func (s *state3) transactions() (adt.Map, error) {

View File

@ -15,6 +15,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
msig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
)
@ -69,17 +70,17 @@ func (s *state4) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
if n <= 0 {
return xerrors.Errorf("invalid pending transaction key: %v", key)
}
return cb(txid, (Transaction)(out))
return cb(txid, (Transaction)(out)) //nolint:unconvert
})
}
func (s *state4) PendingTxnChanged(other State) (bool, error) {
other2, ok := other.(*state4)
other4, ok := other.(*state4)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
return !s.State.PendingTxns.Equals(other4.PendingTxns), nil
}
func (s *state4) transactions() (adt.Map, error) {

View File

@ -0,0 +1,109 @@
package paych
import (
"encoding/base64"
"fmt"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
big "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/ipfs/go-cid"
ipldcbor "github.com/ipfs/go-ipld-cbor"
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}}
// Load returns an abstract copy of payment channel state, irregardless of actor version
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.PaymentChannelActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
// State is an abstract version of payment channel state that works across
// versions
type State interface {
cbor.Marshaler
// Channel owner, who has funded the actor
From() (address.Address, error)
// Recipient of payouts from channel
To() (address.Address, error)
// Height at which the channel can be `Collected`
SettlingAt() (abi.ChainEpoch, error)
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
ToSend() (abi.TokenAmount, error)
// Get total number of lanes
LaneCount() (uint64, error)
// Iterate lane states
ForEachLaneState(cb func(idx uint64, dl LaneState) error) error
}
// LaneState is an abstract copy of the state of a single lane
type LaneState interface {
Redeemed() (big.Int, error)
Nonce() (uint64, error)
}
type SignedVoucher = paych0.SignedVoucher
type ModVerifyParams = paych0.ModVerifyParams
// DecodeSignedVoucher decodes base64 encoded signed voucher.
func DecodeSignedVoucher(s string) (*SignedVoucher, error) {
data, err := base64.RawURLEncoding.DecodeString(s)
if err != nil {
return nil, err
}
var sv SignedVoucher
if err := ipldcbor.DecodeInto(data, &sv); err != nil {
return nil, err
}
return &sv, nil
}
var Methods = builtin{{.latestVersion}}.MethodsPaych
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
{{range .versions}}
case actors.Version{{.}}:
return message{{.}}{from}
{{end}}
default:
panic(fmt.Sprintf("unsupported actors version: %d", version))
}
}
type MessageBuilder interface {
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
Settle(paych address.Address) (*types.Message, error)
Collect(paych address.Address) (*types.Message, error)
}

View File

@ -1,36 +0,0 @@
package paych
import (
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
)
var Methods = builtin4.MethodsPaych
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
case actors.Version0:
return message0{from}
case actors.Version2:
return message2{from}
case actors.Version3:
return message3{from}
case actors.Version4:
return message4{from}
default:
panic(fmt.Sprintf("unsupported actors version: %d", version))
}
}
type MessageBuilder interface {
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
Settle(paych address.Address) (*types.Message, error)
Collect(paych address.Address) (*types.Message, error)
}

View File

@ -0,0 +1,74 @@
package paych
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init"
paych{{.v}} "github.com/filecoin-project/specs-actors{{.import}}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 message{{.v}} struct{ from address.Address }
func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
params, aerr := actors.SerializeParams(&paych{{.v}}.ConstructorParams{From: m.from, To: to})
if aerr != nil {
return nil, aerr
}
enc, aerr := actors.SerializeParams(&init{{.v}}.ExecParams{
CodeCID: builtin{{.v}}.PaymentChannelActorCodeID,
ConstructorParams: params,
})
if aerr != nil {
return nil, aerr
}
return &types.Message{
To: init_.Address,
From: m.from,
Value: initialAmount,
Method: builtin{{.v}}.MethodsInit.Exec,
Params: enc,
}, nil
}
func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) {
params, aerr := actors.SerializeParams(&paych{{.v}}.UpdateChannelStateParams{
Sv: *sv,
Secret: secret,
})
if aerr != nil {
return nil, aerr
}
return &types.Message{
To: paych,
From: m.from,
Value: abi.NewTokenAmount(0),
Method: builtin{{.v}}.MethodsPaych.UpdateChannelState,
Params: params,
}, nil
}
func (m message{{.v}}) Settle(paych address.Address) (*types.Message, error) {
return &types.Message{
To: paych,
From: m.from,
Value: abi.NewTokenAmount(0),
Method: builtin{{.v}}.MethodsPaych.Settle,
}, nil
}
func (m message{{.v}}) Collect(paych address.Address) (*types.Message, error) {
return &types.Message{
To: paych,
From: m.from,
Value: abi.NewTokenAmount(0),
Method: builtin{{.v}}.MethodsPaych.Collect,
}, nil
}

View File

@ -2,6 +2,7 @@ package paych
import (
"encoding/base64"
"fmt"
"golang.org/x/xerrors"
@ -12,27 +13,36 @@ import (
"github.com/ipfs/go-cid"
ipldcbor "github.com/ipfs/go-ipld-cbor"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
builtin.RegisterActorState(builtin0.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
@ -41,14 +51,19 @@ func init() {
// Load returns an abstract copy of payment channel state, irregardless of actor version
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.PaymentChannelActorCodeID:
return load0(store, act.Head)
case builtin2.PaymentChannelActorCodeID:
return load2(store, act.Head)
case builtin3.PaymentChannelActorCodeID:
return load3(store, act.Head)
case builtin4.PaymentChannelActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
@ -98,3 +113,32 @@ func DecodeSignedVoucher(s string) (*SignedVoucher, error) {
return &sv, nil
}
var Methods = builtin4.MethodsPaych
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
case actors.Version0:
return message0{from}
case actors.Version2:
return message2{from}
case actors.Version3:
return message3{from}
case actors.Version4:
return message4{from}
default:
panic(fmt.Sprintf("unsupported actors version: %d", version))
}
}
type MessageBuilder interface {
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
Settle(paych address.Address) (*types.Message, error)
Collect(paych address.Address) (*types.Message, error)
}

View 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"
paych{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/paych"
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
paych{{.v}}.State
store adt.Store
lsAmt *adt{{.v}}.Array
}
// Channel owner, who has funded the actor
func (s *state{{.v}}) From() (address.Address, error) {
return s.State.From, nil
}
// Recipient of payouts from channel
func (s *state{{.v}}) To() (address.Address, error) {
return s.State.To, nil
}
// Height at which the channel can be `Collected`
func (s *state{{.v}}) SettlingAt() (abi.ChainEpoch, error) {
return s.State.SettlingAt, nil
}
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
func (s *state{{.v}}) ToSend() (abi.TokenAmount, error) {
return s.State.ToSend, nil
}
func (s *state{{.v}}) getOrLoadLsAmt() (*adt{{.v}}.Array, error) {
if s.lsAmt != nil {
return s.lsAmt, nil
}
// Get the lane state from the chain
lsamt, err := adt{{.v}}.AsArray(s.store, s.State.LaneStates{{if (ge .v 3)}}, paych{{.v}}.LaneStatesAmtBitwidth{{end}})
if err != nil {
return nil, err
}
s.lsAmt = lsamt
return lsamt, nil
}
// Get total number of lanes
func (s *state{{.v}}) LaneCount() (uint64, error) {
lsamt, err := s.getOrLoadLsAmt()
if err != nil {
return 0, err
}
return lsamt.Length(), nil
}
// Iterate lane states
func (s *state{{.v}}) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error {
// Get the lane state from the chain
lsamt, err := s.getOrLoadLsAmt()
if err != nil {
return err
}
// Note: we use a map instead of an array to store laneStates because the
// client sets the lane ID (the index) and potentially they could use a
// very large index.
var ls paych{{.v}}.LaneState
return lsamt.ForEach(&ls, func(i int64) error {
return cb(uint64(i), &laneState{{.v}}{ls})
})
}
type laneState{{.v}} struct {
paych{{.v}}.LaneState
}
func (ls *laneState{{.v}}) Redeemed() (big.Int, error) {
return ls.LaneState.Redeemed, nil
}
func (ls *laneState{{.v}}) Nonce() (uint64, error) {
return ls.LaneState.Nonce, nil
}

View File

@ -0,0 +1,78 @@
package power
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}}
var (
Address = builtin{{.latestVersion}}.StoragePowerActorAddr
Methods = builtin{{.latestVersion}}.MethodsPower
)
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.StoragePowerActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
TotalLocked() (abi.TokenAmount, error)
TotalPower() (Claim, error)
TotalCommitted() (Claim, error)
TotalPowerSmoothed() (builtin.FilterEstimate, error)
// MinerCounts returns the number of miners. Participating is the number
// with power above the minimum miner threshold.
MinerCounts() (participating, total uint64, err error)
MinerPower(address.Address) (Claim, bool, error)
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
ListAllMiners() ([]address.Address, error)
ForEachClaim(func(miner address.Address, claim Claim) error) error
ClaimsChanged(State) (bool, error)
// Diff helpers. Used by Diff* functions internally.
claims() (adt.Map, error)
decodeClaim(*cbg.Deferred) (Claim, error)
}
type Claim struct {
// Sum of raw byte power for a miner's sectors.
RawBytePower abi.StoragePower
// Sum of quality adjusted power for a miner's sectors.
QualityAdjPower abi.StoragePower
}
func AddClaims(a Claim, b Claim) Claim {
return Claim{
RawBytePower: big.Add(a.RawBytePower, b.RawBytePower),
QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower),
}
}

View File

@ -15,21 +15,28 @@ import (
"github.com/filecoin-project/lotus/chain/types"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
)
func init() {
builtin.RegisterActorState(builtin0.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
@ -40,16 +47,21 @@ var (
Methods = builtin4.MethodsPower
)
func Load(store adt.Store, act *types.Actor) (st State, err error) {
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.StoragePowerActorCodeID:
return load0(store, act.Head)
case builtin2.StoragePowerActorCodeID:
return load2(store, act.Head)
case builtin3.StoragePowerActorCodeID:
return load3(store, act.Head)
case builtin4.StoragePowerActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}

View File

@ -0,0 +1,151 @@
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"
{{if (ge .v 3)}}
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
{{end}}
power{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/power"
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
power{{.v}}.State
store adt.Store
}
func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) {
return s.TotalPledgeCollateral, nil
}
func (s *state{{.v}}) 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 *state{{.v}}) TotalCommitted() (Claim, error) {
return Claim{
RawBytePower: s.TotalBytesCommitted,
QualityAdjPower: s.TotalQABytesCommitted,
}, nil
}
func (s *state{{.v}}) MinerPower(addr address.Address) (Claim, bool, error) {
claims, err := s.claims()
if err != nil {
return Claim{}, false, err
}
var claim power{{.v}}.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 *state{{.v}}) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
}
func (s *state{{.v}}) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
return builtin.FromV{{.v}}FilterEstimate({{if (le .v 1)}}*{{end}}s.State.ThisEpochQAPowerSmoothed), nil
}
func (s *state{{.v}}) MinerCounts() (uint64, uint64, error) {
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
}
func (s *state{{.v}}) 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 *state{{.v}}) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
claims, err := s.claims()
if err != nil {
return err
}
var claim power{{.v}}.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 *state{{.v}}) ClaimsChanged(other State) (bool, error) {
other{{.v}}, ok := other.(*state{{.v}})
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Claims.Equals(other{{.v}}.State.Claims), nil
}
func (s *state{{.v}}) claims() (adt.Map, error) {
return adt{{.v}}.AsMap(s.store, s.Claims{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
}
func (s *state{{.v}}) decodeClaim(val *cbg.Deferred) (Claim, error) {
var ci power{{.v}}.Claim
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return Claim{}, err
}
return fromV{{.v}}Claim(ci), nil
}
func fromV{{.v}}Claim(v{{.v}} power{{.v}}.Claim) Claim {
return Claim{
RawBytePower: v{{.v}}.RawBytePower,
QualityAdjPower: v{{.v}}.QualityAdjPower,
}
}

View File

@ -51,7 +51,7 @@ func (s *state0) TotalCommitted() (Claim, error) {
}
func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) {
claims, err := adt0.AsMap(s.store, s.Claims)
claims, err := s.claims()
if err != nil {
return Claim{}, false, err
}
@ -79,7 +79,7 @@ func (s *state0) MinerCounts() (uint64, uint64, error) {
}
func (s *state0) ListAllMiners() ([]address.Address, error) {
claims, err := adt0.AsMap(s.store, s.Claims)
claims, err := s.claims()
if err != nil {
return nil, err
}
@ -101,7 +101,7 @@ func (s *state0) ListAllMiners() ([]address.Address, error) {
}
func (s *state0) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
claims, err := adt0.AsMap(s.store, s.Claims)
claims, err := s.claims()
if err != nil {
return err
}
@ -141,5 +141,8 @@ func (s *state0) decodeClaim(val *cbg.Deferred) (Claim, error) {
}
func fromV0Claim(v0 power0.Claim) Claim {
return (Claim)(v0)
return Claim{
RawBytePower: v0.RawBytePower,
QualityAdjPower: v0.QualityAdjPower,
}
}

View File

@ -51,7 +51,7 @@ func (s *state2) TotalCommitted() (Claim, error) {
}
func (s *state2) MinerPower(addr address.Address) (Claim, bool, error) {
claims, err := adt2.AsMap(s.store, s.Claims)
claims, err := s.claims()
if err != nil {
return Claim{}, false, err
}
@ -79,7 +79,7 @@ func (s *state2) MinerCounts() (uint64, uint64, error) {
}
func (s *state2) ListAllMiners() ([]address.Address, error) {
claims, err := adt2.AsMap(s.store, s.Claims)
claims, err := s.claims()
if err != nil {
return nil, err
}
@ -101,7 +101,7 @@ func (s *state2) ListAllMiners() ([]address.Address, error) {
}
func (s *state2) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
claims, err := adt2.AsMap(s.store, s.Claims)
claims, err := s.claims()
if err != nil {
return err
}

View File

@ -12,6 +12,7 @@ import (
"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"
)
@ -121,12 +122,12 @@ func (s *state3) ForEachClaim(cb func(miner address.Address, claim Claim) error)
}
func (s *state3) ClaimsChanged(other State) (bool, error) {
other2, ok := other.(*state3)
other3, ok := other.(*state3)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Claims.Equals(other2.State.Claims), nil
return !s.State.Claims.Equals(other3.State.Claims), nil
}
func (s *state3) claims() (adt.Map, error) {

View File

@ -12,6 +12,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/builtin"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
power4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power"
adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
)
@ -121,12 +122,12 @@ func (s *state4) ForEachClaim(cb func(miner address.Address, claim Claim) error)
}
func (s *state4) ClaimsChanged(other State) (bool, error) {
other2, ok := other.(*state4)
other4, ok := other.(*state4)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Claims.Equals(other2.State.Claims), nil
return !s.State.Claims.Equals(other4.State.Claims), nil
}
func (s *state4) claims() (adt.Map, error) {

View File

@ -0,0 +1,60 @@
package reward
import (
"github.com/filecoin-project/go-state-types/abi"
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/cbor"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}}
var (
Address = builtin{{.latestVersion}}.RewardActorAddr
Methods = builtin{{.latestVersion}}.MethodsReward
)
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.RewardActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
ThisEpochBaselinePower() (abi.StoragePower, error)
ThisEpochReward() (abi.StoragePower, error)
ThisEpochRewardSmoothed() (builtin.FilterEstimate, error)
EffectiveBaselinePower() (abi.StoragePower, error)
EffectiveNetworkTime() (abi.ChainEpoch, error)
TotalStoragePowerReward() (abi.TokenAmount, error)
CumsumBaseline() (abi.StoragePower, error)
CumsumRealized() (abi.StoragePower, error)
InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error)
PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error)
}
type AwardBlockRewardParams = reward0.AwardBlockRewardParams

View File

@ -7,9 +7,13 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/cbor"
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"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/adt"
@ -18,15 +22,19 @@ import (
)
func init() {
builtin.RegisterActorState(builtin0.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
@ -37,16 +45,21 @@ var (
Methods = builtin4.MethodsReward
)
func Load(store adt.Store, act *types.Actor) (st State, err error) {
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.RewardActorCodeID:
return load0(store, act.Head)
case builtin2.RewardActorCodeID:
return load2(store, act.Head)
case builtin3.RewardActorCodeID:
return load3(store, act.Head)
case builtin4.RewardActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}

View File

@ -0,0 +1,103 @@
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"
miner{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/miner"
reward{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/reward"
smoothing{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/smoothing"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
reward{{.v}}.State
store adt.Store
}
func (s *state{{.v}}) ThisEpochReward() (abi.TokenAmount, error) {
return s.State.ThisEpochReward, nil
}
func (s *state{{.v}}) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
{{if (ge .v 2)}}
return builtin.FilterEstimate{
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
}, nil
{{else}}
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
{{end}}
}
func (s *state{{.v}}) ThisEpochBaselinePower() (abi.StoragePower, error) {
return s.State.ThisEpochBaselinePower, nil
}
func (s *state{{.v}}) TotalStoragePowerReward() (abi.TokenAmount, error) {
return s.State.{{if (ge .v 2)}}TotalStoragePowerReward{{else}}TotalMined{{end}}, nil
}
func (s *state{{.v}}) EffectiveBaselinePower() (abi.StoragePower, error) {
return s.State.EffectiveBaselinePower, nil
}
func (s *state{{.v}}) EffectiveNetworkTime() (abi.ChainEpoch, error) {
return s.State.EffectiveNetworkTime, nil
}
func (s *state{{.v}}) CumsumBaseline() (reward{{.v}}.Spacetime, error) {
return s.State.CumsumBaseline, nil
}
func (s *state{{.v}}) CumsumRealized() (reward{{.v}}.Spacetime, error) {
return s.State.CumsumRealized, nil
}
{{if (ge .v 2)}}
func (s *state{{.v}}) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
return miner{{.v}}.InitialPledgeForPower(
qaPower,
s.State.ThisEpochBaselinePower,
s.State.ThisEpochRewardSmoothed,
smoothing{{.v}}.FilterEstimate{
PositionEstimate: networkQAPower.PositionEstimate,
VelocityEstimate: networkQAPower.VelocityEstimate,
},
circSupply,
), nil
}
{{else}}
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
return miner0.InitialPledgeForPower(
sectorWeight,
s.State.ThisEpochBaselinePower,
networkTotalPledge,
s.State.ThisEpochRewardSmoothed,
&smoothing0.FilterEstimate{
PositionEstimate: networkQAPower.PositionEstimate,
VelocityEstimate: networkQAPower.VelocityEstimate,
},
circSupply), nil
}
{{end}}
func (s *state{{.v}}) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
return miner{{.v}}.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
{{if (le .v 0)}}&{{end}}smoothing{{.v}}.FilterEstimate{
PositionEstimate: networkQAPower.PositionEstimate,
VelocityEstimate: networkQAPower.VelocityEstimate,
},
sectorWeight), nil
}

View File

@ -28,12 +28,14 @@ type state0 struct {
store adt.Store
}
func (s *state0) ThisEpochReward() (abi.StoragePower, error) {
func (s *state0) ThisEpochReward() (abi.TokenAmount, error) {
return s.State.ThisEpochReward, nil
}
func (s *state0) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
}
func (s *state0) ThisEpochBaselinePower() (abi.StoragePower, error) {
@ -52,11 +54,11 @@ func (s *state0) EffectiveNetworkTime() (abi.ChainEpoch, error) {
return s.State.EffectiveNetworkTime, nil
}
func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
func (s *state0) CumsumBaseline() (reward0.Spacetime, error) {
return s.State.CumsumBaseline, nil
}
func (s *state0) CumsumRealized() (abi.StoragePower, error) {
func (s *state0) CumsumRealized() (reward0.Spacetime, error) {
return s.State.CumsumRealized, nil
}

View File

@ -33,10 +33,12 @@ func (s *state2) ThisEpochReward() (abi.TokenAmount, error) {
}
func (s *state2) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
return builtin.FilterEstimate{
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
}, nil
}
func (s *state2) ThisEpochBaselinePower() (abi.StoragePower, error) {

View File

@ -33,10 +33,12 @@ func (s *state3) ThisEpochReward() (abi.TokenAmount, error) {
}
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) {

View File

@ -33,10 +33,12 @@ func (s *state4) ThisEpochReward() (abi.TokenAmount, error) {
}
func (s *state4) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
return builtin.FilterEstimate{
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
}, nil
}
func (s *state4) ThisEpochBaselinePower() (abi.StoragePower, error) {

View File

@ -0,0 +1,51 @@
package verifreg
import (
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
{{range .versions}}
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
{{end}}
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
)
func init() {
{{range .versions}}
builtin.RegisterActorState(builtin{{.}}.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load{{.}}(store, root)
})
{{end}}
}
var (
Address = builtin{{.latestVersion}}.VerifiedRegistryActorAddr
Methods = builtin{{.latestVersion}}.MethodsVerifiedRegistry
)
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
{{range .versions}}
case builtin{{.}}.VerifiedRegistryActorCodeID:
return load{{.}}(store, act.Head)
{{end}}
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}
type State interface {
cbor.Marshaler
RootKey() (address.Address, error)
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
}

View 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"
{{if (ge .v 3)}} builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg"
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
)
var _ State = (*state{{.v}})(nil)
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
out := state{{.v}}{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
type state{{.v}} struct {
verifreg{{.v}}.State
store adt.Store
}
func (s *state{{.v}}) RootKey() (address.Address, error) {
return s.State.RootKey, nil
}
func (s *state{{.v}}) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
return getDataCap(s.store, actors.Version{{.v}}, s.verifiedClients, addr)
}
func (s *state{{.v}}) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
return getDataCap(s.store, actors.Version{{.v}}, s.verifiers, addr)
}
func (s *state{{.v}}) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
return forEachCap(s.store, actors.Version{{.v}}, s.verifiers, cb)
}
func (s *state{{.v}}) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
return forEachCap(s.store, actors.Version{{.v}}, s.verifiedClients, cb)
}
func (s *state{{.v}}) verifiedClients() (adt.Map, error) {
return adt{{.v}}.AsMap(s.store, s.VerifiedClients{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
}
func (s *state{{.v}}) verifiers() (adt.Map, error) {
return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
}

View File

@ -8,9 +8,13 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/adt"
@ -19,18 +23,23 @@ import (
)
func init() {
builtin.RegisterActorState(builtin0.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load0(store, root)
})
builtin.RegisterActorState(builtin2.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load2(store, root)
})
builtin.RegisterActorState(builtin3.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load3(store, root)
})
builtin.RegisterActorState(builtin4.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
return load4(store, root)
})
}
var (
@ -40,14 +49,19 @@ var (
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.VerifiedRegistryActorCodeID:
return load0(store, act.Head)
case builtin2.VerifiedRegistryActorCodeID:
return load2(store, act.Head)
case builtin3.VerifiedRegistryActorCodeID:
return load3(store, act.Head)
case builtin4.VerifiedRegistryActorCodeID:
return load4(store, act.Head)
}
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
}

View File

@ -25,8 +25,9 @@ import (
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market"
miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych"
verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg"
paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych"
)
const (
@ -39,7 +40,9 @@ const (
// SetSupportedProofTypes sets supported proof types, across all actor versions.
// This should only be used for testing.
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
miner0.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types))
miner2.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
miner2.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
miner2.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
@ -63,6 +66,7 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
panic("must specify v1 proof types only")
}
// Set for all miner versions.
miner0.SupportedProofTypes[t] = struct{}{}
miner2.PreCommitSealProofTypesV0[t] = struct{}{}
@ -79,6 +83,7 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
miner4.PreCommitSealProofTypesV7[t] = struct{}{}
miner4.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
miner4.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
}
}
@ -86,22 +91,29 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
// actors versions. Use for testing.
func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
// Set for all miner versions.
miner0.PreCommitChallengeDelay = delay
miner2.PreCommitChallengeDelay = delay
miner3.PreCommitChallengeDelay = delay
miner4.PreCommitChallengeDelay = delay
}
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
func GetPreCommitChallengeDelay() abi.ChainEpoch {
return miner0.PreCommitChallengeDelay
return miner4.PreCommitChallengeDelay
}
// SetConsensusMinerMinPower sets the minimum power of an individual miner must
// meet for leader election, across all actor versions. This should only be used
// for testing.
func SetConsensusMinerMinPower(p abi.StoragePower) {
power0.ConsensusMinerMinPower = p
for _, policy := range builtin2.SealProofPolicies {
policy.ConsensusMinerMinPower = p
}
@ -113,27 +125,42 @@ func SetConsensusMinerMinPower(p abi.StoragePower) {
for _, policy := range builtin4.PoStProofPolicies {
policy.ConsensusMinerMinPower = p
}
}
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
// only be used for testing.
func SetMinVerifiedDealSize(size abi.StoragePower) {
verifreg0.MinVerifiedDealSize = size
verifreg2.MinVerifiedDealSize = size
verifreg3.MinVerifiedDealSize = size
verifreg4.MinVerifiedDealSize = size
}
func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch {
switch ver {
case actors.Version0:
return miner0.MaxSealDuration[t]
case actors.Version2:
return miner2.MaxProveCommitDuration[t]
case actors.Version3:
return miner3.MaxProveCommitDuration[t]
case actors.Version4:
return miner4.MaxProveCommitDuration[t]
default:
panic("unsupported actors version")
}
@ -145,26 +172,36 @@ func DealProviderCollateralBounds(
circulatingFil abi.TokenAmount, nwVer network.Version,
) (min, max abi.TokenAmount) {
switch actors.VersionForNetwork(nwVer) {
case actors.Version0:
return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer)
case actors.Version2:
return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
case actors.Version3:
return market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
case actors.Version4:
return market4.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
default:
panic("unsupported actors version")
}
}
func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) {
return market2.DealDurationBounds(pieceSize)
return market4.DealDurationBounds(pieceSize)
}
// Sets the challenge window and scales the proving period to match (such that
// there are always 48 challenge windows in a proving period).
func SetWPoStChallengeWindow(period abi.ChainEpoch) {
miner0.WPoStChallengeWindow = period
miner0.WPoStProvingPeriod = period * abi.ChainEpoch(miner0.WPoStPeriodDeadlines)
@ -173,13 +210,18 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) {
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
miner4.WPoStChallengeWindow = period
miner4.WPoStProvingPeriod = period * abi.ChainEpoch(miner4.WPoStPeriodDeadlines)
miner4.WPoStDisputeWindow = period * 30 // see the miner3 comment
// by default, this is 2x finality which is 30 periods.
// scale it if we're scaling the challenge period.
miner4.WPoStDisputeWindow = period * 30
}
func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
@ -192,12 +234,12 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
}
func GetMaxSectorExpirationExtension() abi.ChainEpoch {
return miner0.MaxSectorExpirationExtension
return miner4.MaxSectorExpirationExtension
}
// TODO: we'll probably need to abstract over this better in the future.
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
sectorsPerPart, err := builtin3.PoStProofWindowPoStPartitionSectors(p)
sectorsPerPart, err := builtin4.PoStProofWindowPoStPartitionSectors(p)
if err != nil {
return 0, err
}
@ -233,14 +275,19 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version)
func GetAddressedSectorsMax(nwVer network.Version) int {
switch actors.VersionForNetwork(nwVer) {
case actors.Version0:
return miner0.AddressedSectorsMax
case actors.Version2:
return miner2.AddressedSectorsMax
case actors.Version3:
return miner3.AddressedSectorsMax
case actors.Version4:
return miner4.AddressedSectorsMax
default:
panic("unsupported network version")
}
@ -248,15 +295,24 @@ func GetAddressedSectorsMax(nwVer network.Version) int {
func GetDeclarationsMax(nwVer network.Version) int {
switch actors.VersionForNetwork(nwVer) {
case actors.Version0:
// TODO: Should we instead panic here since the concept doesn't exist yet?
return miner0.AddressedPartitionsMax
case actors.Version2:
return miner2.DeclarationsMax
case actors.Version3:
return miner3.DeclarationsMax
case actors.Version4:
return miner4.DeclarationsMax
default:
panic("unsupported network version")
}

View File

@ -0,0 +1,233 @@
package policy
import (
"sort"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors"
{{range .versions}}
{{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}}
market{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/market"
miner{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/miner"
verifreg{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/verifreg"
{{if (eq . 0)}} power{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/power" {{end}}
{{end}}
paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych"
)
const (
ChainFinality = miner{{.latestVersion}}.ChainFinality
SealRandomnessLookback = ChainFinality
PaychSettleDelay = paych{{.latestVersion}}.SettleDelay
MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback
)
// SetSupportedProofTypes sets supported proof types, across all actor versions.
// This should only be used for testing.
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
{{range .versions}}
{{if (eq . 0)}}
miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types))
{{else}}
miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
{{end}}
{{end}}
AddSupportedProofTypes(types...)
}
// AddSupportedProofTypes sets supported proof types, across all actor versions.
// This should only be used for testing.
func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
for _, t := range types {
if t >= abi.RegisteredSealProof_StackedDrg2KiBV1_1 {
panic("must specify v1 proof types only")
}
// Set for all miner versions.
{{range .versions}}
{{if (eq . 0)}}
miner{{.}}.SupportedProofTypes[t] = struct{}{}
{{else}}
miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{}
miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{}
miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
{{end}}
{{end}}
}
}
// SetPreCommitChallengeDelay sets the pre-commit challenge delay across all
// actors versions. Use for testing.
func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
// Set for all miner versions.
{{range .versions}}
miner{{.}}.PreCommitChallengeDelay = delay
{{end}}
}
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
func GetPreCommitChallengeDelay() abi.ChainEpoch {
return miner{{.latestVersion}}.PreCommitChallengeDelay
}
// SetConsensusMinerMinPower sets the minimum power of an individual miner must
// meet for leader election, across all actor versions. This should only be used
// for testing.
func SetConsensusMinerMinPower(p abi.StoragePower) {
{{range .versions}}
{{if (eq . 0)}}
power{{.}}.ConsensusMinerMinPower = p
{{else if (eq . 2)}}
for _, policy := range builtin{{.}}.SealProofPolicies {
policy.ConsensusMinerMinPower = p
}
{{else}}
for _, policy := range builtin{{.}}.PoStProofPolicies {
policy.ConsensusMinerMinPower = p
}
{{end}}
{{end}}
}
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
// only be used for testing.
func SetMinVerifiedDealSize(size abi.StoragePower) {
{{range .versions}}
verifreg{{.}}.MinVerifiedDealSize = size
{{end}}
}
func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch {
switch ver {
{{range .versions}}
case actors.Version{{.}}:
{{if (eq . 0)}}
return miner{{.}}.MaxSealDuration[t]
{{else}}
return miner{{.}}.MaxProveCommitDuration[t]
{{end}}
{{end}}
default:
panic("unsupported actors version")
}
}
func DealProviderCollateralBounds(
size abi.PaddedPieceSize, verified bool,
rawBytePower, qaPower, baselinePower abi.StoragePower,
circulatingFil abi.TokenAmount, nwVer network.Version,
) (min, max abi.TokenAmount) {
switch actors.VersionForNetwork(nwVer) {
{{range .versions}}
case actors.Version{{.}}:
{{if (eq . 0)}}
return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer)
{{else}}
return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
{{end}}
{{end}}
default:
panic("unsupported actors version")
}
}
func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) {
return market{{.latestVersion}}.DealDurationBounds(pieceSize)
}
// Sets the challenge window and scales the proving period to match (such that
// there are always 48 challenge windows in a proving period).
func SetWPoStChallengeWindow(period abi.ChainEpoch) {
{{range .versions}}
miner{{.}}.WPoStChallengeWindow = period
miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines)
{{if (ge . 3)}}
// by default, this is 2x finality which is 30 periods.
// scale it if we're scaling the challenge period.
miner{{.}}.WPoStDisputeWindow = period * 30
{{end}}
{{end}}
}
func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
if nwVer <= network.Version3 {
return 10
}
// NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well
return ChainFinality
}
func GetMaxSectorExpirationExtension() abi.ChainEpoch {
return miner{{.latestVersion}}.MaxSectorExpirationExtension
}
// TODO: we'll probably need to abstract over this better in the future.
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
sectorsPerPart, err := builtin{{.latestVersion}}.PoStProofWindowPoStPartitionSectors(p)
if err != nil {
return 0, err
}
return int(miner{{.latestVersion}}.AddressedSectorsMax / sectorsPerPart), nil
}
func GetDefaultSectorSize() abi.SectorSize {
// supported sector sizes are the same across versions.
szs := make([]abi.SectorSize, 0, len(miner{{.latestVersion}}.PreCommitSealProofTypesV8))
for spt := range miner{{.latestVersion}}.PreCommitSealProofTypesV8 {
ss, err := spt.SectorSize()
if err != nil {
panic(err)
}
szs = append(szs, ss)
}
sort.Slice(szs, func(i, j int) bool {
return szs[i] < szs[j]
})
return szs[0]
}
func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) abi.ChainEpoch {
if nwVer <= network.Version10 {
return builtin{{.latestVersion}}.SealProofPoliciesV0[proof].SectorMaxLifetime
}
return builtin{{.latestVersion}}.SealProofPoliciesV11[proof].SectorMaxLifetime
}
func GetAddressedSectorsMax(nwVer network.Version) int {
switch actors.VersionForNetwork(nwVer) {
{{range .versions}}
case actors.Version{{.}}:
return miner{{.}}.AddressedSectorsMax
{{end}}
default:
panic("unsupported network version")
}
}
func GetDeclarationsMax(nwVer network.Version) int {
switch actors.VersionForNetwork(nwVer) {
{{range .versions}}
case actors.Version{{.}}:
{{if (eq . 0)}}
// TODO: Should we instead panic here since the concept doesn't exist yet?
return miner{{.}}.AddressedPartitionsMax
{{else}}
return miner{{.}}.DeclarationsMax
{{end}}
{{end}}
default:
panic("unsupported network version")
}
}

View File

@ -51,7 +51,7 @@ func TestWorkerKeyChange(t *testing.T) {
blocktime := 1 * time.Millisecond
n, sn := builder.MockSbBuilder(t, []test.FullNodeOpts{test.FullNodeWithActorsV4At(-1), test.FullNodeWithActorsV4At(-1)}, test.OneMiner)
n, sn := builder.MockSbBuilder(t, []test.FullNodeOpts{test.FullNodeWithLatestActorsAt(-1), test.FullNodeWithLatestActorsAt(-1)}, test.OneMiner)
client1 := n[0]
client2 := n[1]

View File

@ -0,0 +1,19 @@
### Actor version integration checklist
- [ ] Import new actors
- [ ] Define upgrade heights in `build/params_`
- [ ] Generate adapters
- [ ] Add the new version in `chain/actors/agen/main.go`
- [ ] Update adapter code in `chain/actors/builtin` if needed
- [ ] Update `chain/actors/policy/policy.go`
- [ ] Update `chain/actors/version.go`
- [ ] Register in `chain/vm/invoker.go`
- [ ] Register in `chain/vm/mkactor.go`
- [ ] Update `chain/types/state.go`
- [ ] Update `chain/state/statetree.go`
- [ ] Update `chain/stmgr/forks.go`
- [ ] Schedule
- [ ] Migration
- [ ] Update upgrade schedule in `api/test/test.go`
- [ ] Update `NewestNetworkVersion` in `build/params_shared_vals.go`
- [ ] Register in init in `chain/stmgr/utils.go`