actors: Implement cron actor
This commit is contained in:
parent
5bfcc307e9
commit
96023d415e
48
chain/actors/actor_cron.go
Normal file
48
chain/actors/actor_cron.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package actors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/address"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CronActor struct{}
|
||||||
|
|
||||||
|
type callTuple struct {
|
||||||
|
addr address.Address
|
||||||
|
method uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
var CronActors = []callTuple{
|
||||||
|
{StoragePowerAddress, SPAMethods.CheckProofSubmissions},
|
||||||
|
}
|
||||||
|
|
||||||
|
type CronActorState struct{}
|
||||||
|
|
||||||
|
type cAMethods struct {
|
||||||
|
EpochTick uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
var CAMethods = cAMethods{2}
|
||||||
|
|
||||||
|
func (ca CronActor) Exports() []interface{} {
|
||||||
|
return []interface{}{
|
||||||
|
1: nil,
|
||||||
|
2: ca.EpochTick,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ca CronActor) EpochTick(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
|
if vmctx.Message().From != CronAddress {
|
||||||
|
return nil, aerrors.New(1, "EpochTick is only callable as a part of tipset state computation")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, call := range CronActors {
|
||||||
|
_, err := vmctx.Send(call.addr, call.method, types.NewInt(0), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err // todo: this very bad?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -170,7 +170,7 @@ func IsBuiltinActor(code cid.Cid) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsSingletonActor(code cid.Cid) bool {
|
func IsSingletonActor(code cid.Cid) bool {
|
||||||
return code == StoragePowerCodeCid || code == StorageMarketCodeCid || code == InitCodeCid
|
return code == StoragePowerCodeCid || code == StorageMarketCodeCid || code == InitCodeCid || code == CronCodeCid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ias *InitActorState) AddActor(cst *hamt.CborIpldStore, addr address.Address) (address.Address, error) {
|
func (ias *InitActorState) AddActor(cst *hamt.CborIpldStore, addr address.Address) (address.Address, error) {
|
||||||
|
@ -567,8 +567,8 @@ func pledgeCollateralForSize(vmctx types.VMContext, size, totalStorage types.Big
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types.VMContext, param *struct{}) ([]byte, ActorError) {
|
func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types.VMContext, param *struct{}) ([]byte, ActorError) {
|
||||||
if vmctx.Message().From != StoragePowerAddress {
|
if vmctx.Message().From != CronAddress {
|
||||||
return nil, aerrors.New(1, "CheckProofSubmissions is only callable as a part of tipset state computation")
|
return nil, aerrors.New(1, "CheckProofSubmissions is only callable from the cron actor")
|
||||||
}
|
}
|
||||||
|
|
||||||
var self StoragePowerState
|
var self StoragePowerState
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var AccountCodeCid cid.Cid
|
var AccountCodeCid cid.Cid
|
||||||
|
var CronCodeCid cid.Cid
|
||||||
var StoragePowerCodeCid cid.Cid
|
var StoragePowerCodeCid cid.Cid
|
||||||
var StorageMarketCodeCid cid.Cid
|
var StorageMarketCodeCid cid.Cid
|
||||||
var StorageMinerCodeCid cid.Cid
|
var StorageMinerCodeCid cid.Cid
|
||||||
@ -19,6 +20,7 @@ var InitAddress = mustIDAddress(0)
|
|||||||
var NetworkAddress = mustIDAddress(1)
|
var NetworkAddress = mustIDAddress(1)
|
||||||
var StoragePowerAddress = mustIDAddress(2)
|
var StoragePowerAddress = mustIDAddress(2)
|
||||||
var StorageMarketAddress = mustIDAddress(3) // TODO: missing from spec
|
var StorageMarketAddress = mustIDAddress(3) // TODO: missing from spec
|
||||||
|
var CronAddress = mustIDAddress(4)
|
||||||
var BurntFundsAddress = mustIDAddress(99)
|
var BurntFundsAddress = mustIDAddress(99)
|
||||||
|
|
||||||
func mustIDAddress(i uint64) address.Address {
|
func mustIDAddress(i uint64) address.Address {
|
||||||
@ -40,6 +42,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AccountCodeCid = mustSum("fil/1/account") // TODO: spec
|
AccountCodeCid = mustSum("fil/1/account") // TODO: spec
|
||||||
|
CronCodeCid = mustSum("fil/1/cron")
|
||||||
StoragePowerCodeCid = mustSum("fil/1/power")
|
StoragePowerCodeCid = mustSum("fil/1/power")
|
||||||
StorageMarketCodeCid = mustSum("fil/1/market")
|
StorageMarketCodeCid = mustSum("fil/1/market")
|
||||||
StorageMinerCodeCid = mustSum("fil/1/miner")
|
StorageMinerCodeCid = mustSum("fil/1/miner")
|
||||||
|
@ -3976,3 +3976,32 @@ func (t *CheckMinerParams) UnmarshalCBOR(r io.Reader) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *CronActorState) MarshalCBOR(w io.Writer) error {
|
||||||
|
if t == nil {
|
||||||
|
_, err := w.Write(cbg.CborNull)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.Write([]byte{128}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *CronActorState) UnmarshalCBOR(r io.Reader) error {
|
||||||
|
br := cbg.GetPeeker(r)
|
||||||
|
|
||||||
|
maj, extra, err := cbg.CborReadHeader(br)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if maj != cbg.MajArray {
|
||||||
|
return fmt.Errorf("cbor input should be of type array")
|
||||||
|
}
|
||||||
|
|
||||||
|
if extra != 0 {
|
||||||
|
return fmt.Errorf("cbor input had wrong number of fields")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
cid "github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
@ -89,6 +89,15 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
|
|||||||
return nil, xerrors.Errorf("set init actor: %w", err)
|
return nil, xerrors.Errorf("set init actor: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cronact, err := SetupCronActor(bs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("setup cron actor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := state.SetActor(actors.CronAddress, cronact); err != nil {
|
||||||
|
return nil, xerrors.Errorf("set cron actor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
spact, err := SetupStoragePowerActor(bs)
|
spact, err := SetupStoragePowerActor(bs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("setup storage market actor: %w", err)
|
return nil, xerrors.Errorf("setup storage market actor: %w", err)
|
||||||
@ -144,6 +153,23 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
|
|||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetupCronActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||||
|
cst := hamt.CSTFromBstore(bs)
|
||||||
|
cas := &actors.CronActorState{}
|
||||||
|
|
||||||
|
stcid, err := cst.Put(context.TODO(), cas)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Actor{
|
||||||
|
Code: actors.CronCodeCid,
|
||||||
|
Head: stcid,
|
||||||
|
Nonce: 0,
|
||||||
|
Balance: types.NewInt(0),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||||
cst := hamt.CSTFromBstore(bs)
|
cst := hamt.CSTFromBstore(bs)
|
||||||
nd := hamt.NewNode(cst)
|
nd := hamt.NewNode(cst)
|
||||||
|
@ -197,21 +197,20 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this nonce-getting is a ting bit ugly
|
// TODO: this nonce-getting is a tiny bit ugly
|
||||||
spa, err := vmi.StateTree().GetActor(actors.StoragePowerAddress)
|
ca, err := vmi.StateTree().GetActor(actors.CronAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, err
|
return cid.Undef, cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: cron actor
|
|
||||||
ret, err := vmi.ApplyMessage(ctx, &types.Message{
|
ret, err := vmi.ApplyMessage(ctx, &types.Message{
|
||||||
To: actors.StoragePowerAddress,
|
To: actors.CronAddress,
|
||||||
From: actors.StoragePowerAddress,
|
From: actors.CronAddress,
|
||||||
Nonce: spa.Nonce,
|
Nonce: ca.Nonce,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: types.NewInt(0),
|
GasPrice: types.NewInt(0),
|
||||||
GasLimit: types.NewInt(1 << 30), // Make super sure this is never too little
|
GasLimit: types.NewInt(1 << 30), // Make super sure this is never too little
|
||||||
Method: actors.SPAMethods.CheckProofSubmissions,
|
Method: actors.CAMethods.EpochTick,
|
||||||
Params: nil,
|
Params: nil,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
@ -31,6 +31,7 @@ func newInvoker() *invoker {
|
|||||||
|
|
||||||
// add builtInCode using: register(cid, singleton)
|
// add builtInCode using: register(cid, singleton)
|
||||||
inv.register(actors.InitCodeCid, actors.InitActor{}, actors.InitActorState{})
|
inv.register(actors.InitCodeCid, actors.InitActor{}, actors.InitActorState{})
|
||||||
|
inv.register(actors.CronCodeCid, actors.CronActor{}, actors.CronActorState{})
|
||||||
inv.register(actors.StoragePowerCodeCid, actors.StoragePowerActor{}, actors.StoragePowerState{})
|
inv.register(actors.StoragePowerCodeCid, actors.StoragePowerActor{}, actors.StoragePowerState{})
|
||||||
inv.register(actors.StorageMarketCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
|
inv.register(actors.StorageMarketCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
|
||||||
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
||||||
|
@ -129,6 +129,7 @@ func main() {
|
|||||||
actors.ComputeDataCommitmentParams{},
|
actors.ComputeDataCommitmentParams{},
|
||||||
actors.SectorProveCommitInfo{},
|
actors.SectorProveCommitInfo{},
|
||||||
actors.CheckMinerParams{},
|
actors.CheckMinerParams{},
|
||||||
|
actors.CronActorState{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
Loading…
Reference in New Issue
Block a user