Merge pull request #343 from filecoin-project/feat/spec-sync

Sync with the new spec
This commit is contained in:
Łukasz Magiera 2019-10-15 15:20:56 +02:00 committed by GitHub
commit f15d527a35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 268 additions and 130 deletions

View File

@ -61,6 +61,7 @@ type FullNode interface {
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
ChainSetHead(context.Context, *types.TipSet) error
ChainGetGenesis(context.Context) (*types.TipSet, error)
ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error)
// syncer
SyncState(context.Context) (*SyncState, error)

View File

@ -49,6 +49,7 @@ type FullNodeStruct struct {
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
SyncState func(context.Context) (*SyncState, error) `perm:"read"`
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
@ -316,6 +317,10 @@ func (c *FullNodeStruct) ChainGetGenesis(ctx context.Context) (*types.TipSet, er
return c.Internal.ChainGetGenesis(ctx)
}
func (c *FullNodeStruct) ChainTipSetWeight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
return c.Internal.ChainTipSetWeight(ctx, ts)
}
func (c *FullNodeStruct) SyncState(ctx context.Context) (*SyncState, error) {
return c.Internal.SyncState(ctx)
}

View File

@ -38,6 +38,9 @@ const AllowableClockDrift = BlockDelay * 2
// Blocks
const ForkLengthThreshold = 100
// Blocks (e)
const BlocksPerEpoch = 1
// /////
// Proofs / Mining

View File

@ -433,7 +433,7 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
return nil, err
}
_, err = vmctx.Send(StorageMarketAddress, SMAMethods.UpdateStorage, types.NewInt(0), enc)
_, err = vmctx.Send(StorageMarketAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc)
if err != nil {
return nil, err
}

View File

