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)
|
ChainNotify(context.Context) (<-chan *store.HeadChange, error)
|
||||||
ChainHead(context.Context) (*types.TipSet, error) // TODO: check serialization
|
ChainHead(context.Context) (*types.TipSet, error) // TODO: check serialization
|
||||||
ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) 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)
|
ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error)
|
||||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||||
ChainGetBlockReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, 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
|
// messages
|
||||||
|
|
||||||
@ -107,6 +102,10 @@ type FullNode interface {
|
|||||||
StateMinerProvingSet(context.Context, address.Address) ([]*SectorInfo, error)
|
StateMinerProvingSet(context.Context, address.Address) ([]*SectorInfo, error)
|
||||||
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
|
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
|
||||||
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, 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)
|
PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (address.Address, error)
|
||||||
PaychList(context.Context) ([]address.Address, error)
|
PaychList(context.Context) ([]address.Address, error)
|
||||||
|
@ -39,17 +39,14 @@ type FullNodeStruct struct {
|
|||||||
CommonStruct
|
CommonStruct
|
||||||
|
|
||||||
Internal struct {
|
Internal struct {
|
||||||
ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"`
|
ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"`
|
||||||
ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"`
|
ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"`
|
||||||
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||||
ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, 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"`
|
ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"`
|
||||||
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
|
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
|
||||||
ChainGetBlockReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, 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"`
|
|
||||||
|
|
||||||
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
||||||
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"`
|
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"`
|
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"`
|
ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"`
|
||||||
|
|
||||||
StateMinerSectors func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
StateMinerSectors func(context.Context, address.Address) ([]*SectorInfo, error) `perm:"read"`
|
||||||
StateMinerProvingSet 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"`
|
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"`
|
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"`
|
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"`
|
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)
|
return c.Internal.ChainHead(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts *types.TipSet) ([]byte, error) {
|
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts *types.TipSet, ticks []*types.Ticket, lb int) ([]byte, error) {
|
||||||
return c.Internal.ChainGetRandomness(ctx, pts)
|
return c.Internal.ChainGetRandomness(ctx, pts, ticks, lb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) ChainWaitMsg(ctx context.Context, msgc cid.Cid) (*MsgWait, error) {
|
func (c *FullNodeStruct) ChainWaitMsg(ctx context.Context, msgc cid.Cid) (*MsgWait, error) {
|
||||||
return c.Internal.ChainWaitMsg(ctx, msgc)
|
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) {
|
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ string) (address.Address, error) {
|
||||||
return c.Internal.WalletNew(ctx, typ)
|
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)
|
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) {
|
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)
|
return c.Internal.PaychCreate(ctx, from, to, amt)
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,6 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours
|
|||||||
const DealVoucherSkewLimit = 10
|
const DealVoucherSkewLimit = 10
|
||||||
|
|
||||||
const ForkLengthThreshold = 20
|
const ForkLengthThreshold = 20
|
||||||
|
const RandomnessLookback = 20
|
||||||
|
|
||||||
// TODO: Move other important consts here
|
// TODO: Move other important consts here
|
||||||
|
@ -77,7 +77,7 @@ func (h *Handler) sendSignedResponse(resp StorageDealResponse) error {
|
|||||||
From: h.actor,
|
From: h.actor,
|
||||||
Method: actors.MAMethods.GetWorkerAddr,
|
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 {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting worker address: %w", err)
|
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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/ipfs/go-blockservice"
|
"github.com/ipfs/go-blockservice"
|
||||||
"github.com/ipfs/go-car"
|
"github.com/ipfs/go-car"
|
||||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||||
"github.com/ipfs/go-merkledag"
|
"github.com/ipfs/go-merkledag"
|
||||||
|
peer "github.com/libp2p/go-libp2p-peer"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/api"
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/build"
|
"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/address"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/go-lotus/chain/store"
|
"github.com/filecoin-project/go-lotus/chain/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||||
@ -41,8 +43,10 @@ type ChainGen struct {
|
|||||||
|
|
||||||
cs *store.ChainStore
|
cs *store.ChainStore
|
||||||
|
|
||||||
genesis *types.BlockHeader
|
sm *stmgr.StateManager
|
||||||
curBlock *types.FullBlock
|
|
||||||
|
genesis *types.BlockHeader
|
||||||
|
curTipset *store.FullTipSet
|
||||||
|
|
||||||
w *wallet.Wallet
|
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{
|
minercfg := &GenMinerCfg{
|
||||||
Worker: worker,
|
Workers: []address.Address{worker},
|
||||||
Owner: worker,
|
Owners: []address.Address{worker},
|
||||||
|
PeerIDs: []peer.ID{"peerID1"},
|
||||||
}
|
}
|
||||||
|
|
||||||
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
|
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
|
||||||
@ -134,28 +146,32 @@ func NewGenerator() (*ChainGen, error) {
|
|||||||
cs := store.NewChainStore(bs, ds)
|
cs := store.NewChainStore(bs, ds)
|
||||||
|
|
||||||
genfb := &types.FullBlock{Header: genb.Genesis}
|
genfb := &types.FullBlock{Header: genb.Genesis}
|
||||||
|
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
|
||||||
|
|
||||||
if err := cs.SetGenesis(genb.Genesis); err != nil {
|
if err := cs.SetGenesis(genb.Genesis); err != nil {
|
||||||
return nil, xerrors.Errorf("set genesis failed: %w", err)
|
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")
|
return nil, xerrors.Errorf("MakeGenesisBlock failed to set miner address")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sm := stmgr.NewStateManager(cs)
|
||||||
|
|
||||||
gen := &ChainGen{
|
gen := &ChainGen{
|
||||||
bs: bs,
|
bs: bs,
|
||||||
cs: cs,
|
cs: cs,
|
||||||
|
sm: sm,
|
||||||
msgsPerBlock: msgsPerBlock,
|
msgsPerBlock: msgsPerBlock,
|
||||||
genesis: genb.Genesis,
|
genesis: genb.Genesis,
|
||||||
w: w,
|
w: w,
|
||||||
|
|
||||||
miners: []address.Address{minercfg.MinerAddr},
|
miners: minercfg.MinerAddrs,
|
||||||
mworkers: []address.Address{worker},
|
mworkers: minercfg.Workers,
|
||||||
banker: banker,
|
banker: banker,
|
||||||
receivers: receievers,
|
receivers: receievers,
|
||||||
|
|
||||||
curBlock: genfb,
|
curTipset: gents,
|
||||||
|
|
||||||
r: mr,
|
r: mr,
|
||||||
lr: lr,
|
lr: lr,
|
||||||
@ -182,19 +198,35 @@ func (cg *ChainGen) GenesisCar() ([]byte, error) {
|
|||||||
return out.Bytes(), nil
|
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
|
fmt.Println("checking winner:", m, ticks)
|
||||||
lastTicket := ticks[len(ticks)-1]
|
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 {
|
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)
|
out, proof, err := vdf.Run(vrfout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tick := &types.Ticket{
|
tick := &types.Ticket{
|
||||||
@ -203,7 +235,15 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context) (address.Address, types.
|
|||||||
VDFResult: out,
|
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 {
|
type MinedTipSet struct {
|
||||||
@ -212,13 +252,64 @@ type MinedTipSet struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
msgs := make([]*types.SignedMessage, cg.msgsPerBlock)
|
||||||
for m := range msgs {
|
for m := range msgs {
|
||||||
msg := types.Message{
|
msg := types.Message{
|
||||||
@ -255,30 +346,7 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create block
|
return msgs, nil
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
|
func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
|
||||||
@ -289,7 +357,7 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MiningCheckAPI interface {
|
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)
|
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)
|
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) {
|
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 {
|
if err != nil {
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println("chain randomness: ", r)
|
||||||
mworker, err := a.StateMinerWorker(ctx, miner, ts)
|
mworker, err := a.StateMinerWorker(ctx, miner, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, xerrors.Errorf("failed to get miner worker: %w", err)
|
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 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)
|
||||||
|
|
||||||
/*
|
func ComputeVRF(ctx context.Context, sign SignFunc, w address.Address, input []byte) ([]byte, error) {
|
||||||
Need to check that
|
sig, err := sign(ctx, w, input)
|
||||||
h(vrfout) / 2^256 < minerPower / totalPower
|
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
|
return sig.Data, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package gen
|
package gen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,11 +14,12 @@ func testGeneration(t testing.TB, n int, msgs int) {
|
|||||||
g.msgsPerBlock = msgs
|
g.msgsPerBlock = msgs
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
|
fmt.Println("LOOP: ", i)
|
||||||
mts, err := g.NextTipSet()
|
mts, err := g.NextTipSet()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error at H:%d, %s", i, err)
|
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")
|
t.Fatal("wrong height")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,31 +11,31 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"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/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
"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) {
|
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 := cs.TipSetState(parents.Cids())
|
st, err := sm.TipSetState(parents.Cids())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to load tipset state")
|
return nil, errors.Wrap(err, "failed to load tipset state")
|
||||||
}
|
}
|
||||||
|
|
||||||
height := parents.Height() + uint64(len(tickets))
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
owner, err := getMinerOwner(ctx, cs, st, miner)
|
owner, err := stmgr.GetMinerOwner(ctx, sm, st, miner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to get miner owner: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
|
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{
|
next := &types.BlockHeader{
|
||||||
Miner: miner,
|
Miner: miner,
|
||||||
Parents: parents.Cids(),
|
Parents: parents.Cids(),
|
||||||
Tickets: tickets,
|
Tickets: tickets,
|
||||||
Height: height,
|
Height: height,
|
||||||
Timestamp: timestamp,
|
Timestamp: timestamp,
|
||||||
|
ElectionProof: proof,
|
||||||
}
|
}
|
||||||
|
|
||||||
var blsMessages []*types.Message
|
var blsMessages []*types.Message
|
||||||
@ -63,7 +64,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
|||||||
blsSigs = append(blsSigs, msg.Signature)
|
blsSigs = append(blsSigs, msg.Signature)
|
||||||
blsMessages = append(blsMessages, &msg.Message)
|
blsMessages = append(blsMessages, &msg.Message)
|
||||||
|
|
||||||
c, err := cs.PutMessage(&msg.Message)
|
c, err := sm.ChainStore().PutMessage(&msg.Message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -93,7 +94,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
|||||||
receipts = append(receipts, rec.MessageReceipt)
|
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)
|
blsmsgroot, err := sharray.Build(context.TODO(), 4, toIfArr(blsMsgCids), cst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -130,7 +131,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
|||||||
|
|
||||||
next.BLSAggregate = aggSig
|
next.BLSAggregate = aggSig
|
||||||
next.StateRoot = stateRoot
|
next.StateRoot = stateRoot
|
||||||
pweight := cs.Weight(parents)
|
pweight := sm.ChainStore().Weight(parents)
|
||||||
next.ParentWeight = types.NewInt(pweight)
|
next.ParentWeight = types.NewInt(pweight)
|
||||||
|
|
||||||
// TODO: set timestamp
|
// TODO: set timestamp
|
||||||
@ -161,40 +162,6 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, w *wallet.Walle
|
|||||||
return fullBlock, nil
|
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) {
|
func aggregateSignatures(sigs []types.Signature) (types.Signature, error) {
|
||||||
var blsSigs []bls.Signature
|
var blsSigs []bls.Signature
|
||||||
for _, s := range sigs {
|
for _, s := range sigs {
|
||||||
|
@ -140,16 +140,16 @@ func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GenMinerCfg struct {
|
type GenMinerCfg struct {
|
||||||
Owner address.Address
|
Owners []address.Address
|
||||||
Worker address.Address
|
Workers []address.Address
|
||||||
|
|
||||||
// not quite generating real sectors yet, but this will be necessary
|
// not quite generating real sectors yet, but this will be necessary
|
||||||
//SectorDir string
|
//SectorDir string
|
||||||
|
|
||||||
// The address of the created miner, this is set by the genesis setup
|
// The addresses of the created miner, this is set by the genesis setup
|
||||||
MinerAddr address.Address
|
MinerAddrs []address.Address
|
||||||
|
|
||||||
PeerID peer.ID
|
PeerIDs []peer.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustEnc(i interface{}) []byte {
|
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)
|
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
params := mustEnc(actors.CreateStorageMinerParams{
|
for i := 0; i < len(gmcfg.Workers); i++ {
|
||||||
Owner: gmcfg.Owner,
|
owner := gmcfg.Owners[i]
|
||||||
Worker: gmcfg.Worker,
|
worker := gmcfg.Workers[i]
|
||||||
SectorSize: types.NewInt(build.SectorSize),
|
pid := gmcfg.PeerIDs[i]
|
||||||
PeerID: gmcfg.PeerID,
|
|
||||||
})
|
|
||||||
|
|
||||||
rval, err := doExec(ctx, vm, actors.StorageMarketAddress, gmcfg.Owner, actors.SMAMethods.CreateStorageMiner, params)
|
params := mustEnc(actors.CreateStorageMinerParams{
|
||||||
if err != nil {
|
Owner: owner,
|
||||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
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)
|
return vm.Flush(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uint64, params []byte) ([]byte, error) {
|
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{
|
ret, err := vm.ApplyMessage(context.TODO(), &types.Message{
|
||||||
To: to,
|
To: to,
|
||||||
From: from,
|
From: from,
|
||||||
@ -235,6 +246,7 @@ func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uin
|
|||||||
GasLimit: types.NewInt(1000000),
|
GasLimit: types.NewInt(1000000),
|
||||||
GasPrice: types.NewInt(0),
|
GasPrice: types.NewInt(0),
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
|
Nonce: act.Nonce,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -322,19 +334,3 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
|
|||||||
Genesis: b,
|
Genesis: b,
|
||||||
}, nil
|
}, 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"
|
"sync"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"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/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -15,7 +15,7 @@ type MessagePool struct {
|
|||||||
|
|
||||||
pending map[address.Address]*msgSet
|
pending map[address.Address]*msgSet
|
||||||
|
|
||||||
cs *store.ChainStore
|
sm *stmgr.StateManager
|
||||||
}
|
}
|
||||||
|
|
||||||
type msgSet struct {
|
type msgSet struct {
|
||||||
@ -36,12 +36,12 @@ func (ms *msgSet) add(m *types.SignedMessage) {
|
|||||||
ms.msgs[m.Message.Nonce] = m
|
ms.msgs[m.Message.Nonce] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMessagePool(cs *store.ChainStore) *MessagePool {
|
func NewMessagePool(sm *stmgr.StateManager) *MessagePool {
|
||||||
mp := &MessagePool{
|
mp := &MessagePool{
|
||||||
pending: make(map[address.Address]*msgSet),
|
pending: make(map[address.Address]*msgSet),
|
||||||
cs: cs,
|
sm: sm,
|
||||||
}
|
}
|
||||||
cs.SubscribeHeadChanges(mp.HeadChange)
|
sm.ChainStore().SubscribeHeadChanges(mp.HeadChange)
|
||||||
|
|
||||||
return mp
|
return mp
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ func (mp *MessagePool) Add(m *types.SignedMessage) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := mp.cs.PutMessage(m); err != nil {
|
if _, err := mp.sm.ChainStore().PutMessage(m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) {
|
|||||||
return mset.startNonce + uint64(len(mset.msgs)), nil
|
return mset.startNonce + uint64(len(mset.msgs)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
act, err := mp.cs.GetActor(addr)
|
act, err := mp.sm.GetActor(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ func (mp *MessagePool) Pending() []*types.SignedMessage {
|
|||||||
func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet) error {
|
func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet) error {
|
||||||
for _, ts := range revert {
|
for _, ts := range revert {
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
bmsgs, smsgs, err := mp.cs.MessagesForBlock(b)
|
bmsgs, smsgs, err := mp.sm.ChainStore().MessagesForBlock(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to get messages for revert block %s(height %d)", b.Cid(), b.Height)
|
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 _, ts := range apply {
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
bmsgs, smsgs, err := mp.cs.MessagesForBlock(b)
|
bmsgs, smsgs, err := mp.sm.ChainStore().MessagesForBlock(b)
|
||||||
if err != nil {
|
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)
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
"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/types"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CallRaw(ctx context.Context, cs *store.ChainStore, msg *types.Message, bstate cid.Cid, bheight uint64) (*types.MessageReceipt, error) {
|
func CallRaw(ctx context.Context, sm *StateManager, msg *types.Message, bstate cid.Cid, bheight uint64) (*types.MessageReceipt, error) {
|
||||||
vmi, err := NewVM(bstate, bheight, actors.NetworkAddress, cs)
|
vmi, err := vm.NewVM(bstate, bheight, actors.NetworkAddress, sm.cs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"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"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -462,21 +461,6 @@ func (cs *ChainStore) GetGenesis() (*types.BlockHeader, error) {
|
|||||||
return types.DecodeBlock(genb.RawData())
|
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) {
|
func (cs *ChainStore) GetMessage(c cid.Cid) (*types.Message, error) {
|
||||||
sb, err := cs.bs.Get(c)
|
sb, err := cs.bs.Get(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -604,31 +588,6 @@ func (cs *ChainStore) LoadSignedMessagesFromCids(cids []cid.Cid) ([]*types.Signe
|
|||||||
return msgs, nil
|
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) {
|
func (cs *ChainStore) WaitForMessage(ctx context.Context, mcid cid.Cid) (cid.Cid, *types.MessageReceipt, error) {
|
||||||
tsub := cs.SubHeadChanges(ctx)
|
tsub := cs.SubHeadChanges(ctx)
|
||||||
|
|
||||||
@ -737,3 +696,44 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
|
|||||||
}
|
}
|
||||||
return NewFullTipSet(out), nil
|
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/build"
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"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/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
"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
|
// The interface for accessing and putting tipsets into local storage
|
||||||
store *store.ChainStore
|
store *store.ChainStore
|
||||||
|
|
||||||
|
// the state manager handles making state queries
|
||||||
|
sm *stmgr.StateManager
|
||||||
|
|
||||||
// The known Genesis tipset
|
// The known Genesis tipset
|
||||||
Genesis *types.TipSet
|
Genesis *types.TipSet
|
||||||
|
|
||||||
@ -53,8 +57,8 @@ type Syncer struct {
|
|||||||
peerHeadsLk sync.Mutex
|
peerHeadsLk sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSyncer(cs *store.ChainStore, bsync *BlockSync, self peer.ID) (*Syncer, error) {
|
func NewSyncer(sm *stmgr.StateManager, bsync *BlockSync, self peer.ID) (*Syncer, error) {
|
||||||
gen, err := cs.GetGenesis()
|
gen, err := sm.ChainStore().GetGenesis()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -68,7 +72,8 @@ func NewSyncer(cs *store.ChainStore, bsync *BlockSync, self peer.ID) (*Syncer, e
|
|||||||
Genesis: gent,
|
Genesis: gent,
|
||||||
Bsync: bsync,
|
Bsync: bsync,
|
||||||
peerHeads: make(map[peer.ID]*types.TipSet),
|
peerHeads: make(map[peer.ID]*types.TipSet),
|
||||||
store: cs,
|
store: sm.ChainStore(),
|
||||||
|
sm: sm,
|
||||||
self: self,
|
self: self,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -320,7 +325,7 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := vm.Call(ctx, syncer.store, &types.Message{
|
ret, err := stmgr.Call(ctx, syncer.sm, &types.Message{
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
From: maddr,
|
From: maddr,
|
||||||
Method: actors.SMAMethods.IsMiner,
|
Method: actors.SMAMethods.IsMiner,
|
||||||
@ -353,7 +358,6 @@ func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Addre
|
|||||||
Data: next.VRFProof,
|
Data: next.VRFProof,
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("About to verify signature: ", sig.Data, mworker, cur.VDFResult)
|
|
||||||
if err := sig.Verify(mworker, cur.VDFResult); err != nil {
|
if err := sig.Verify(mworker, cur.VDFResult); err != nil {
|
||||||
return xerrors.Errorf("invalid ticket, VRFProof invalid: %w", err)
|
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
|
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
|
// Should match up with 'Semantical Validation' in validation.md in the spec
|
||||||
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error {
|
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error {
|
||||||
h := b.Header
|
h := b.Header
|
||||||
stateroot, err := syncer.store.TipSetState(h.Parents)
|
stateroot, err := syncer.sm.TipSetState(h.Parents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get tipsetstate(%d, %s) failed: %w", h.Height, h.Parents, err)
|
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)
|
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 {
|
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 {
|
if err := syncer.validateTickets(ctx, waddr, h.Tickets, baseTs); err != nil {
|
||||||
return xerrors.Errorf("validating block tickets failed: %w", err)
|
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)
|
vmi, err := vm.NewVM(stateroot, h.Height, h.Miner, syncer.store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to instantiate VM: %w", err)
|
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 {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting miner owner for block miner failed: %w", err)
|
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 {
|
func (syncer *Syncer) syncMessagesAndCheckState(headers []*types.TipSet) error {
|
||||||
return syncer.iterFullTipsets(headers, func(fts *store.FullTipSet) 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 {
|
if err := syncer.ValidateTipSet(context.TODO(), fts); err != nil {
|
||||||
log.Errorf("failed to validate tipset: %s", err)
|
log.Errorf("failed to validate tipset: %s", err)
|
||||||
return xerrors.Errorf("message processing failed: %w", err)
|
return xerrors.Errorf("message processing failed: %w", err)
|
||||||
@ -692,3 +662,59 @@ func (syncer *Syncer) collectChain(fts *store.FullTipSet) error {
|
|||||||
|
|
||||||
return nil
|
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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
block "github.com/ipfs/go-block-format"
|
block "github.com/ipfs/go-block-format"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@ -87,6 +89,10 @@ func (blk *BlockHeader) Serialize() ([]byte, error) {
|
|||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (blk *BlockHeader) LastTicket() *Ticket {
|
||||||
|
return blk.Tickets[len(blk.Tickets)-1]
|
||||||
|
}
|
||||||
|
|
||||||
type MsgMeta struct {
|
type MsgMeta struct {
|
||||||
BlsMessages cid.Cid
|
BlsMessages cid.Cid
|
||||||
SecpkMessages cid.Cid
|
SecpkMessages cid.Cid
|
||||||
@ -126,3 +132,21 @@ func CidArrsEqual(a, b []cid.Cid) bool {
|
|||||||
}
|
}
|
||||||
return true
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *TipSet) MinTicket() *Ticket {
|
func (t *Ticket) Less(o *Ticket) bool {
|
||||||
if len(ts.Blocks()) == 0 {
|
return bytes.Compare(t.VDFResult, o.VDFResult) < 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return minTicket
|
func (ts *TipSet) MinTicket() *Ticket {
|
||||||
|
b := ts.MinTicketBlock()
|
||||||
|
return b.Tickets[len(b.Tickets)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *TipSet) MinTimestamp() uint64 {
|
func (ts *TipSet) MinTimestamp() uint64 {
|
||||||
@ -120,3 +114,17 @@ func (ts *TipSet) MinTimestamp() uint64 {
|
|||||||
}
|
}
|
||||||
return minTs
|
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]
|
code, ok := inv.builtInCode[act.Code]
|
||||||
if !ok {
|
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)
|
return nil, aerrors.Newf(255, "no code for actor %s", act.Code)
|
||||||
}
|
}
|
||||||
if method >= uint64(len(code)) || code[method] == nil {
|
if method >= uint64(len(code)) || code[method] == nil {
|
||||||
|
@ -454,6 +454,10 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vm *VM) SetBlockMiner(m address.Address) {
|
||||||
|
vm.blockMiner = m
|
||||||
|
}
|
||||||
|
|
||||||
func (vm *VM) ActorBalance(addr address.Address) (types.BigInt, aerrors.ActorError) {
|
func (vm *VM) ActorBalance(addr address.Address) (types.BigInt, aerrors.ActorError) {
|
||||||
act, err := vm.cstate.GetActor(addr)
|
act, err := vm.cstate.GetActor(addr)
|
||||||
if err != nil {
|
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...
|
// 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,
|
To: addr,
|
||||||
From: addr,
|
From: addr,
|
||||||
Method: actors.MAMethods.GetWorkerAddr,
|
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) {
|
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,
|
From: addr,
|
||||||
To: addr,
|
To: addr,
|
||||||
Method: actors.MAMethods.GetWorkerAddr,
|
Method: actors.MAMethods.GetWorkerAddr,
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/api"
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/chain"
|
"github.com/filecoin-project/go-lotus/chain"
|
||||||
"github.com/filecoin-project/go-lotus/chain/deals"
|
"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/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||||
@ -201,6 +202,7 @@ func Online() Option {
|
|||||||
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
||||||
|
|
||||||
Override(new(*store.ChainStore), modules.ChainStore),
|
Override(new(*store.ChainStore), modules.ChainStore),
|
||||||
|
Override(new(*stmgr.StateManager), stmgr.NewStateManager),
|
||||||
Override(new(*wallet.Wallet), wallet.NewWallet),
|
Override(new(*wallet.Wallet), wallet.NewWallet),
|
||||||
|
|
||||||
Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker),
|
Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker),
|
||||||
|
@ -5,17 +5,11 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/api"
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/chain"
|
"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/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"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"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
@ -51,9 +45,8 @@ func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) {
|
|||||||
return a.Chain.GetHeaviestTipSet(), nil
|
return a.Chain.GetHeaviestTipSet(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts *types.TipSet) ([]byte, error) {
|
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts *types.TipSet, tickets []*types.Ticket, lb int) ([]byte, error) {
|
||||||
// TODO: this needs to look back in the chain for the right random beacon value
|
return a.Chain.GetRandomness(ctx, pts, tickets, lb)
|
||||||
return []byte("foo bar random"), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ChainAPI) ChainWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait, error) {
|
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
|
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
|
fx.In
|
||||||
|
|
||||||
ChainAPI
|
ChainAPI
|
||||||
|
StateAPI
|
||||||
WalletAPI
|
WalletAPI
|
||||||
PaychAPI
|
PaychAPI
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ func (a *ClientAPI) ClientStartDeal(ctx context.Context, data cid.Cid, miner add
|
|||||||
Method: actors.MAMethods.GetPeerID,
|
Method: actors.MAMethods.GetPeerID,
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := a.ChainCall(ctx, msg, nil)
|
r, err := a.StateCall(ctx, msg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,20 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"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/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
"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"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/api"
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/state"
|
"github.com/filecoin-project/go-lotus/chain/state"
|
||||||
"github.com/filecoin-project/go-lotus/chain/store"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
"github.com/ipfs/go-hamt-ipld"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
@ -23,18 +28,23 @@ import (
|
|||||||
type StateAPI struct {
|
type StateAPI struct {
|
||||||
fx.In
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cst := hamt.CSTFromBstore(a.Chain.Blockstore())
|
cst := hamt.CSTFromBstore(a.StateManager.ChainStore().Blockstore())
|
||||||
|
|
||||||
st, err := state.LoadStateTree(cst, stc)
|
st, err := state.LoadStateTree(cst, stc)
|
||||||
if err != nil {
|
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) {
|
func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address) ([]*api.SectorInfo, error) {
|
||||||
ts := a.Chain.GetHeaviestTipSet()
|
ts := a.Chain.GetHeaviestTipSet()
|
||||||
|
|
||||||
stc, err := a.Chain.TipSetState(ts.Cids())
|
stc, err := a.StateManager.TipSetState(ts.Cids())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -152,7 +162,7 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, t
|
|||||||
var mpow types.BigInt
|
var mpow types.BigInt
|
||||||
|
|
||||||
if maddr != address.Undef {
|
if maddr != address.Undef {
|
||||||
ret, err := vm.Call(ctx, a.Chain, &types.Message{
|
ret, err := stmgr.Call(ctx, a.StateManager, &types.Message{
|
||||||
From: maddr,
|
From: maddr,
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
Method: actors.SMAMethods.PowerLookup,
|
Method: actors.SMAMethods.PowerLookup,
|
||||||
@ -168,7 +178,7 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, t
|
|||||||
mpow = types.BigFromBytes(ret.Return)
|
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,
|
From: actors.StorageMarketAddress,
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
Method: actors.SMAMethods.GetTotalStorage,
|
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) {
|
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,
|
From: m,
|
||||||
To: m,
|
To: m,
|
||||||
Method: actors.MAMethods.GetWorkerAddr,
|
Method: actors.MAMethods.GetWorkerAddr,
|
||||||
@ -209,3 +219,72 @@ func (a *StateAPI) StateMinerWorker(ctx context.Context, m address.Address, ts *
|
|||||||
|
|
||||||
return w, nil
|
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"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"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/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||||
|
|
||||||
@ -15,8 +15,8 @@ import (
|
|||||||
type WalletAPI struct {
|
type WalletAPI struct {
|
||||||
fx.In
|
fx.In
|
||||||
|
|
||||||
Chain *store.ChainStore
|
StateManager *stmgr.StateManager
|
||||||
Wallet *wallet.Wallet
|
Wallet *wallet.Wallet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *WalletAPI) WalletNew(ctx context.Context, typ string) (address.Address, error) {
|
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) {
|
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) {
|
func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*types.Signature, error) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package modules
|
package modules
|
||||||
|
|
||||||
import (
|
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/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/go-lotus/paych"
|
"github.com/filecoin-project/go-lotus/paych"
|
||||||
)
|
)
|
||||||
@ -10,6 +10,6 @@ func PaychStore(ds dtypes.MetadataDS) *paych.Store {
|
|||||||
return paych.NewStore(ds)
|
return paych.NewStore(ds)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PaymentChannelManager(chain *store.ChainStore, store *paych.Store) (*paych.Manager, error) {
|
func PaymentChannelManager(sm *stmgr.StateManager, store *paych.Store) (*paych.Manager, error) {
|
||||||
return paych.NewManager(chain, store), nil
|
return paych.NewManager(sm, store), nil
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
"github.com/ipfs/go-merkledag"
|
"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/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/gen"
|
"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{
|
gmc := &gen.GenMinerCfg{
|
||||||
Owner: w,
|
Owners: []address.Address{w},
|
||||||
Worker: w,
|
Workers: []address.Address{w},
|
||||||
|
PeerIDs: []peer.ID{"peerID 1"},
|
||||||
}
|
}
|
||||||
alloc := map[address.Address]types.BigInt{
|
alloc := map[address.Address]types.BigInt{
|
||||||
w: types.NewInt(100000),
|
w: types.NewInt(100000),
|
||||||
@ -68,8 +70,9 @@ func MakeGenesis(outFile string) func(bs dtypes.ChainBlockstore, w *wallet.Walle
|
|||||||
}
|
}
|
||||||
|
|
||||||
gmc := &gen.GenMinerCfg{
|
gmc := &gen.GenMinerCfg{
|
||||||
Owner: minerAddr,
|
Owners: []address.Address{minerAddr},
|
||||||
Worker: minerAddr,
|
Workers: []address.Address{minerAddr},
|
||||||
|
PeerIDs: []peer.ID{"peer ID 1"},
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs := map[address.Address]types.BigInt{
|
addrs := map[address.Address]types.BigInt{
|
||||||
@ -81,7 +84,7 @@ func MakeGenesis(outFile string) func(bs dtypes.ChainBlockstore, w *wallet.Walle
|
|||||||
return nil, err
|
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)
|
f, err := os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,28 +4,25 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/state"
|
"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/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("paych")
|
var log = logging.Logger("paych")
|
||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
chain *store.ChainStore
|
|
||||||
store *Store
|
store *Store
|
||||||
|
sm *stmgr.StateManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewManager(chain *store.ChainStore, pchstore *Store) *Manager {
|
func NewManager(sm *stmgr.StateManager, pchstore *Store) *Manager {
|
||||||
return &Manager{
|
return &Manager{
|
||||||
chain: chain,
|
|
||||||
store: pchstore,
|
store: pchstore,
|
||||||
|
sm: sm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +145,7 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := vm.Call(ctx, pm.chain, &types.Message{
|
ret, err := stmgr.Call(ctx, pm.sm, &types.Message{
|
||||||
From: owner,
|
From: owner,
|
||||||
To: ch,
|
To: ch,
|
||||||
Method: actors.PCAMethods.UpdateChannelState,
|
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) {
|
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
|
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
|
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) {
|
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,
|
From: ch,
|
||||||
To: ch,
|
To: ch,
|
||||||
Method: actors.PCAMethods.GetOwner,
|
Method: actors.PCAMethods.GetOwner,
|
||||||
|
@ -41,7 +41,7 @@ type storageMinerApi interface {
|
|||||||
//ReadState(ctx context.Context, addr address.Address) (????, error)
|
//ReadState(ctx context.Context, addr address.Address) (????, error)
|
||||||
|
|
||||||
// Call a read only method on actors (no interaction with the chain required)
|
// 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
|
MpoolPush(context.Context, *types.SignedMessage) error
|
||||||
MpoolGetNonce(context.Context, address.Address) (uint64, 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,
|
Params: actors.EmptyStructCBOR,
|
||||||
}
|
}
|
||||||
|
|
||||||
recpt, err := m.api.ChainCall(ctx, msg, nil)
|
recpt, err := m.api.StateCall(ctx, msg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, errors.Wrapf(err, "calling getWorker(%s)", m.maddr)
|
return address.Undef, errors.Wrapf(err, "calling getWorker(%s)", m.maddr)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user