refactor state utilities into StateManager package, implement proper election proofs
This commit is contained in:
parent
6e21372ccb
commit
ed45d1c2b4
11
api/api.go
11
api/api.go
@ -48,16 +48,11 @@ type FullNode interface {
|
||||
ChainNotify(context.Context) (<-chan *store.HeadChange, error)
|
||||
ChainHead(context.Context) (*types.TipSet, error) // TODO: check serialization
|
||||
ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error // TODO: check serialization
|
||||
ChainGetRandomness(context.Context, *types.TipSet) ([]byte, error)
|
||||
ChainGetRandomness(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error)
|
||||
ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error)
|
||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||
ChainGetBlockReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error)
|
||||
ChainGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
|
||||
ChainReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error)
|
||||
|
||||
// if tipset is nil, we'll use heaviest
|
||||
ChainCall(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error)
|
||||
|
||||
// messages
|
||||
|
||||
@ -107,6 +102,10 @@ type FullNode interface {
|
||||
StateMinerProvingSet(context.Context, address.Address) ([]*SectorInfo, error)
|
||||
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
|
||||
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
|
||||
// if tipset is nil, we'll use heaviest
|
||||
StateCall(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error)
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
|
||||
StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error)
|
||||
|
||||
PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error)
|
||||
PaychList(context.Context) ([]address.Address, error)
|
||||
|
@ -39,17 +39,14 @@ type FullNodeStruct struct {
|
||||
CommonStruct
|
||||
|
||||
Internal struct {
|
||||
ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"`
|
||||
ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"`
|
||||
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"`
|
||||
ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"`
|
||||
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
|
||||
ChainGetBlockReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
||||
ChainCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
|
||||
ChainGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"`
|
||||
ChainReadState func(context.Context, *types.Actor, *types.TipSet) (*ActorState, error) `perm:"read"`
|
||||
ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"`
|
||||
ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"`
|
||||
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetRandomness func(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error) `perm:"read"`
|
||||
ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"`
|
||||
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
|
||||
ChainGetBlockReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
||||
|
||||
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"`
|
||||
@ -75,10 +72,13 @@ type FullNodeStruct struct {
|
||||
ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"`
|
||||
ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"`
|
||||
|
||||
StateMinerSectors func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
||||
StateMinerProvingSet func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"`
|
||||
StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
||||
StateMinerProvingSet func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"`
|
||||
StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"`
|
||||
StateCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, *types.Actor, *types.TipSet) (*ActorState, error) `perm:"read"`
|
||||
|
||||
PaychCreate func(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error) `perm:"sign"`
|
||||
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
|
||||
@ -204,26 +204,14 @@ func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||
return c.Internal.ChainHead(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts *types.TipSet) ([]byte, error) {
|
||||
return c.Internal.ChainGetRandomness(ctx, pts)
|
||||
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts *types.TipSet, ticks []*types.Ticket, lb int) ([]byte, error) {
|
||||
return c.Internal.ChainGetRandomness(ctx, pts, ticks, lb)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainWaitMsg(ctx context.Context, msgc cid.Cid) (*MsgWait, error) {
|
||||
return c.Internal.ChainWaitMsg(ctx, msgc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
return c.Internal.ChainCall(ctx, msg, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
return c.Internal.ChainGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error) {
|
||||
return c.Internal.ChainReadState(ctx, act, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ string) (address.Address, error) {
|
||||
return c.Internal.WalletNew(ctx, typ)
|
||||
}
|
||||
@ -288,6 +276,18 @@ func (c *FullNodeStruct) StateMinerWorker(ctx context.Context, m address.Address
|
||||
return c.Internal.StateMinerWorker(ctx, m, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
return c.Internal.StateCall(ctx, msg, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
return c.Internal.StateGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error) {
|
||||
return c.Internal.StateReadState(ctx, act, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error) {
|
||||
return c.Internal.PaychCreate(ctx, from, to, amt)
|
||||
}
|
||||
|
@ -12,5 +12,6 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours
|
||||
const DealVoucherSkewLimit = 10
|
||||
|
||||
const ForkLengthThreshold = 20
|
||||
const RandomnessLookback = 20
|
||||
|
||||
// TODO: Move other important consts here
|
||||
|
@ -77,7 +77,7 @@ func (h *Handler) sendSignedResponse(resp StorageDealResponse) error {
|
||||
From: h.actor,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
}
|
||||
r, err := h.full.ChainCall(context.TODO(), getworker, nil)
|
||||
r, err := h.full.StateCall(context.TODO(), getworker, nil)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting worker address: %w", err)
|
||||
}
|
||||
|
218
chain/gen/gen.go
218
chain/gen/gen.go
@ -3,19 +3,21 @@ package gen
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"math/big"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-car"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
"github.com/filecoin-project/go-lotus/chain"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||
@ -41,8 +43,10 @@ type ChainGen struct {
|
||||
|
||||
cs *store.ChainStore
|
||||
|
||||
genesis *types.BlockHeader
|
||||
curBlock *types.FullBlock
|
||||
sm *stmgr.StateManager
|
||||
|
||||
genesis *types.BlockHeader
|
||||
curTipset *store.FullTipSet
|
||||
|
||||
w *wallet.Wallet
|
||||
|
||||
@ -118,9 +122,17 @@ func NewGenerator() (*ChainGen, error) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
minercfg := &GenMinerCfg{
|
||||
Workers: []address.Address{worker, worker},
|
||||
Owners: []address.Address{worker, worker},
|
||||
PeerIDs: []peer.ID{"peerID1", "peerID2"},
|
||||
}
|
||||
*/
|
||||
minercfg := &GenMinerCfg{
|
||||
Worker: worker,
|
||||
Owner: worker,
|
||||
Workers: []address.Address{worker},
|
||||
Owners: []address.Address{worker},
|
||||
PeerIDs: []peer.ID{"peerID1"},
|
||||
}
|
||||
|
||||
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
|
||||
@ -134,28 +146,32 @@ func NewGenerator() (*ChainGen, error) {
|
||||
cs := store.NewChainStore(bs, ds)
|
||||
|
||||
genfb := &types.FullBlock{Header: genb.Genesis}
|
||||
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
|
||||
|
||||
if err := cs.SetGenesis(genb.Genesis); err != nil {
|
||||
return nil, xerrors.Errorf("set genesis failed: %w", err)
|
||||
}
|
||||
|
||||
if minercfg.MinerAddr == address.Undef {
|
||||
if len(minercfg.MinerAddrs) == 0 {
|
||||
return nil, xerrors.Errorf("MakeGenesisBlock failed to set miner address")
|
||||
}
|
||||
|
||||
sm := stmgr.NewStateManager(cs)
|
||||
|
||||
gen := &ChainGen{
|
||||
bs: bs,
|
||||
cs: cs,
|
||||
sm: sm,
|
||||
msgsPerBlock: msgsPerBlock,
|
||||
genesis: genb.Genesis,
|
||||
w: w,
|
||||
|
||||
miners: []address.Address{minercfg.MinerAddr},
|
||||
mworkers: []address.Address{worker},
|
||||
miners: minercfg.MinerAddrs,
|
||||
mworkers: minercfg.Workers,
|
||||
banker: banker,
|
||||
receivers: receievers,
|
||||
|
||||
curBlock: genfb,
|
||||
curTipset: gents,
|
||||
|
||||
r: mr,
|
||||
lr: lr,
|
||||
@ -182,19 +198,35 @@ func (cg *ChainGen) GenesisCar() ([]byte, error) {
|
||||
return out.Bytes(), nil
|
||||
}
|
||||
|
||||
func (cg *ChainGen) nextBlockProof(ctx context.Context) (address.Address, types.ElectionProof, []*types.Ticket, error) {
|
||||
func (cg *ChainGen) nextBlockProof(ctx context.Context, m address.Address, ticks []*types.Ticket) (types.ElectionProof, *types.Ticket, error) {
|
||||
pts := cg.curTipset.TipSet()
|
||||
|
||||
ticks := cg.curBlock.Header.Tickets
|
||||
lastTicket := ticks[len(ticks)-1]
|
||||
fmt.Println("checking winner:", m, ticks)
|
||||
var lastTicket *types.Ticket
|
||||
if len(ticks) == 0 {
|
||||
lastTicket = pts.MinTicket()
|
||||
} else {
|
||||
lastTicket = ticks[len(ticks)-1]
|
||||
}
|
||||
|
||||
vrfout, err := ComputeVRF(ctx, cg.w.Sign, cg.mworkers[0], lastTicket.VDFResult)
|
||||
st, err := cg.sm.TipSetState(pts.Cids())
|
||||
if err != nil {
|
||||
return address.Undef, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
worker, err := stmgr.GetMinerWorker(ctx, cg.sm, st, m)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, lastTicket.VDFResult)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
out, proof, err := vdf.Run(vrfout)
|
||||
if err != nil {
|
||||
return address.Undef, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
tick := &types.Ticket{
|
||||
@ -203,7 +235,15 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context) (address.Address, types.
|
||||
VDFResult: out,
|
||||
}
|
||||
|
||||
return cg.miners[0], []byte("cat in a box"), []*types.Ticket{tick}, nil
|
||||
win, eproof, err := IsRoundWinner(ctx, pts, append(ticks, tick), m, &mca{w: cg.w, sm: cg.sm})
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("checking round winner failed: %w", err)
|
||||
}
|
||||
if !win {
|
||||
return nil, tick, nil
|
||||
}
|
||||
|
||||
return eproof, tick, nil
|
||||
}
|
||||
|
||||
type MinedTipSet struct {
|
||||
@ -212,13 +252,64 @@ type MinedTipSet struct {
|
||||
}
|
||||
|
||||
func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
|
||||
miner, proof, tickets, err := cg.nextBlockProof(context.TODO())
|
||||
var blks []*types.FullBlock
|
||||
ticketSets := make([][]*types.Ticket, len(cg.miners))
|
||||
|
||||
msgs, err := cg.getRandomMessages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// make some transfers from banker
|
||||
for len(blks) == 0 {
|
||||
for i, m := range cg.miners {
|
||||
fmt.Println("Checking for winner: ", m)
|
||||
proof, t, err := cg.nextBlockProof(context.TODO(), m, ticketSets[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ticketSets[i] = append(ticketSets[i], t)
|
||||
if proof != nil {
|
||||
fmt.Println("WINNER!!!!", m)
|
||||
fblk, err := cg.makeBlock(m, proof, ticketSets[i], msgs)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
|
||||
}
|
||||
|
||||
if err := cg.cs.AddBlock(fblk.Header); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blks = append(blks, fblk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("num winners: ", len(blks))
|
||||
|
||||
cg.curTipset = store.NewFullTipSet(blks)
|
||||
|
||||
return &MinedTipSet{
|
||||
TipSet: cg.curTipset,
|
||||
Messages: msgs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cg *ChainGen) makeBlock(m address.Address, eproof types.ElectionProof, tickets []*types.Ticket, msgs []*types.SignedMessage) (*types.FullBlock, error) {
|
||||
|
||||
parents := cg.curTipset.TipSet()
|
||||
|
||||
ts := parents.MinTimestamp() + (uint64(len(tickets)) * build.BlockDelay)
|
||||
|
||||
fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, m, parents, tickets, eproof, msgs, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fblk, err
|
||||
}
|
||||
|
||||
func (cg *ChainGen) getRandomMessages() ([]*types.SignedMessage, error) {
|
||||
msgs := make([]*types.SignedMessage, cg.msgsPerBlock)
|
||||
for m := range msgs {
|
||||
msg := types.Message{
|
||||
@ -255,30 +346,7 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// create block
|
||||
|
||||
parents, err := types.NewTipSet([]*types.BlockHeader{cg.curBlock.Header})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ts := parents.MinTimestamp() + (uint64(len(tickets)) * build.BlockDelay)
|
||||
|
||||
fblk, err := MinerCreateBlock(context.TODO(), cg.cs, cg.w, miner, parents, tickets, proof, msgs, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := cg.cs.AddBlock(fblk.Header); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cg.curBlock = fblk
|
||||
|
||||
return &MinedTipSet{
|
||||
TipSet: store.NewFullTipSet([]*types.FullBlock{fblk}),
|
||||
Messages: msgs,
|
||||
}, nil
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
|
||||
@ -289,7 +357,7 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
|
||||
}
|
||||
|
||||
type MiningCheckAPI interface {
|
||||
ChainGetRandomness(context.Context, *types.TipSet) ([]byte, error)
|
||||
ChainGetRandomness(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error)
|
||||
|
||||
StateMinerPower(context.Context, address.Address, *types.TipSet) (api.MinerPower, error)
|
||||
|
||||
@ -298,12 +366,47 @@ type MiningCheckAPI interface {
|
||||
WalletSign(context.Context, address.Address, []byte) (*types.Signature, error)
|
||||
}
|
||||
|
||||
type mca struct {
|
||||
w *wallet.Wallet
|
||||
sm *stmgr.StateManager
|
||||
}
|
||||
|
||||
func (mca mca) ChainGetRandomness(ctx context.Context, pts *types.TipSet, ticks []*types.Ticket, lb int) ([]byte, error) {
|
||||
return mca.sm.ChainStore().GetRandomness(ctx, pts, ticks, lb)
|
||||
}
|
||||
|
||||
func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, ts *types.TipSet) (api.MinerPower, error) {
|
||||
mpow, tpow, err := chain.GetPower(ctx, mca.sm, ts, maddr)
|
||||
if err != nil {
|
||||
return api.MinerPower{}, err
|
||||
}
|
||||
|
||||
return api.MinerPower{
|
||||
MinerPower: mpow,
|
||||
TotalPower: tpow,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
st, err := mca.sm.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
return stmgr.GetMinerWorker(ctx, mca.sm, st, maddr)
|
||||
}
|
||||
|
||||
func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*types.Signature, error) {
|
||||
return mca.w.Sign(ctx, a, v)
|
||||
}
|
||||
|
||||
func IsRoundWinner(ctx context.Context, ts *types.TipSet, ticks []*types.Ticket, miner address.Address, a MiningCheckAPI) (bool, types.ElectionProof, error) {
|
||||
r, err := a.ChainGetRandomness(ctx, ts)
|
||||
r, err := a.ChainGetRandomness(ctx, ts, ticks, build.RandomnessLookback)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
fmt.Println("chain randomness: ", r)
|
||||
mworker, err := a.StateMinerWorker(ctx, miner, ts)
|
||||
if err != nil {
|
||||
return false, nil, xerrors.Errorf("failed to get miner worker: %w", err)
|
||||
@ -319,23 +422,20 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, ticks []*types.Ticket,
|
||||
return false, nil, xerrors.Errorf("failed to check power: %w", err)
|
||||
}
|
||||
|
||||
return PowerCmp(vrfout, pow.MinerPower, pow.TotalPower), vrfout, nil
|
||||
return types.PowerCmp(vrfout, pow.MinerPower, pow.TotalPower), vrfout, nil
|
||||
}
|
||||
|
||||
func PowerCmp(vrfout []byte, mpow, totpow types.BigInt) bool {
|
||||
type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error)
|
||||
|
||||
/*
|
||||
Need to check that
|
||||
h(vrfout) / 2^256 < minerPower / totalPower
|
||||
*/
|
||||
func ComputeVRF(ctx context.Context, sign SignFunc, w address.Address, input []byte) ([]byte, error) {
|
||||
sig, err := sign(ctx, w, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h := sha256.Sum256(vrfout)
|
||||
if sig.Type != types.KTBLS {
|
||||
return nil, fmt.Errorf("miner worker address was not a BLS key")
|
||||
}
|
||||
|
||||
// 2^256
|
||||
rden := types.BigInt{big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), nil)}
|
||||
|
||||
top := types.BigMul(rden, mpow)
|
||||
out := types.BigDiv(top, totpow)
|
||||
|
||||
return types.BigCmp(types.BigFromBytes(h[:]), out) < 0
|
||||
return sig.Data, nil
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -13,11 +14,12 @@ func testGeneration(t testing.TB, n int, msgs int) {
|
||||
g.msgsPerBlock = msgs
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
fmt.Println("LOOP: ", i)
|
||||
mts, err := g.NextTipSet()
|
||||
if err != nil {
|
||||
t.Fatalf("error at H:%d, %s", i, err)
|
||||
}
|
||||
if mts.TipSet.TipSet().Height() != uint64(i+1) {
|
||||
if mts.TipSet.TipSet().Height() != uint64(i+len(mts.TipSet.Blocks[0].Header.Tickets)) {
|
||||
t.Fatal("wrong height")
|
||||
}
|
||||
}
|
||||
|
@ -11,31 +11,31 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||
)
|
||||
|
||||
func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Wallet, miner address.Address, parents *types.TipSet, tickets []*types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage, timestamp uint64) (*types.FullBlock, error) {
|
||||
st, err := cs.TipSetState(parents.Cids())
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, miner address.Address, parents *types.TipSet, tickets []*types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage, timestamp uint64) (*types.FullBlock, error) {
|
||||
st, err := sm.TipSetState(parents.Cids())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load tipset state")
|
||||
}
|
||||
|
||||
height := parents.Height() + uint64(len(tickets))
|
||||
|
||||
vmi, err := vm.NewVM(st, height, miner, cs)
|
||||
vmi, err := vm.NewVM(st, height, miner, sm.ChainStore())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
owner, err := getMinerOwner(ctx, cs, st, miner)
|
||||
owner, err := stmgr.GetMinerOwner(ctx, sm, st, miner)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get miner owner: %w", err)
|
||||
}
|
||||
|
||||
worker, err := getMinerWorker(ctx, cs, st, miner)
|
||||
worker, err := stmgr.GetMinerWorker(ctx, sm, st, miner)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
|
||||
}
|
||||
@ -46,11 +46,12 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
||||
}
|
||||
|
||||
next := &types.BlockHeader{
|
||||
Miner: miner,
|
||||
Parents: parents.Cids(),
|
||||
Tickets: tickets,
|
||||
Height: height,
|
||||
Timestamp: timestamp,
|
||||
Miner: miner,
|
||||
Parents: parents.Cids(),
|
||||
Tickets: tickets,
|
||||
Height: height,
|
||||
Timestamp: timestamp,
|
||||
ElectionProof: proof,
|
||||
}
|
||||
|
||||
var blsMessages []*types.Message
|
||||
@ -63,7 +64,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
||||
blsSigs = append(blsSigs, msg.Signature)
|
||||
blsMessages = append(blsMessages, &msg.Message)
|
||||
|
||||
c, err := cs.PutMessage(&msg.Message)
|
||||
c, err := sm.ChainStore().PutMessage(&msg.Message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -93,7 +94,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
||||
receipts = append(receipts, rec.MessageReceipt)
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(cs.Blockstore())
|
||||
cst := hamt.CSTFromBstore(sm.ChainStore().Blockstore())
|
||||
blsmsgroot, err := sharray.Build(context.TODO(), 4, toIfArr(blsMsgCids), cst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -130,7 +131,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
||||
|
||||
next.BLSAggregate = aggSig
|
||||
next.StateRoot = stateRoot
|
||||
pweight := cs.Weight(parents)
|
||||
pweight := sm.ChainStore().Weight(parents)
|
||||
next.ParentWeight = types.NewInt(pweight)
|
||||
|
||||
// TODO: set timestamp
|
||||
@ -161,40 +162,6 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
||||
return fullBlock, nil
|
||||
}
|
||||
|
||||
func getMinerWorker(ctx context.Context, cs *store.ChainStore, state cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
rec, err := vm.CallRaw(ctx, cs, &types.Message{
|
||||
To: maddr,
|
||||
From: maddr,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
}, state, 0)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
if rec.ExitCode != 0 {
|
||||
return address.Undef, xerrors.Errorf("getWorker failed with exit code %d", rec.ExitCode)
|
||||
}
|
||||
|
||||
return address.NewFromBytes(rec.Return)
|
||||
}
|
||||
|
||||
func getMinerOwner(ctx context.Context, cs *store.ChainStore, state cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
rec, err := vm.CallRaw(ctx, cs, &types.Message{
|
||||
To: maddr,
|
||||
From: maddr,
|
||||
Method: actors.MAMethods.GetOwner,
|
||||
}, state, 0)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
if rec.ExitCode != 0 {
|
||||
return address.Undef, xerrors.Errorf("getOwner failed with exit code %d", rec.ExitCode)
|
||||
}
|
||||
|
||||
return address.NewFromBytes(rec.Return)
|
||||
}
|
||||
|
||||
func aggregateSignatures(sigs []types.Signature) (types.Signature, error) {
|
||||
var blsSigs []bls.Signature
|
||||
for _, s := range sigs {
|
||||
|
@ -140,16 +140,16 @@ func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||
}
|
||||
|
||||
type GenMinerCfg struct {
|
||||
Owner address.Address
|
||||
Worker address.Address
|
||||
Owners []address.Address
|
||||
Workers []address.Address
|
||||
|
||||
// not quite generating real sectors yet, but this will be necessary
|
||||
//SectorDir string
|
||||
|
||||
// The address of the created miner, this is set by the genesis setup
|
||||
MinerAddr address.Address
|
||||
// The addresses of the created miner, this is set by the genesis setup
|
||||
MinerAddrs []address.Address
|
||||
|
||||
PeerID peer.ID
|
||||
PeerIDs []peer.ID
|
||||
}
|
||||
|
||||
func mustEnc(i interface{}) []byte {
|
||||
@ -166,67 +166,78 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||
}
|
||||
|
||||
params := mustEnc(actors.CreateStorageMinerParams{
|
||||
Owner: gmcfg.Owner,
|
||||
Worker: gmcfg.Worker,
|
||||
SectorSize: types.NewInt(build.SectorSize),
|
||||
PeerID: gmcfg.PeerID,
|
||||
})
|
||||
for i := 0; i < len(gmcfg.Workers); i++ {
|
||||
owner := gmcfg.Owners[i]
|
||||
worker := gmcfg.Workers[i]
|
||||
pid := gmcfg.PeerIDs[i]
|
||||
|
||||
rval, err := doExec(ctx, vm, actors.StorageMarketAddress, gmcfg.Owner, actors.SMAMethods.CreateStorageMiner, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
||||
params := mustEnc(actors.CreateStorageMinerParams{
|
||||
Owner: owner,
|
||||
Worker: worker,
|
||||
SectorSize: types.NewInt(build.SectorSize),
|
||||
PeerID: pid,
|
||||
})
|
||||
|
||||
rval, err := doExec(ctx, vm, actors.StorageMarketAddress, owner, actors.SMAMethods.CreateStorageMiner, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
||||
}
|
||||
|
||||
maddr, err := address.NewFromBytes(rval)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
gmcfg.MinerAddrs = append(gmcfg.MinerAddrs, maddr)
|
||||
|
||||
params = mustEnc(actors.UpdateStorageParams{Delta: types.NewInt(5000)})
|
||||
|
||||
_, err = doExec(ctx, vm, actors.StorageMarketAddress, maddr, actors.SMAMethods.UpdateStorage, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to update total storage: %w", err)
|
||||
}
|
||||
|
||||
// UGLY HACKY MODIFICATION OF MINER POWER
|
||||
|
||||
// we have to flush the vm here because it buffers stuff internally for perf reasons
|
||||
if _, err := vm.Flush(ctx); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("vm.Flush failed: %w", err)
|
||||
}
|
||||
|
||||
st := vm.StateTree()
|
||||
mact, err := st.GetActor(maddr)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("get miner actor failed: %w", err)
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(cs.Blockstore())
|
||||
var mstate actors.StorageMinerActorState
|
||||
if err := cst.Get(ctx, mact.Head, &mstate); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("getting miner actor state failed: %w", err)
|
||||
}
|
||||
mstate.Power = types.NewInt(5000)
|
||||
|
||||
nstate, err := cst.Put(ctx, mstate)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
mact.Head = nstate
|
||||
if err := st.SetActor(maddr, mact); err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
// End of super haxx
|
||||
}
|
||||
|
||||
maddr, err := address.NewFromBytes(rval)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
gmcfg.MinerAddr = maddr
|
||||
|
||||
params = mustEnc(actors.UpdateStorageParams{Delta: types.NewInt(5000)})
|
||||
|
||||
_, err = doExec(ctx, vm, actors.StorageMarketAddress, maddr, actors.SMAMethods.UpdateStorage, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to update total storage: %w", err)
|
||||
}
|
||||
|
||||
// UGLY HACKY MODIFICATION OF MINER POWER
|
||||
|
||||
// we have to flush the vm here because it buffers stuff internally for perf reasons
|
||||
if _, err := vm.Flush(ctx); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("vm.Flush failed: %w", err)
|
||||
}
|
||||
|
||||
st := vm.StateTree()
|
||||
mact, err := st.GetActor(maddr)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("get miner actor failed: %w", err)
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(cs.Blockstore())
|
||||
var mstate actors.StorageMinerActorState
|
||||
if err := cst.Get(ctx, mact.Head, &mstate); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("getting miner actor state failed: %w", err)
|
||||
}
|
||||
mstate.Power = types.NewInt(5000)
|
||||
|
||||
nstate, err := cst.Put(ctx, mstate)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
mact.Head = nstate
|
||||
if err := st.SetActor(maddr, mact); err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
// End of super haxx
|
||||
|
||||
return vm.Flush(ctx)
|
||||
}
|
||||
|
||||
func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uint64, params []byte) ([]byte, error) {
|
||||
act, err := vm.StateTree().GetActor(from)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("doExec failed to get from actor: %w", err)
|
||||
}
|
||||
|
||||
ret, err := vm.ApplyMessage(context.TODO(), &types.Message{
|
||||
To: to,
|
||||
From: from,
|
||||
@ -235,6 +246,7 @@ func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uin
|
||||
GasLimit: types.NewInt(1000000),
|
||||
GasPrice: types.NewInt(0),
|
||||
Value: types.NewInt(0),
|
||||
Nonce: act.Nonce,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -322,19 +334,3 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
|
||||
Genesis: b,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error)
|
||||
|
||||
func ComputeVRF(ctx context.Context, sign SignFunc, w address.Address, input []byte) ([]byte, error) {
|
||||
|
||||
sig, err := sign(ctx, w, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sig.Type != types.KTBLS {
|
||||
return nil, fmt.Errorf("miner worker address was not a BLS key")
|
||||
}
|
||||
|
||||
return sig.Data, nil
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -15,7 +15,7 @@ type MessagePool struct {
|
||||
|
||||
pending map[address.Address]*msgSet
|
||||
|
||||
cs *store.ChainStore
|
||||
sm *stmgr.StateManager
|
||||
}
|
||||
|
||||
type msgSet struct {
|
||||
@ -36,12 +36,12 @@ func (ms *msgSet) add(m *types.SignedMessage) {
|
||||
ms.msgs[m.Message.Nonce] = m
|
||||
}
|
||||
|
||||
func NewMessagePool(cs *store.ChainStore) *MessagePool {
|
||||
func NewMessagePool(sm *stmgr.StateManager) *MessagePool {
|
||||
mp := &MessagePool{
|
||||
pending: make(map[address.Address]*msgSet),
|
||||
cs: cs,
|
||||
sm: sm,
|
||||
}
|
||||
cs.SubscribeHeadChanges(mp.HeadChange)
|
||||
sm.ChainStore().SubscribeHeadChanges(mp.HeadChange)
|
||||
|
||||
return mp
|
||||
}
|
||||
@ -61,7 +61,7 @@ func (mp *MessagePool) Add(m *types.SignedMessage) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := mp.cs.PutMessage(m); err != nil {
|
||||
if _, err := mp.sm.ChainStore().PutMessage(m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) {
|
||||
return mset.startNonce + uint64(len(mset.msgs)), nil
|
||||
}
|
||||
|
||||
act, err := mp.cs.GetActor(addr)
|
||||
act, err := mp.sm.GetActor(addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -130,7 +130,7 @@ func (mp *MessagePool) Pending() []*types.SignedMessage {
|
||||
func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet) error {
|
||||
for _, ts := range revert {
|
||||
for _, b := range ts.Blocks() {
|
||||
bmsgs, smsgs, err := mp.cs.MessagesForBlock(b)
|
||||
bmsgs, smsgs, err := mp.sm.ChainStore().MessagesForBlock(b)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get messages for revert block %s(height %d)", b.Cid(), b.Height)
|
||||
}
|
||||
@ -155,7 +155,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
|
||||
|
||||
for _, ts := range apply {
|
||||
for _, b := range ts.Blocks() {
|
||||
bmsgs, smsgs, err := mp.cs.MessagesForBlock(b)
|
||||
bmsgs, smsgs, err := mp.sm.ChainStore().MessagesForBlock(b)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get messages for apply block %s(height %d) (msgroot = %s)", b.Cid(), b.Height, b.Messages)
|
||||
}
|
||||
|
@ -1,17 +1,18 @@
|
||||
package vm
|
||||
package stmgr
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func CallRaw(ctx context.Context, cs *store.ChainStore, msg *types.Message, bstate cid.Cid, bheight uint64) (*types.MessageReceipt, error) {
|
||||
vmi, err := NewVM(bstate, bheight, actors.NetworkAddress, cs)
|
||||
func CallRaw(ctx context.Context, sm *StateManager, msg *types.Message, bstate cid.Cid, bheight uint64) (*types.MessageReceipt, error) {
|
||||
vmi, err := vm.NewVM(bstate, bheight, actors.NetworkAddress, sm.cs)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||
}
|
||||
@ -32,7 +33,7 @@ func CallRaw(ctx context.Context, cs *store.ChainStore, msg *types.Message, bsta
|
||||
}
|
||||
}
|
||||
|
||||
fromActor, err := vmi.cstate.GetActor(msg.From)
|
||||
fromActor, err := vmi.StateTree().GetActor(msg.From)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -52,15 +53,15 @@ func CallRaw(ctx context.Context, cs *store.ChainStore, msg *types.Message, bsta
|
||||
|
||||
}
|
||||
|
||||
func Call(ctx context.Context, cs *store.ChainStore, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
func Call(ctx context.Context, sm *StateManager, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
if ts == nil {
|
||||
ts = cs.GetHeaviestTipSet()
|
||||
ts = sm.cs.GetHeaviestTipSet()
|
||||
}
|
||||
|
||||
state, err := cs.TipSetState(ts.Cids())
|
||||
state, err := sm.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return CallRaw(ctx, cs, msg, state, ts.Height())
|
||||
return CallRaw(ctx, sm, msg, state, ts.Height())
|
||||
}
|
129
chain/stmgr/stmgr.go
Normal file
129
chain/stmgr/stmgr.go
Normal file
@ -0,0 +1,129 @@
|
||||
package stmgr
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/state"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
logging "github.com/ipfs/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("chainstore")
|
||||
|
||||
type StateManager struct {
|
||||
cs *store.ChainStore
|
||||
}
|
||||
|
||||
func NewStateManager(cs *store.ChainStore) *StateManager {
|
||||
return &StateManager{cs}
|
||||
}
|
||||
|
||||
func (sm *StateManager) TipSetState(cids []cid.Cid) (cid.Cid, error) {
|
||||
ctx := context.TODO()
|
||||
|
||||
ts, err := sm.cs.LoadTipSet(cids)
|
||||
if err != nil {
|
||||
log.Error("failed loading tipset: ", cids)
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
if len(ts.Blocks()) == 1 {
|
||||
return ts.Blocks()[0].StateRoot, nil
|
||||
}
|
||||
|
||||
pstate, err := sm.TipSetState(ts.Parents())
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
vmi, err := vm.NewVM(pstate, ts.Height(), address.Undef, sm.cs)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
applied := make(map[cid.Cid]bool)
|
||||
for _, b := range ts.Blocks() {
|
||||
vmi.SetBlockMiner(b.Miner)
|
||||
|
||||
bms, sms, err := sm.cs.MessagesForBlock(b)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
for _, m := range bms {
|
||||
if applied[m.Cid()] {
|
||||
continue
|
||||
}
|
||||
applied[m.Cid()] = true
|
||||
|
||||
_, err := vmi.ApplyMessage(ctx, m)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, sm := range sms {
|
||||
if applied[sm.Cid()] {
|
||||
continue
|
||||
}
|
||||
applied[sm.Cid()] = true
|
||||
|
||||
_, err := vmi.ApplyMessage(ctx, &sm.Message)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vmi.Flush(ctx)
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetActor(addr address.Address) (*types.Actor, error) {
|
||||
ts := sm.cs.GetHeaviestTipSet()
|
||||
stcid, err := sm.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, stcid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state.GetActor(addr)
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetBalance(addr address.Address) (types.BigInt, error) {
|
||||
act, err := sm.GetActor(addr)
|
||||
if err != nil {
|
||||
return types.BigInt{}, err
|
||||
}
|
||||
|
||||
return act.Balance, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) ChainStore() *store.ChainStore {
|
||||
return sm.cs
|
||||
}
|
||||
|
||||
func (sm *StateManager) LoadActorState(ctx context.Context, a address.Address, out interface{}) (*types.Actor, error) {
|
||||
act, err := sm.GetActor(a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(sm.cs.Blockstore())
|
||||
if err := cst.Get(ctx, act.Head, out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return act, nil
|
||||
|
||||
}
|
63
chain/stmgr/utils.go
Normal file
63
chain/stmgr/utils.go
Normal file
@ -0,0 +1,63 @@
|
||||
package stmgr
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func GetMinerWorker(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
recp, err := CallRaw(ctx, sm, &types.Message{
|
||||
To: maddr,
|
||||
From: maddr,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
}, st, 0)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("callRaw failed: %w", err)
|
||||
}
|
||||
|
||||
if recp.ExitCode != 0 {
|
||||
return address.Undef, xerrors.Errorf("getting miner worker addr failed (exit code %d)", recp.ExitCode)
|
||||
}
|
||||
|
||||
worker, err := address.NewFromBytes(recp.Return)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
if worker.Protocol() == address.ID {
|
||||
return address.Undef, xerrors.Errorf("need to resolve worker address to a pubkeyaddr")
|
||||
}
|
||||
|
||||
return worker, nil
|
||||
}
|
||||
|
||||
func GetMinerOwner(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
recp, err := CallRaw(ctx, sm, &types.Message{
|
||||
To: maddr,
|
||||
From: maddr,
|
||||
Method: actors.MAMethods.GetOwner,
|
||||
}, st, 0)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("callRaw failed: %w", err)
|
||||
}
|
||||
|
||||
if recp.ExitCode != 0 {
|
||||
return address.Undef, xerrors.Errorf("getting miner owner addr failed (exit code %d)", recp.ExitCode)
|
||||
}
|
||||
|
||||
owner, err := address.NewFromBytes(recp.Return)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
if owner.Protocol() == address.ID {
|
||||
return address.Undef, xerrors.Errorf("need to resolve owner address to a pubkeyaddr")
|
||||
}
|
||||
|
||||
return owner, nil
|
||||
}
|
@ -2,12 +2,11 @@ package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/state"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -462,21 +461,6 @@ func (cs *ChainStore) GetGenesis() (*types.BlockHeader, error) {
|
||||
return types.DecodeBlock(genb.RawData())
|
||||
}
|
||||
|
||||
func (cs *ChainStore) TipSetState(cids []cid.Cid) (cid.Cid, error) {
|
||||
ts, err := cs.LoadTipSet(cids)
|
||||
if err != nil {
|
||||
log.Error("failed loading tipset: ", cids)
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
if len(ts.Blocks()) == 1 {
|
||||
return ts.Blocks()[0].StateRoot, nil
|
||||
}
|
||||
|
||||
panic("cant handle multiblock tipsets yet")
|
||||
|
||||
}
|
||||
|
||||
func (cs *ChainStore) GetMessage(c cid.Cid) (*types.Message, error) {
|
||||
sb, err := cs.bs.Get(c)
|
||||
if err != nil {
|
||||
@ -604,31 +588,6 @@ func (cs *ChainStore) LoadSignedMessagesFromCids(cids []cid.Cid) ([]*types.Signe
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func (cs *ChainStore) GetBalance(addr address.Address) (types.BigInt, error) {
|
||||
act, err := cs.GetActor(addr)
|
||||
if err != nil {
|
||||
return types.BigInt{}, err
|
||||
}
|
||||
|
||||
return act.Balance, nil
|
||||
}
|
||||
|
||||
func (cs *ChainStore) GetActor(addr address.Address) (*types.Actor, error) {
|
||||
ts := cs.GetHeaviestTipSet()
|
||||
stcid, err := cs.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(cs.bs)
|
||||
state, err := state.LoadStateTree(cst, stcid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state.GetActor(addr)
|
||||
}
|
||||
|
||||
func (cs *ChainStore) WaitForMessage(ctx context.Context, mcid cid.Cid) (cid.Cid, *types.MessageReceipt, error) {
|
||||
tsub := cs.SubHeadChanges(ctx)
|
||||
|
||||
@ -737,3 +696,44 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
|
||||
}
|
||||
return NewFullTipSet(out), nil
|
||||
}
|
||||
|
||||
func (cs *ChainStore) GetRandomness(ctx context.Context, pts *types.TipSet, tickets []*types.Ticket, lb int) ([]byte, error) {
|
||||
if lb < len(tickets) {
|
||||
t := tickets[len(tickets)-(1+lb)]
|
||||
|
||||
return t.VDFResult, nil
|
||||
}
|
||||
|
||||
nv := lb - len(tickets)
|
||||
|
||||
for {
|
||||
fmt.Println("lookback looping: ", nv)
|
||||
nts, err := cs.LoadTipSet(pts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mtb := nts.MinTicketBlock()
|
||||
if nv < len(mtb.Tickets) {
|
||||
t := mtb.Tickets[len(mtb.Tickets)-(1+nv)]
|
||||
return t.VDFResult, nil
|
||||
}
|
||||
|
||||
nv -= len(mtb.Tickets)
|
||||
|
||||
// special case for lookback behind genesis block
|
||||
// TODO(spec): this is not in the spec, need to sync that
|
||||
if mtb.Height == 0 {
|
||||
fmt.Println("Randomness from height 0: ", nv)
|
||||
|
||||
t := mtb.Tickets[0]
|
||||
|
||||
rval := t.VDFResult
|
||||
for i := 0; i < nv; i++ {
|
||||
h := sha256.Sum256(rval)
|
||||
rval = h[:]
|
||||
}
|
||||
return rval, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
150
chain/sync.go
150
chain/sync.go
@ -11,6 +11,7 @@ import (
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||
@ -34,6 +35,9 @@ type Syncer struct {
|
||||
// The interface for accessing and putting tipsets into local storage
|
||||
store *store.ChainStore
|
||||
|
||||
// the state manager handles making state queries
|
||||
sm *stmgr.StateManager
|
||||
|
||||
// The known Genesis tipset
|
||||
Genesis *types.TipSet
|
||||
|
||||
@ -53,8 +57,8 @@ type Syncer struct {
|
||||
peerHeadsLk sync.Mutex
|
||||
}
|
||||
|
||||
func NewSyncer(cs *store.ChainStore, bsync *BlockSync, self peer.ID) (*Syncer, error) {
|
||||
gen, err := cs.GetGenesis()
|
||||
func NewSyncer(sm *stmgr.StateManager, bsync *BlockSync, self peer.ID) (*Syncer, error) {
|
||||
gen, err := sm.ChainStore().GetGenesis()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -68,7 +72,8 @@ func NewSyncer(cs *store.ChainStore, bsync *BlockSync, self peer.ID) (*Syncer, e
|
||||
Genesis: gent,
|
||||
Bsync: bsync,
|
||||
peerHeads: make(map[peer.ID]*types.TipSet),
|
||||
store: cs,
|
||||
store: sm.ChainStore(),
|
||||
sm: sm,
|
||||
self: self,
|
||||
}, nil
|
||||
}
|
||||
@ -320,7 +325,7 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
|
||||
return err
|
||||
}
|
||||
|
||||
ret, err := vm.Call(ctx, syncer.store, &types.Message{
|
||||
ret, err := stmgr.Call(ctx, syncer.sm, &types.Message{
|
||||
To: actors.StorageMarketAddress,
|
||||
From: maddr,
|
||||
Method: actors.SMAMethods.IsMiner,
|
||||
@ -353,7 +358,6 @@ func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Addre
|
||||
Data: next.VRFProof,
|
||||
}
|
||||
|
||||
log.Infof("About to verify signature: ", sig.Data, mworker, cur.VDFResult)
|
||||
if err := sig.Verify(mworker, cur.VDFResult); err != nil {
|
||||
return xerrors.Errorf("invalid ticket, VRFProof invalid: %w", err)
|
||||
}
|
||||
@ -369,62 +373,10 @@ func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Addre
|
||||
return nil
|
||||
}
|
||||
|
||||
func getMinerWorker(ctx context.Context, cs *store.ChainStore, st cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
recp, err := vm.CallRaw(ctx, cs, &types.Message{
|
||||
To: maddr,
|
||||
From: maddr,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
}, st, 0)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("callRaw failed: %w", err)
|
||||
}
|
||||
|
||||
if recp.ExitCode != 0 {
|
||||
return address.Undef, xerrors.Errorf("getting miner worker addr failed (exit code %d)", recp.ExitCode)
|
||||
}
|
||||
|
||||
worker, err := address.NewFromBytes(recp.Return)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
if worker.Protocol() == address.ID {
|
||||
return address.Undef, xerrors.Errorf("need to resolve worker address to a pubkeyaddr")
|
||||
}
|
||||
|
||||
return worker, nil
|
||||
}
|
||||
|
||||
func getMinerOwner(ctx context.Context, cs *store.ChainStore, st cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
recp, err := vm.CallRaw(ctx, cs, &types.Message{
|
||||
To: maddr,
|
||||
From: maddr,
|
||||
Method: actors.MAMethods.GetOwner,
|
||||
}, st, 0)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("callRaw failed: %w", err)
|
||||
}
|
||||
|
||||
if recp.ExitCode != 0 {
|
||||
return address.Undef, xerrors.Errorf("getting miner owner addr failed (exit code %d)", recp.ExitCode)
|
||||
}
|
||||
|
||||
owner, err := address.NewFromBytes(recp.Return)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
if owner.Protocol() == address.ID {
|
||||
return address.Undef, xerrors.Errorf("need to resolve owner address to a pubkeyaddr")
|
||||
}
|
||||
|
||||
return owner, nil
|
||||
}
|
||||
|
||||
// Should match up with 'Semantical Validation' in validation.md in the spec
|
||||
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error {
|
||||
h := b.Header
|
||||
stateroot, err := syncer.store.TipSetState(h.Parents)
|
||||
stateroot, err := syncer.sm.TipSetState(h.Parents)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get tipsetstate(%d, %s) failed: %w", h.Height, h.Parents, err)
|
||||
}
|
||||
@ -447,21 +399,39 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
||||
return xerrors.Errorf("minerIsValid failed: %w", err)
|
||||
}
|
||||
|
||||
waddr, err := getMinerWorker(ctx, syncer.store, stateroot, h.Miner)
|
||||
waddr, err := stmgr.GetMinerWorker(ctx, syncer.sm, stateroot, h.Miner)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getMinerWorker failed: %w", err)
|
||||
return xerrors.Errorf("GetMinerWorker failed: %w", err)
|
||||
}
|
||||
|
||||
if err := syncer.validateTickets(ctx, waddr, h.Tickets, baseTs); err != nil {
|
||||
return xerrors.Errorf("validating block tickets failed: %w", err)
|
||||
}
|
||||
|
||||
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs, h.Tickets, build.RandomnessLookback)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err)
|
||||
}
|
||||
|
||||
if err := VerifyElectionProof(ctx, h.ElectionProof, rand, waddr); err != nil {
|
||||
return xerrors.Errorf("checking eproof failed: %w", err)
|
||||
}
|
||||
|
||||
mpow, tpow, err := GetPower(ctx, syncer.sm, baseTs, h.Miner)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed getting power: %w", err)
|
||||
}
|
||||
|
||||
if !types.PowerCmp(h.ElectionProof, mpow, tpow) {
|
||||
return xerrors.Errorf("miner created a block but was not a winner")
|
||||
}
|
||||
|
||||
vmi, err := vm.NewVM(stateroot, h.Height, h.Miner, syncer.store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to instantiate VM: %w", err)
|
||||
}
|
||||
|
||||
owner, err := getMinerOwner(ctx, syncer.store, stateroot, b.Header.Miner)
|
||||
owner, err := stmgr.GetMinerOwner(ctx, syncer.sm, stateroot, b.Header.Miner)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner owner for block miner failed: %w", err)
|
||||
}
|
||||
@ -572,7 +542,7 @@ func (syncer *Syncer) collectHeaders(from *types.TipSet, to *types.TipSet) ([]*t
|
||||
|
||||
func (syncer *Syncer) syncMessagesAndCheckState(headers []*types.TipSet) error {
|
||||
return syncer.iterFullTipsets(headers, func(fts *store.FullTipSet) error {
|
||||
log.Warn("validating tipset: ", fts.TipSet().Height())
|
||||
log.Warnf("validating tipset (heigt=%d, size=%d)", fts.TipSet().Height(), len(fts.TipSet().Cids()))
|
||||
if err := syncer.ValidateTipSet(context.TODO(), fts); err != nil {
|
||||
log.Errorf("failed to validate tipset: %s", err)
|
||||
return xerrors.Errorf("message processing failed: %w", err)
|
||||
@ -692,3 +662,59 @@ func (syncer *Syncer) collectChain(fts *store.FullTipSet) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func VerifyElectionProof(ctx context.Context, eproof []byte, rand []byte, worker address.Address) error {
|
||||
sig := types.Signature{
|
||||
Data: eproof,
|
||||
Type: types.KTBLS,
|
||||
}
|
||||
|
||||
if err := sig.Verify(worker, rand); err != nil {
|
||||
return xerrors.Errorf("failed to verify election proof signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetPower(ctx context.Context, sm *stmgr.StateManager, ts *types.TipSet, maddr address.Address) (types.BigInt, types.BigInt, error) {
|
||||
var err error
|
||||
enc, err := actors.SerializeParams(&actors.PowerLookupParams{maddr})
|
||||
if err != nil {
|
||||
return types.EmptyInt, types.EmptyInt, err
|
||||
}
|
||||
|
||||
var mpow types.BigInt
|
||||
|
||||
if maddr != address.Undef {
|
||||
ret, err := stmgr.Call(ctx, sm, &types.Message{
|
||||
From: maddr,
|
||||
To: actors.StorageMarketAddress,
|
||||
Method: actors.SMAMethods.PowerLookup,
|
||||
Params: enc,
|
||||
}, ts)
|
||||
if err != nil {
|
||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get miner power from chain: %w", err)
|
||||
}
|
||||
if ret.ExitCode != 0 {
|
||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get miner power from chain (exit code %d)", ret.ExitCode)
|
||||
}
|
||||
|
||||
mpow = types.BigFromBytes(ret.Return)
|
||||
}
|
||||
|
||||
ret, err := stmgr.Call(ctx, sm, &types.Message{
|
||||
From: actors.StorageMarketAddress,
|
||||
To: actors.StorageMarketAddress,
|
||||
Method: actors.SMAMethods.GetTotalStorage,
|
||||
}, ts)
|
||||
if err != nil {
|
||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err)
|
||||
}
|
||||
if ret.ExitCode != 0 {
|
||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain (exit code %d)", ret.ExitCode)
|
||||
}
|
||||
|
||||
tpow := types.BigFromBytes(ret.Return)
|
||||
|
||||
return mpow, tpow, nil
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"math/big"
|
||||
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -87,6 +89,10 @@ func (blk *BlockHeader) Serialize() ([]byte, error) {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (blk *BlockHeader) LastTicket() *Ticket {
|
||||
return blk.Tickets[len(blk.Tickets)-1]
|
||||
}
|
||||
|
||||
type MsgMeta struct {
|
||||
BlsMessages cid.Cid
|
||||
SecpkMessages cid.Cid
|
||||
@ -126,3 +132,21 @@ func CidArrsEqual(a, b []cid.Cid) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func PowerCmp(eproof ElectionProof, mpow, totpow BigInt) bool {
|
||||
|
||||
/*
|
||||
Need to check that
|
||||
h(vrfout) / 2^256 < minerPower / totalPower
|
||||
*/
|
||||
|
||||
h := sha256.Sum256(eproof)
|
||||
|
||||
// 2^256
|
||||
rden := BigInt{big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), nil)}
|
||||
|
||||
top := BigMul(rden, mpow)
|
||||
out := BigDiv(top, totpow)
|
||||
|
||||
return BigCmp(BigFromBytes(h[:]), out) < 0
|
||||
}
|
||||
|
@ -96,19 +96,13 @@ func (ts *TipSet) Equals(ots *TipSet) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (ts *TipSet) MinTicket() *Ticket {
|
||||
if len(ts.Blocks()) == 0 {
|
||||
panic("tipset has no blocks!")
|
||||
}
|
||||
var minTicket *Ticket
|
||||
for _, b := range ts.Blocks() {
|
||||
lastTicket := b.Tickets[len(b.Tickets)-1]
|
||||
if minTicket == nil || bytes.Compare(lastTicket.VDFResult, minTicket.VDFResult) < 0 {
|
||||
minTicket = lastTicket
|
||||
}
|
||||
}
|
||||
func (t *Ticket) Less(o *Ticket) bool {
|
||||
return bytes.Compare(t.VDFResult, o.VDFResult) < 0
|
||||
}
|
||||
|
||||
return minTicket
|
||||
func (ts *TipSet) MinTicket() *Ticket {
|
||||
b := ts.MinTicketBlock()
|
||||
return b.Tickets[len(b.Tickets)-1]
|
||||
}
|
||||
|
||||
func (ts *TipSet) MinTimestamp() uint64 {
|
||||
@ -120,3 +114,17 @@ func (ts *TipSet) MinTimestamp() uint64 {
|
||||
}
|
||||
return minTs
|
||||
}
|
||||
|
||||
func (ts *TipSet) MinTicketBlock() *BlockHeader {
|
||||
blks := ts.Blocks()
|
||||
|
||||
min := blks[0]
|
||||
|
||||
for _, b := range blks[1:] {
|
||||
if b.LastTicket().Less(min.LastTicket()) {
|
||||
min = b
|
||||
}
|
||||
}
|
||||
|
||||
return min
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint6
|
||||
|
||||
code, ok := inv.builtInCode[act.Code]
|
||||
if !ok {
|
||||
fmt.Println("bad code? ", act.Code)
|
||||
fmt.Println("miner actor code cid: ", actors.StorageMinerCodeCid)
|
||||
return nil, aerrors.Newf(255, "no code for actor %s", act.Code)
|
||||
}
|
||||
if method >= uint64(len(code)) || code[method] == nil {
|
||||
|
@ -454,6 +454,10 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (vm *VM) SetBlockMiner(m address.Address) {
|
||||
vm.blockMiner = m
|
||||
}
|
||||
|
||||
func (vm *VM) ActorBalance(addr address.Address) (types.BigInt, aerrors.ActorError) {
|
||||
act, err := vm.cstate.GetActor(addr)
|
||||
if err != nil {
|
||||
|
@ -143,7 +143,7 @@ func configureStorageMiner(ctx context.Context, api api.FullNode, addr address.A
|
||||
}
|
||||
|
||||
// This really just needs to be an api call at this point...
|
||||
recp, err := api.ChainCall(ctx, &types.Message{
|
||||
recp, err := api.StateCall(ctx, &types.Message{
|
||||
To: addr,
|
||||
From: addr,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
|
@ -232,7 +232,7 @@ func (m *Miner) computeVRF(ctx context.Context, input []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (m *Miner) getMinerWorker(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
ret, err := m.api.ChainCall(ctx, &types.Message{
|
||||
ret, err := m.api.StateCall(ctx, &types.Message{
|
||||
From: addr,
|
||||
To: addr,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/chain"
|
||||
"github.com/filecoin-project/go-lotus/chain/deals"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||
@ -201,6 +202,7 @@ func Online() Option {
|
||||
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
||||
|
||||
Override(new(*store.ChainStore), modules.ChainStore),
|
||||
Override(new(*stmgr.StateManager), stmgr.NewStateManager),
|
||||
Override(new(*wallet.Wallet), wallet.NewWallet),
|
||||
|
||||
Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker),
|
||||
|
@ -5,17 +5,11 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/chain"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/gen"
|
||||
"github.com/filecoin-project/go-lotus/chain/state"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||
"github.com/filecoin-project/go-lotus/lib/bufbstore"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-hamt-ipld"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
@ -51,9 +45,8 @@ func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) {
|
||||
return a.Chain.GetHeaviestTipSet(), nil
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts *types.TipSet) ([]byte, error) {
|
||||
// TODO: this needs to look back in the chain for the right random beacon value
|
||||
return []byte("foo bar random"), nil
|
||||
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts *types.TipSet, tickets []*types.Ticket, lb int) ([]byte, error) {
|
||||
return a.Chain.GetRandomness(ctx, pts, tickets, lb)
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait, error) {
|
||||
@ -113,72 +106,3 @@ func (a *ChainAPI) ChainGetBlockReceipts(ctx context.Context, bcid cid.Cid) ([]*
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
return vm.Call(ctx, a.Chain, msg, ts)
|
||||
}
|
||||
|
||||
func (a *ChainAPI) stateForTs(ts *types.TipSet) (*state.StateTree, error) {
|
||||
if ts == nil {
|
||||
ts = a.Chain.GetHeaviestTipSet()
|
||||
}
|
||||
|
||||
st, err := a.Chain.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := bufbstore.NewBufferedBstore(a.Chain.Blockstore())
|
||||
cst := hamt.CSTFromBstore(buf)
|
||||
return state.LoadStateTree(cst, st)
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
state, err := a.stateForTs(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state.GetActor(actor)
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) {
|
||||
state, err := a.stateForTs(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blk, err := state.Store.Blocks.GetBlock(ctx, act.Head)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oif, err := vm.DumpActorState(act.Code, blk.RawData())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &api.ActorState{
|
||||
Balance: act.Balance,
|
||||
State: oif,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// This is on ChainAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
|
||||
func (a *ChainAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, tickets []*types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage, ts uint64) (*chain.BlockMsg, error) {
|
||||
fblk, err := gen.MinerCreateBlock(ctx, a.Chain, a.Wallet, addr, parents, tickets, proof, msgs, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out chain.BlockMsg
|
||||
out.Header = fblk.Header
|
||||
for _, msg := range fblk.BlsMessages {
|
||||
out.BlsMessages = append(out.BlsMessages, msg.Cid())
|
||||
}
|
||||
for _, msg := range fblk.SecpkMessages {
|
||||
out.SecpkMessages = append(out.SecpkMessages, msg.Cid())
|
||||
}
|
||||
|
||||
return &out, nil
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ type ClientAPI struct {
|
||||
fx.In
|
||||
|
||||
ChainAPI
|
||||
StateAPI
|
||||
WalletAPI
|
||||
PaychAPI
|
||||
|
||||
@ -62,7 +63,7 @@ func (a *ClientAPI) ClientStartDeal(ctx context.Context, data cid.Cid, miner add
|
||||
Method: actors.MAMethods.GetPeerID,
|
||||
}
|
||||
|
||||
r, err := a.ChainCall(ctx, msg, nil)
|
||||
r, err := a.StateCall(ctx, msg, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -5,15 +5,20 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain"
|
||||
"github.com/filecoin-project/go-lotus/chain/gen"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||
"github.com/filecoin-project/go-lotus/lib/bufbstore"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/state"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
|
||||
"github.com/ipfs/go-hamt-ipld"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
@ -23,18 +28,23 @@ import (
|
||||
type StateAPI struct {
|
||||
fx.In
|
||||
|
||||
Chain *store.ChainStore
|
||||
// TODO: the wallet here is only needed because we have the MinerCreateBlock
|
||||
// API attached to the state API. It probably should live somewhere better
|
||||
Wallet *wallet.Wallet
|
||||
|
||||
StateManager *stmgr.StateManager
|
||||
Chain *store.ChainStore
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address) ([]*api.SectorInfo, error) {
|
||||
ts := a.Chain.GetHeaviestTipSet()
|
||||
ts := a.StateManager.ChainStore().GetHeaviestTipSet()
|
||||
|
||||
stc, err := a.Chain.TipSetState(ts.Cids())
|
||||
stc, err := a.StateManager.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(a.Chain.Blockstore())
|
||||
cst := hamt.CSTFromBstore(a.StateManager.ChainStore().Blockstore())
|
||||
|
||||
st, err := state.LoadStateTree(cst, stc)
|
||||
if err != nil {
|
||||
@ -87,7 +97,7 @@ func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address)
|
||||
func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address) ([]*api.SectorInfo, error) {
|
||||
ts := a.Chain.GetHeaviestTipSet()
|
||||
|
||||
stc, err := a.Chain.TipSetState(ts.Cids())
|
||||
stc, err := a.StateManager.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -152,7 +162,7 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, t
|
||||
var mpow types.BigInt
|
||||
|
||||
if maddr != address.Undef {
|
||||
ret, err := vm.Call(ctx, a.Chain, &types.Message{
|
||||
ret, err := stmgr.Call(ctx, a.StateManager, &types.Message{
|
||||
From: maddr,
|
||||
To: actors.StorageMarketAddress,
|
||||
Method: actors.SMAMethods.PowerLookup,
|
||||
@ -168,7 +178,7 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, t
|
||||
mpow = types.BigFromBytes(ret.Return)
|
||||
}
|
||||
|
||||
ret, err := vm.Call(ctx, a.Chain, &types.Message{
|
||||
ret, err := stmgr.Call(ctx, a.StateManager, &types.Message{
|
||||
From: actors.StorageMarketAddress,
|
||||
To: actors.StorageMarketAddress,
|
||||
Method: actors.SMAMethods.GetTotalStorage,
|
||||
@ -189,7 +199,7 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, t
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerWorker(ctx context.Context, m address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
ret, err := vm.Call(ctx, a.Chain, &types.Message{
|
||||
ret, err := stmgr.Call(ctx, a.StateManager, &types.Message{
|
||||
From: m,
|
||||
To: m,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
@ -209,3 +219,72 @@ func (a *StateAPI) StateMinerWorker(ctx context.Context, m address.Address, ts *
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
return stmgr.Call(ctx, a.StateManager, msg, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) stateForTs(ts *types.TipSet) (*state.StateTree, error) {
|
||||
if ts == nil {
|
||||
ts = a.Chain.GetHeaviestTipSet()
|
||||
}
|
||||
|
||||
st, err := a.StateManager.TipSetState(ts.Cids())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := bufbstore.NewBufferedBstore(a.Chain.Blockstore())
|
||||
cst := hamt.CSTFromBstore(buf)
|
||||
return state.LoadStateTree(cst, st)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
state, err := a.stateForTs(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state.GetActor(actor)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) {
|
||||
state, err := a.stateForTs(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blk, err := state.Store.Blocks.GetBlock(ctx, act.Head)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oif, err := vm.DumpActorState(act.Code, blk.RawData())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &api.ActorState{
|
||||
Balance: act.Balance,
|
||||
State: oif,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
|
||||
func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, tickets []*types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage, ts uint64) (*chain.BlockMsg, error) {
|
||||
fblk, err := gen.MinerCreateBlock(ctx, a.StateManager, a.Wallet, addr, parents, tickets, proof, msgs, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out chain.BlockMsg
|
||||
out.Header = fblk.Header
|
||||
for _, msg := range fblk.BlsMessages {
|
||||
out.BlsMessages = append(out.BlsMessages, msg.Cid())
|
||||
}
|
||||
for _, msg := range fblk.SecpkMessages {
|
||||
out.SecpkMessages = append(out.SecpkMessages, msg.Cid())
|
||||
}
|
||||
|
||||
return &out, nil
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||
|
||||
@ -15,8 +15,8 @@ import (
|
||||
type WalletAPI struct {
|
||||
fx.In
|
||||
|
||||
Chain *store.ChainStore
|
||||
Wallet *wallet.Wallet
|
||||
StateManager *stmgr.StateManager
|
||||
Wallet *wallet.Wallet
|
||||
}
|
||||
|
||||
func (a *WalletAPI) WalletNew(ctx context.Context, typ string) (address.Address, error) {
|
||||
@ -32,7 +32,7 @@ func (a *WalletAPI) WalletList(ctx context.Context) ([]address.Address, error) {
|
||||
}
|
||||
|
||||
func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) {
|
||||
return a.Chain.GetBalance(addr)
|
||||
return a.StateManager.GetBalance(addr)
|
||||
}
|
||||
|
||||
func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*types.Signature, error) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/go-lotus/paych"
|
||||
)
|
||||
@ -10,6 +10,6 @@ func PaychStore(ds dtypes.MetadataDS) *paych.Store {
|
||||
return paych.NewStore(ds)
|
||||
}
|
||||
|
||||
func PaymentChannelManager(chain *store.ChainStore, store *paych.Store) (*paych.Manager, error) {
|
||||
return paych.NewManager(chain, store), nil
|
||||
func PaymentChannelManager(sm *stmgr.StateManager, store *paych.Store) (*paych.Manager, error) {
|
||||
return paych.NewManager(sm, store), nil
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/gen"
|
||||
@ -34,8 +35,9 @@ func MakeGenesisMem(out io.Writer) func(bs dtypes.ChainBlockstore, w *wallet.Wal
|
||||
}
|
||||
|
||||
gmc := &gen.GenMinerCfg{
|
||||
Owner: w,
|
||||
Worker: w,
|
||||
Owners: []address.Address{w},
|
||||
Workers: []address.Address{w},
|
||||
PeerIDs: []peer.ID{"peerID 1"},
|
||||
}
|
||||
alloc := map[address.Address]types.BigInt{
|
||||
w: types.NewInt(100000),
|
||||
@ -68,8 +70,9 @@ func MakeGenesis(outFile string) func(bs dtypes.ChainBlockstore, w *wallet.Walle
|
||||
}
|
||||
|
||||
gmc := &gen.GenMinerCfg{
|
||||
Owner: minerAddr,
|
||||
Worker: minerAddr,
|
||||
Owners: []address.Address{minerAddr},
|
||||
Workers: []address.Address{minerAddr},
|
||||
PeerIDs: []peer.ID{"peer ID 1"},
|
||||
}
|
||||
|
||||
addrs := map[address.Address]types.BigInt{
|
||||
@ -81,7 +84,7 @@ func MakeGenesis(outFile string) func(bs dtypes.ChainBlockstore, w *wallet.Walle
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("GENESIS MINER ADDRESS: ", gmc.MinerAddr.String())
|
||||
fmt.Println("GENESIS MINER ADDRESS: ", gmc.MinerAddrs[0].String())
|
||||
|
||||
f, err := os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
|
@ -4,28 +4,25 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
logging "github.com/ipfs/go-log"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/state"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||
)
|
||||
|
||||
var log = logging.Logger("paych")
|
||||
|
||||
type Manager struct {
|
||||
chain *store.ChainStore
|
||||
store *Store
|
||||
sm *stmgr.StateManager
|
||||
}
|
||||
|
||||
func NewManager(chain *store.ChainStore, pchstore *Store) *Manager {
|
||||
func NewManager(sm *stmgr.StateManager, pchstore *Store) *Manager {
|
||||
return &Manager{
|
||||
chain: chain,
|
||||
store: pchstore,
|
||||
sm: sm,
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +145,7 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address
|
||||
return false, err
|
||||
}
|
||||
|
||||
ret, err := vm.Call(ctx, pm.chain, &types.Message{
|
||||
ret, err := stmgr.Call(ctx, pm.sm, &types.Message{
|
||||
From: owner,
|
||||
To: ch,
|
||||
Method: actors.PCAMethods.UpdateChannelState,
|
||||
@ -166,24 +163,9 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address
|
||||
}
|
||||
|
||||
func (pm *Manager) loadPaychState(ctx context.Context, ch address.Address) (*types.Actor, *actors.PaymentChannelActorState, error) {
|
||||
st, err := pm.chain.TipSetState(pm.chain.GetHeaviestTipSet().Cids())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(pm.chain.Blockstore())
|
||||
tree, err := state.LoadStateTree(cst, st)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
act, err := tree.GetActor(ch)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pcast actors.PaymentChannelActorState
|
||||
if err := cst.Get(ctx, act.Head, &pcast); err != nil {
|
||||
act, err := pm.sm.LoadActorState(ctx, ch, &pcast)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@ -191,7 +173,7 @@ func (pm *Manager) loadPaychState(ctx context.Context, ch address.Address) (*typ
|
||||
}
|
||||
|
||||
func (pm *Manager) getPaychOwner(ctx context.Context, ch address.Address) (address.Address, error) {
|
||||
ret, err := vm.Call(ctx, pm.chain, &types.Message{
|
||||
ret, err := stmgr.Call(ctx, pm.sm, &types.Message{
|
||||
From: ch,
|
||||
To: ch,
|
||||
Method: actors.PCAMethods.GetOwner,
|
||||
|
@ -41,7 +41,7 @@ type storageMinerApi interface {
|
||||
//ReadState(ctx context.Context, addr address.Address) (????, error)
|
||||
|
||||
// Call a read only method on actors (no interaction with the chain required)
|
||||
ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error)
|
||||
StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error)
|
||||
|
||||
MpoolPush(context.Context, *types.SignedMessage) error
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||
@ -201,7 +201,7 @@ func (m *Miner) getWorkerAddr(ctx context.Context) (address.Address, error) {
|
||||
Params: actors.EmptyStructCBOR,
|
||||
}
|
||||
|
||||
recpt, err := m.api.ChainCall(ctx, msg, nil)
|
||||
recpt, err := m.api.StateCall(ctx, msg, nil)
|
||||
if err != nil {
|
||||
return address.Undef, errors.Wrapf(err, "calling getWorker(%s)", m.maddr)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user