@ -15,9 +15,9 @@ import (
xerrors "golang.org/x/xerrors"
)
type StorageMarketActor struct{}
type StoragePowerActor struct{}
type smaMethods struct {
type spaMethods struct {
Constructor uint64
CreateStorageMiner uint64
ArbitrateConsensusFault uint64
@ -28,22 +28,22 @@ type smaMethods struct {
PledgeCollateralForSize uint64
}
var SMAMethods = smaMethods{1, 2, 3, 4, 5, 6, 7, 8}
var SPAMethods = spaMethods{1, 2, 3, 4, 5, 6, 7, 8}
func (sma StorageMarketActor) Exports() []interface{} {
func (spa StoragePowerActor) Exports() []interface{} {
return []interface{}{
//1: sma.StorageMarketConstructor,
2: sma.CreateStorageMiner,
3: sma.ArbitrateConsensusFault,
4: sma.UpdateStorage,
5: sma.GetTotalStorage,
6: sma.PowerLookup,
7: sma.IsMiner,
8: sma.PledgeCollateralForSize,
//1: spa.StoragePowerConstructor,
2: spa.CreateStorageMiner,
3: spa.ArbitrateConsensusFault,
4: spa.UpdateStorage,
5: spa.GetTotalStorage,
6: spa.PowerLookup,
7: spa.IsMiner,
8: spa.PledgeCollateralForSize,
}
}
type StorageMarketState struct {
type StoragePowerState struct {
Miners cid.Cid
MinerCount uint64
@ -57,12 +57,12 @@ type CreateStorageMinerParams struct {
PeerID peer.ID
}
func (sma StorageMarketActor) CreateStorageMiner(act *types.Actor, vmctx types.VMContext, params *CreateStorageMinerParams) ([]byte, ActorError) {
func (spa StoragePowerActor) CreateStorageMiner(act *types.Actor, vmctx types.VMContext, params *CreateStorageMinerParams) ([]byte, ActorError) {
if !SupportedSectorSize(params.SectorSize) {
return nil, aerrors.New(1, "Unsupported sector size")
}
var self StorageMarketState
var self StoragePowerState
old := vmctx.Storage().GetHead()
if err := vmctx.Storage().Get(old, &self); err != nil {
return nil, err
@ -128,7 +128,7 @@ type ArbitrateConsensusFaultParams struct {
Block2 *types.BlockHeader
}
func (sma StorageMarketActor) ArbitrateConsensusFault(act *types.Actor, vmctx types.VMContext, params *ArbitrateConsensusFaultParams) ([]byte, ActorError) {
func (spa StoragePowerActor) ArbitrateConsensusFault(act *types.Actor, vmctx types.VMContext, params *ArbitrateConsensusFaultParams) ([]byte, ActorError) {
if params.Block1.Miner != params.Block2.Miner {
return nil, aerrors.New(2, "blocks must be from the same miner")
}
@ -158,14 +158,14 @@ func (sma StorageMarketActor) ArbitrateConsensusFault(act *types.Actor, vmctx ty
return nil, aerrors.New(6, "blocks do not prove a slashable offense")
}
var self StorageMarketState
var self StoragePowerState
old := vmctx.Storage().GetHead()
if err := vmctx.Storage().Get(old, &self); err != nil {
return nil, err
}
if types.BigCmp(self.TotalStorage, types.NewInt(0)) == 0 {
return nil, aerrors.Fatal("invalid state, storage market actor has zero total storage")
return nil, aerrors.Fatal("invalid state, storage power actor has zero total storage")
}
miner := params.Block1.Miner
@ -269,8 +269,8 @@ type UpdateStorageParams struct {
Delta types.BigInt
}
func (sma StorageMarketActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) {
var self StorageMarketState
func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) {
var self StoragePowerState
old := vmctx.Storage().GetHead()
if err := vmctx.Storage().Get(old, &self); err != nil {
return nil, err
@ -299,8 +299,8 @@ func (sma StorageMarketActor) UpdateStorage(act *types.Actor, vmctx types.VMCont
return nil, nil
}
func (sma StorageMarketActor) GetTotalStorage(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
var self StorageMarketState
func (spa StoragePowerActor) GetTotalStorage(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
var self StoragePowerState
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return nil, err
}
@ -312,8 +312,8 @@ type PowerLookupParams struct {
Miner address.Address
}
func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) ([]byte, ActorError) {
var self StorageMarketState
func (spa StoragePowerActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) ([]byte, ActorError) {
var self StoragePowerState
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return nil, aerrors.Wrap(err, "getting head")
}
@ -326,14 +326,14 @@ func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContex
return pow.Bytes(), nil
}
func powerLookup(ctx context.Context, vmctx types.VMContext, self *StorageMarketState, miner address.Address) (types.BigInt, ActorError) {
func powerLookup(ctx context.Context, vmctx types.VMContext, self *StoragePowerState, miner address.Address) (types.BigInt, ActorError) {
has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, miner)
if err != nil {
return types.EmptyInt, err
}
if !has {
return types.EmptyInt, aerrors.New(1, "miner not registered with storage market")
return types.EmptyInt, aerrors.New(1, "miner not registered with storage power actor")
}
ret, err := vmctx.Send(miner, MAMethods.GetPower, types.NewInt(0), nil)
@ -348,8 +348,8 @@ type IsMinerParam struct {
Addr address.Address
}
func (sma StorageMarketActor) IsMiner(act *types.Actor, vmctx types.VMContext, param *IsMinerParam) ([]byte, ActorError) {
var self StorageMarketState
func (spa StoragePowerActor) IsMiner(act *types.Actor, vmctx types.VMContext, param *IsMinerParam) ([]byte, ActorError) {
var self StoragePowerState
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return nil, err
}
@ -366,8 +366,8 @@ type PledgeCollateralParams struct {
Size types.BigInt
}
func (sma StorageMarketActor) PledgeCollateralForSize(act *types.Actor, vmctx types.VMContext, param *PledgeCollateralParams) ([]byte, ActorError) {
var self StorageMarketState
func (spa StoragePowerActor) PledgeCollateralForSize(act *types.Actor, vmctx types.VMContext, param *PledgeCollateralParams) ([]byte, ActorError) {
var self StoragePowerState
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return nil, err
}

View File

@ -37,7 +37,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
// cheating the bootstrapping problem
cheatStorageMarketTotal(t, h.vm, h.cs.Blockstore())
ret, _ := h.InvokeWithValue(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
ret, _ := h.InvokeWithValue(t, ownerAddr, StorageMarketAddress, SPAMethods.CreateStorageMiner,
types.NewInt(500000),
&CreateStorageMinerParams{
Owner: ownerAddr,
@ -52,7 +52,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
}
{
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.IsMiner,
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.IsMiner,
&IsMinerParam{Addr: minerAddr})
ApplyOK(t, ret)
@ -68,7 +68,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
}
{
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.PowerLookup,
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.PowerLookup,
&PowerLookupParams{Miner: minerAddr})
ApplyOK(t, ret)
power := types.BigFromBytes(ret.Return)
@ -93,7 +93,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
signBlock(t, h.w, workerAddr, b1)
signBlock(t, h.w, workerAddr, b2)
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.ArbitrateConsensusFault,
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.ArbitrateConsensusFault,
&ArbitrateConsensusFaultParams{
Block1: b1,
Block2: b2,
@ -102,13 +102,13 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
}
{
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.PowerLookup,
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.PowerLookup,
&PowerLookupParams{Miner: minerAddr})
assert.Equal(t, ret.ExitCode, byte(1))
}
{
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.IsMiner, &IsMinerParam{minerAddr})
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.IsMiner, &IsMinerParam{minerAddr})
ApplyOK(t, ret)
assert.Equal(t, ret.Return, cbg.CborBoolFalse)
}
@ -124,7 +124,7 @@ func cheatStorageMarketTotal(t *testing.T, vm *vm.VM, bs bstore.Blockstore) {
cst := hamt.CSTFromBstore(bs)
var smastate StorageMarketState
var smastate StoragePowerState
if err := cst.Get(context.TODO(), sma.Head, &smastate); err != nil {
t.Fatal(err)
}

View File

@ -53,7 +53,7 @@ func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address, bstore.Blockstore)
cs := store.NewChainStore(bs, nil)
// TODO: should probabaly mock out the randomness bit, nil works for now
vm, err := vm.NewVM(stateroot, 1, nil, maddr, cs)
vm, err := vm.NewVM(stateroot, 1, nil, maddr, cs.Blockstore())
if err != nil {
t.Fatal(err)
}
@ -130,7 +130,7 @@ func TestStorageMarketActorCreateMiner(t *testing.T) {
msg := &types.Message{
To: StorageMarketAddress,
From: from,
Method: SMAMethods.CreateStorageMiner,
Method: SPAMethods.CreateStorageMiner,
Params: enc,
GasPrice: types.NewInt(1),
GasLimit: types.NewInt(10000),

View File

@ -2379,7 +2379,7 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error {
return nil
}
func (t *StorageMarketState) MarshalCBOR(w io.Writer) error {
func (t *StoragePowerState) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
@ -2406,7 +2406,7 @@ func (t *StorageMarketState) MarshalCBOR(w io.Writer) error {
return nil
}
func (t *StorageMarketState) UnmarshalCBOR(r io.Reader) error {
func (t *StoragePowerState) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)

View File

@ -158,7 +158,7 @@ func NewHarness(t *testing.T, options ...HarnessOpt) *Harness {
t.Fatal(err)
}
h.cs = store.NewChainStore(h.bs, nil)
h.vm, err = vm.NewVM(stateroot, 1, nil, h.HI.Miner, h.cs)
h.vm, err = vm.NewVM(stateroot, 1, nil, h.HI.Miner, h.cs.Blockstore())
if err != nil {
t.Fatal(err)
}

View File

@ -413,7 +413,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, ticks []*types.Ticket,
return false, nil, xerrors.Errorf("failed to check power: %w", err)
}
return types.PowerCmp(vrfout, pow.MinerPower, pow.TotalPower), vrfout, nil
return types.PowerCmp(vrfout, types.BigMul(pow.MinerPower, types.NewInt(build.BlocksPerEpoch)), pow.TotalPower), vrfout, nil
}
type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error)

View File

@ -96,8 +96,11 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
}
next.BLSAggregate = aggSig
pweight := sm.ChainStore().Weight(parents)
next.ParentWeight = types.NewInt(pweight)
pweight, err := sm.ChainStore().Weight(ctx, parents)
if err != nil {
return nil, err
}
next.ParentWeight = pweight
cst := hamt.CSTFromBstore(sm.ChainStore().Blockstore())
tree, err := state.LoadStateTree(cst, st)

View File

@ -143,7 +143,7 @@ func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
return nil, err
}
sms := &actors.StorageMarketState{
sms := &actors.StoragePowerState{
Miners: emptyhamt,
TotalStorage: types.NewInt(0),
}
@ -183,7 +183,7 @@ func mustEnc(i cbg.CBORMarshaler) []byte {
}
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, error) {
vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs)
vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs.Blockstore())
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
}
@ -202,7 +202,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
// TODO: hardcoding 7000000 here is a little fragile, it changes any
// time anyone changes the initial account allocations
rval, err := doExecValue(ctx, vm, actors.StorageMarketAddress, owner, types.FromFil(6500), actors.SMAMethods.CreateStorageMiner, params)
rval, err := doExecValue(ctx, vm, actors.StorageMarketAddress, owner, types.FromFil(6500), actors.SPAMethods.CreateStorageMiner, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
}
@ -216,7 +216,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
params = mustEnc(&actors.UpdateStorageParams{Delta: types.NewInt(5000)})
_, err = doExec(ctx, vm, actors.StorageMarketAddress, maddr, actors.SMAMethods.UpdateStorage, params)
_, err = doExec(ctx, vm, actors.StorageMarketAddress, maddr, actors.SPAMethods.UpdateStorage, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to update total storage: %w", err)
}

View File

@ -89,11 +89,16 @@ func sendHeadNotifs(ctx context.Context, ps *pubsub.PubSub, topic string, chain
case notif := <-notifs:
n := notif[len(notif)-1]
w, err := chain.ChainTipSetWeight(ctx, n.Val)
if err != nil {
return err
}
m := message{
Cids: n.Val.Cids(),
Blocks: n.Val.Blocks(),
Height: n.Val.Height(),
Weight: n.Val.Weight(),
Weight: w,
NodeName: nickname,
}

View File

@ -4,16 +4,17 @@ import (
"context"
"fmt"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/vm"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/store"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/vm"
)
func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate cid.Cid, r vm.Rand, bheight uint64) (*types.MessageReceipt, error) {
vmi, err := vm.NewVM(bstate, bheight, r, actors.NetworkAddress, sm.cs)
vmi, err := vm.NewVM(bstate, bheight, r, actors.NetworkAddress, sm.cs.Blockstore())
if err != nil {
return nil, xerrors.Errorf("failed to set up vm: %w", err)
}
@ -55,7 +56,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
state := ts.ParentState()
r := vm.NewChainRand(sm.cs, ts.Cids(), ts.Height(), nil)
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height(), nil)
return sm.CallRaw(ctx, msg, state, r, ts.Height())
}

View File

@ -89,9 +89,9 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
cids[i] = v.Cid()
}
r := vm.NewChainRand(sm.cs, cids, blks[0].Height, nil)
r := store.NewChainRand(sm.cs, cids, blks[0].Height, nil)
vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs)
vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs.Blockstore())
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
}

View File

@ -2,7 +2,6 @@ package stmgr
import (
"context"
"github.com/filecoin-project/go-lotus/api"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
@ -82,7 +81,7 @@ func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr add
ret, err := sm.Call(ctx, &types.Message{
From: maddr,
To: actors.StorageMarketAddress,
Method: actors.SMAMethods.PowerLookup,
Method: actors.SPAMethods.PowerLookup,
Params: enc,
}, ts)
if err != nil {
@ -98,7 +97,7 @@ func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr add
ret, err := sm.Call(ctx, &types.Message{
From: actors.StorageMarketAddress,
To: actors.StorageMarketAddress,
Method: actors.SMAMethods.GetTotalStorage,
Method: actors.SPAMethods.GetTotalStorage,
}, ts)
if err != nil {
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err)

View File

@ -5,6 +5,7 @@ import (
"crypto/sha256"
"encoding/json"
"fmt"
"github.com/filecoin-project/go-lotus/chain/vm"
"sync"
"github.com/filecoin-project/go-lotus/build"
@ -182,14 +183,14 @@ func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
return err
}
if err := cs.PutTipSet(ts); err != nil {
if err := cs.PutTipSet(context.TODO(), ts); err != nil {
return err
}
return cs.ds.Put(dstore.NewKey("0"), b.Cid().Bytes())
}
func (cs *ChainStore) PutTipSet(ts *types.TipSet) error {
func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error {
for _, b := range ts.Blocks() {
if err := cs.PersistBlockHeader(b); err != nil {
return err
@ -202,16 +203,25 @@ func (cs *ChainStore) PutTipSet(ts *types.TipSet) error {
}
log.Debugf("expanded %s into %s\n", ts.Cids(), expanded.Cids())
if err := cs.MaybeTakeHeavierTipSet(expanded); err != nil {
if err := cs.MaybeTakeHeavierTipSet(ctx, expanded); err != nil {
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed in PutTipSet")
}
return nil
}
func (cs *ChainStore) MaybeTakeHeavierTipSet(ts *types.TipSet) error {
func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipSet) error {
cs.heaviestLk.Lock()
defer cs.heaviestLk.Unlock()
if cs.heaviest == nil || cs.Weight(ts) > cs.Weight(cs.heaviest) {
w, err := cs.Weight(ctx, ts)
if err != nil {
return err
}
heaviestW, err := cs.Weight(ctx, cs.heaviest)
if err != nil {
return err
}
if w.GreaterThan(heaviestW) {
// TODO: don't do this for initial sync. Now that we don't have a
// difference between 'bootstrap sync' and 'caught up' sync, we need
// some other heuristic.
@ -377,10 +387,6 @@ func (cs *ChainStore) ReorgOps(a, b *types.TipSet) ([]*types.TipSet, []*types.Ti
return leftChain, rightChain, nil
}
func (cs *ChainStore) Weight(ts *types.TipSet) uint64 {
return ts.Blocks()[0].ParentWeight.Uint64() + uint64(len(ts.Cids()))
}
func (cs *ChainStore) GetHeaviestTipSet() *types.TipSet {
cs.heaviestLk.Lock()
defer cs.heaviestLk.Unlock()
@ -469,7 +475,7 @@ func (cs *ChainStore) expandTipset(b *types.BlockHeader) (*types.TipSet, error)
return types.NewTipSet(all)
}
func (cs *ChainStore) AddBlock(b *types.BlockHeader) error {
func (cs *ChainStore) AddBlock(ctx context.Context, b *types.BlockHeader) error {
if err := cs.PersistBlockHeader(b); err != nil {
return err
}
@ -479,7 +485,7 @@ func (cs *ChainStore) AddBlock(b *types.BlockHeader) error {
return err
}
if err := cs.MaybeTakeHeavierTipSet(ts); err != nil {
if err := cs.MaybeTakeHeavierTipSet(ctx, ts); err != nil {
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed")
}
@ -793,3 +799,24 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h uint64, ts *types
ts = pts
}
}
type chainRand struct {
cs *ChainStore
blks []cid.Cid
bh uint64
tickets []*types.Ticket
}
func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight uint64, tickets []*types.Ticket) vm.Rand {
return &chainRand{
cs: cs,
blks: blks,
bh: bheight,
tickets: tickets,
}
}
func (cr *chainRand) GetRandomness(ctx context.Context, h int64) ([]byte, error) {
lb := (int64(cr.bh) + int64(len(cr.tickets))) - h
return cr.cs.GetRandomness(ctx, cr.blks, cr.tickets, lb)
}

94
chain/store/weight.go Normal file
View File

@ -0,0 +1,94 @@
package store
import (
"context"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/vm"
"golang.org/x/xerrors"
"math/big"
)
var zero = types.NewInt(0)
func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
if ts == nil {
return types.NewInt(0), nil
}
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
var out = new(big.Int).Set(ts.Blocks()[0].ParentWeight.Int)
// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
ret, err := cs.call(ctx, &types.Message{
From: actors.StorageMarketAddress,
To: actors.StorageMarketAddress,
Method: actors.SPAMethods.GetTotalStorage,
}, ts)
if err != nil {
return types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err)
}
if ret.ExitCode != 0 {
return types.EmptyInt, xerrors.Errorf("failed to get total power from chain (exit code %d)", ret.ExitCode)
}
log2P := int64(0)
tpow := types.BigFromBytes(ret.Return)
if tpow.GreaterThan(zero) {
log2P = int64(tpow.BitLen() - 1)
}
out.Add(out, big.NewInt(log2P*256))
// (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
wRatioNum := int64(1)
wRatioDen := 2
eWeight := big.NewInt((log2P * int64(len(ts.Blocks())) * wRatioNum) << 8)
eWeight.Div(eWeight, big.NewInt(int64(build.BlocksPerEpoch*wRatioDen)))
out.Add(out, eWeight)
return types.BigInt{Int: out}, nil
}
// todo: dedupe with state manager
func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
bstate := ts.ParentState()
r := NewChainRand(cs, ts.Cids(), ts.Height(), nil)
vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs)
if err != nil {
return nil, xerrors.Errorf("failed to set up vm: %w", err)
}
if msg.GasLimit == types.EmptyInt {
msg.GasLimit = types.NewInt(10000000000)
}
if msg.GasPrice == types.EmptyInt {
msg.GasPrice = types.NewInt(0)
}
if msg.Value == types.EmptyInt {
msg.Value = types.NewInt(0)
}
fromActor, err := vmi.StateTree().GetActor(msg.From)
if err != nil {
return nil, xerrors.Errorf("call raw get actor: %s", err)
}
msg.Nonce = fromActor.Nonce
// TODO: maybe just use the invoker directly?
ret, err := vmi.ApplyMessage(ctx, msg)
if err != nil {
return nil, xerrors.Errorf("apply message failed: %w", err)
}
if ret.ActorErr != nil {
log.Warnf("chain call failed: %s", ret.ActorErr)
}
return &ret.MessageReceipt, nil
}

View File

@ -261,7 +261,7 @@ func computeMsgMeta(bs amt.Blocks, bmsgCids, smsgCids []cbg.CBORMarshaler) (cid.
return mrcid, nil
}
func (syncer *Syncer) selectHead(heads map[peer.ID]*types.TipSet) (*types.TipSet, error) {
func (syncer *Syncer) selectHead(ctx context.Context, heads map[peer.ID]*types.TipSet) (*types.TipSet, error) {
var headsArr []*types.TipSet
for _, ts := range heads {
headsArr = append(headsArr, ts)
@ -298,7 +298,16 @@ func (syncer *Syncer) selectHead(heads map[peer.ID]*types.TipSet) (*types.TipSet
return nil, fmt.Errorf("Conflict exists in heads set")
}
if syncer.store.Weight(cur) > syncer.store.Weight(sel) {
curw, err := syncer.store.Weight(ctx, cur)
if err != nil {
return nil, err
}
selw, err := syncer.store.Weight(ctx, sel)
if err != nil {
return nil, err
}
if curw.GreaterThan(selw) {
sel = cur
}
}
@ -352,7 +361,7 @@ func (syncer *Syncer) Sync(ctx context.Context, maybeHead *types.TipSet) error {
return xerrors.Errorf("collectChain failed: %w", err)
}
if err := syncer.store.PutTipSet(maybeHead); err != nil {
if err := syncer.store.PutTipSet(ctx, maybeHead); err != nil {
return xerrors.Errorf("failed to put synced tipset to chainstore: %w", err)
}
@ -391,7 +400,7 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
ret, err := syncer.sm.Call(ctx, &types.Message{
To: actors.StorageMarketAddress,
From: maddr,
Method: actors.SMAMethods.IsMiner,
Method: actors.SPAMethods.IsMiner,
Params: enc,
}, baseTs)
if err != nil {

View File

@ -220,7 +220,7 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
for _, lastB := range lastTs {
cs := out.(*impl.FullNodeAPI).ChainAPI.Chain
require.NoError(tu.t, cs.AddToTipSetTracker(lastB.Header))
err = cs.AddBlock(lastB.Header)
err = cs.AddBlock(tu.ctx, lastB.Header)
require.NoError(tu.t, err)
}

View File

@ -75,6 +75,8 @@ func NewTipSet(blks []*BlockHeader) (*TipSet, error) {
return nil, fmt.Errorf("cannot create tipset with mismatching heights")
}
ts.cids = append(ts.cids, b.Cid())
// TODO: ensure the same parents
}
ts.height = blks[0].Height
@ -89,12 +91,6 @@ func (ts *TipSet) Height() uint64 {
return ts.height
}
func (ts *TipSet) Weight() BigInt {
// TODO: implement correctly
log.Warn("Called TipSet.Weight: TODO: correct implementation")
return BigAdd(ts.blks[0].ParentWeight, NewInt(1))
}
func (ts *TipSet) Parents() []cid.Cid {
return ts.blks[0].Parents
}

View File

@ -30,7 +30,7 @@ func newInvoker() *invoker {
// add builtInCode using: register(cid, singleton)
inv.register(actors.InitActorCodeCid, actors.InitActor{}, actors.InitActorState{})
inv.register(actors.StorageMarketActorCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
inv.register(actors.StorageMarketActorCodeCid, actors.StoragePowerActor{}, actors.StoragePowerState{})
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
inv.register(actors.MultisigActorCodeCid, actors.MultiSigActor{}, actors.MultiSigActorState{})
inv.register(actors.PaymentChannelActorCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})

View File

@ -3,15 +3,16 @@ package vm
import (
"context"
"github.com/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore"
hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"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/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore"
hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore"
)
func init() {

View File

@ -3,6 +3,7 @@ package vm
import (
"context"
"fmt"
blockstore "github.com/ipfs/go-ipfs-blockstore"
"math/big"
"github.com/filecoin-project/go-lotus/build"
@ -10,7 +11,6 @@ import (
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"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/lib/bufbstore"
cbg "github.com/whyrusleeping/cbor-gen"
@ -296,7 +296,6 @@ func (vm *VM) makeVMContext(ctx context.Context, sroot cid.Cid, msg *types.Messa
type VM struct {
cstate *state.StateTree
base cid.Cid
cs *store.ChainStore
cst *hamt.CborIpldStore
buf *bufbstore.BufferedBS
blockHeight uint64
@ -305,8 +304,8 @@ type VM struct {
rand Rand
}
func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cs *store.ChainStore) (*VM, error) {
buf := bufbstore.NewBufferedBstore(cs.Blockstore())
func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cbs blockstore.Blockstore) (*VM, error) {
buf := bufbstore.NewBufferedBstore(cbs)
cst := hamt.CSTFromBstore(buf)
state, err := state.LoadStateTree(cst, base)
if err != nil {
@ -316,7 +315,6 @@ func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cs *store
return &VM{
cstate: state,
base: base,
cs: cs,
cst: cst,
buf: buf,
blockHeight: height,
@ -330,27 +328,6 @@ type Rand interface {
GetRandomness(ctx context.Context, h int64) ([]byte, error)
}
type chainRand struct {
cs *store.ChainStore
blks []cid.Cid
bh uint64
tickets []*types.Ticket
}
func NewChainRand(cs *store.ChainStore, blks []cid.Cid, bheight uint64, tickets []*types.Ticket) Rand {
return &chainRand{
cs: cs,
blks: blks,
bh: bheight,
tickets: tickets,
}
}
func (cr *chainRand) GetRandomness(ctx context.Context, h int64) ([]byte, error) {
lb := (int64(cr.bh) + int64(len(cr.tickets))) - h
return cr.cs.GetRandomness(ctx, cr.blks, cr.tickets, lb)
}
type ApplyRet struct {
types.MessageReceipt
ActorErr aerrors.ActorError

View File

@ -71,7 +71,7 @@ var createMinerCmd = &cli.Command{
msg := &types.Message{
To: actors.StorageMarketAddress,
From: addr,
Method: actors.SMAMethods.CreateStorageMiner,
Method: actors.SPAMethods.CreateStorageMiner,
Params: params,
Value: types.NewInt(0),
GasPrice: types.NewInt(0),

View File

@ -289,7 +289,7 @@ func createStorageMiner(ctx context.Context, api api.FullNode, peerid peer.ID, c
From: owner,
Value: collateral,
Method: actors.SMAMethods.CreateStorageMiner,
Method: actors.SPAMethods.CreateStorageMiner,
Params: params,
GasLimit: types.NewInt(10000),

View File

@ -67,7 +67,7 @@ func main() {
actors.LaneState{},
actors.PCAUpdateChannelStateParams{},
actors.PaymentInfo{},
actors.StorageMarketState{},
actors.StoragePowerState{},
actors.CreateStorageMinerParams{},
actors.IsMinerParam{},
actors.PowerLookupParams{},

View File

@ -70,7 +70,7 @@ class StorageNode extends React.Component {
async loadInfo() {
const version = await this.state.client.call("Filecoin.Version", [])
const peers = await this.state.client.call("Filecoin.NetPeers", [])
const [actor] = await this.state.client.call("Filecoin.ActorAddresses", [])
const actor = await this.state.client.call("Filecoin.ActorAddress", [])
const stActor = await this.props.fullConn.call('Filecoin.StateGetActor', [actor, null])
const actorState = await this.props.fullConn.call('Filecoin.StateReadState', [stActor, null])
@ -80,9 +80,9 @@ class StorageNode extends React.Component {
}
async stagedList() {
let stagedList = await this.state.client.call("Filecoin.SectorsStagedList", [])
let stagedList = await this.state.client.call("Filecoin.SectorsList", [])
let staged = await stagedList
.map(sector => this.state.client.call("Filecoin.SectorsStatus", [sector.SectorID]))
.map(sector => this.state.client.call("Filecoin.SectorsStatus", [sector]))
.reduce(async (p, n) => [...await p, await n], Promise.resolve([]))
let statusCounts = staged.reduce((p, n) => p.map((e, i) => e + (i === n.State ? 1 : 0) ), [0, 0, 0, 0, 0])

View File

@ -155,13 +155,13 @@ func (m *Miner) mine(ctx context.Context) {
return
}
base, err := m.GetBestMiningCandidate()
base, err := m.GetBestMiningCandidate(ctx)
if err != nil {
log.Errorf("failed to get best mining candidate: %s", err)
continue
}
if base.ts.Equals(lastBase.ts) && len(lastBase.tickets) == len(base.tickets) {
log.Error("BestMiningCandidate from the previous round: %s (tkts:%d)", lastBase.ts.Cids(), len(lastBase.tickets))
log.Errorf("BestMiningCandidate from the previous round: %s (tkts:%d)", lastBase.ts.Cids(), len(lastBase.tickets))
time.Sleep(build.BlockDelay * time.Second)
continue
}
@ -199,8 +199,8 @@ type MiningBase struct {
tickets []*types.Ticket
}
func (m *Miner) GetBestMiningCandidate() (*MiningBase, error) {
bts, err := m.api.ChainHead(context.TODO())
func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) {
bts, err := m.api.ChainHead(ctx)
if err != nil {
return nil, err
}
@ -210,7 +210,16 @@ func (m *Miner) GetBestMiningCandidate() (*MiningBase, error) {
return m.lastWork, nil
}
if types.BigCmp(bts.Weight(), m.lastWork.ts.Weight()) <= 0 {
btsw, err := m.api.ChainTipSetWeight(ctx, bts)
if err != nil {
return nil, err
}
ltsw, err := m.api.ChainTipSetWeight(ctx, m.lastWork.ts)
if err != nil {
return nil, err
}
if types.BigCmp(btsw, ltsw) <= 0 {
return m.lastWork, nil
}
}

View File

@ -3,6 +3,7 @@ package hello
import (
"context"
"fmt"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
@ -26,7 +27,7 @@ func init() {
type Message struct {
HeaviestTipSet []cid.Cid
HeaviestTipSetWeight uint64
HeaviestTipSetWeight types.BigInt
GenesisHash cid.Cid
}
@ -83,7 +84,10 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
defer s.Close()
hts := hs.cs.GetHeaviestTipSet()
weight := hs.cs.Weight(hts)
weight, err := hs.cs.Weight(ctx, hts)
if err != nil {
return err
}
gen, err := hs.cs.GetGenesis()
if err != nil {
return err

View File

@ -160,3 +160,7 @@ func (a *ChainAPI) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) {
return types.NewTipSet([]*types.BlockHeader{genb})
}
func (a *ChainAPI) ChainTipSetWeight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
return a.Chain.Weight(ctx, ts)
}

View File

@ -92,7 +92,7 @@ func (a *StateAPI) StatePledgeCollateral(ctx context.Context, ts *types.TipSet)
ret, aerr := a.StateManager.Call(ctx, &types.Message{
From: actors.StorageMarketAddress,
To: actors.StorageMarketAddress,
Method: actors.SMAMethods.PledgeCollateralForSize,
Method: actors.SPAMethods.PledgeCollateralForSize,
Params: param,
}, ts)
@ -209,7 +209,7 @@ func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait,
}
func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
var state actors.StorageMarketState
var state actors.StoragePowerState
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
return nil, err
}