Almost building weight function

This commit is contained in:
Łukasz Magiera 2019-10-15 06:33:29 +02:00
parent 2ce338e162
commit fb80d75b07
12 changed files with 81 additions and 67 deletions

View File

@ -379,6 +379,10 @@ func (c *FullNodeStruct) StateListActors(ctx context.Context, ts *types.TipSet)
return c.Internal.StateListActors(ctx, ts) return c.Internal.StateListActors(ctx, ts)
} }
func (c *FullNodeStruct) StateTipSetWeight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
return c.Internal.StateTipSetWeight(ctx, ts)
}
func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) { func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) {
return c.Internal.PaychGet(ctx, from, to, ensureFunds) return c.Internal.PaychGet(ctx, from, to, ensureFunds)
} }

View File

@ -53,7 +53,7 @@ func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address, bstore.Blockstore)
cs := store.NewChainStore(bs, nil) cs := store.NewChainStore(bs, nil)
// TODO: should probabaly mock out the randomness bit, nil works for now // 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -158,7 +158,7 @@ func NewHarness(t *testing.T, options ...HarnessOpt) *Harness {
t.Fatal(err) t.Fatal(err)
} }
h.cs = store.NewChainStore(h.bs, nil) 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -1,13 +1,13 @@
package deals package deals
import ( import (
"github.com/filecoin-project/go-lotus/api" "github.com/filecoin-project/go-lotus/api"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
"github.com/filecoin-project/go-lotus/chain/address" "github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types" "github.com/filecoin-project/go-lotus/chain/types"
) )
func init() { func init() {
cbor.RegisterCborType(UnsignedStorageDealProposal{}) cbor.RegisterCborType(UnsignedStorageDealProposal{})
@ -34,19 +34,19 @@ const (
) )
type UnsignedStorageDealProposal struct { type UnsignedStorageDealProposal struct {
PieceRef cid.Cid // TODO: port to spec PieceRef cid.Cid // TODO: port to spec
PieceSize uint64 PieceSize uint64
Client address.Address Client address.Address
Provider address.Address Provider address.Address
ProposalExpiryEpoch uint64 ProposalExpiryEpoch uint64
DealExpiryEpoch uint64 DealExpiryEpoch uint64
StoragePrice types.BigInt StoragePrice types.BigInt
StorageCollateral types.BigInt StorageCollateral types.BigInt
ProposerSignature *types.Signature ProposerSignature *types.Signature
} }
type StorageDealProposal struct { type StorageDealProposal struct {

View File

@ -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) { 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 { if err != nil {
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err) return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
} }

View File

@ -4,16 +4,17 @@ import (
"context" "context"
"fmt" "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" "github.com/ipfs/go-cid"
"golang.org/x/xerrors" "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) { 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 { 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)
} }
@ -55,7 +56,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
state := ts.ParentState() 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()) 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() 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 { if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err) return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
} }

View File

@ -5,6 +5,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/filecoin-project/go-lotus/chain/vm"
"sync" "sync"
"github.com/filecoin-project/go-lotus/build" "github.com/filecoin-project/go-lotus/build"
@ -182,14 +183,14 @@ func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
return err return err
} }
if err := cs.PutTipSet(ts); err != nil { if err := cs.PutTipSet(context.TODO(), ts); err != nil {
return err return err
} }
return cs.ds.Put(dstore.NewKey("0"), b.Cid().Bytes()) 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() { for _, b := range ts.Blocks() {
if err := cs.PersistBlockHeader(b); err != nil { if err := cs.PersistBlockHeader(b); err != nil {
return err 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()) 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 errors.Wrap(err, "MaybeTakeHeavierTipSet failed in PutTipSet")
} }
return nil return nil
} }
func (cs *ChainStore) MaybeTakeHeavierTipSet(ts *types.TipSet) error { func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipSet) error {
cs.heaviestLk.Lock() cs.heaviestLk.Lock()
defer cs.heaviestLk.Unlock() 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 // 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 // difference between 'bootstrap sync' and 'caught up' sync, we need
// some other heuristic. // some other heuristic.
@ -465,7 +475,7 @@ func (cs *ChainStore) expandTipset(b *types.BlockHeader) (*types.TipSet, error)
return types.NewTipSet(all) 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 { if err := cs.PersistBlockHeader(b); err != nil {
return err return err
} }
@ -475,7 +485,7 @@ func (cs *ChainStore) AddBlock(b *types.BlockHeader) error {
return err return err
} }
if err := cs.MaybeTakeHeavierTipSet(ts); err != nil { if err := cs.MaybeTakeHeavierTipSet(ctx, ts); err != nil {
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed") return errors.Wrap(err, "MaybeTakeHeavierTipSet failed")
} }
@ -789,3 +799,24 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h uint64, ts *types
ts = pts 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)
}

View File

@ -10,6 +10,9 @@ import (
) )
func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) { func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
if ts == nil {
return types.NewInt(0), nil
}
// w[r+1] = w[r] + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den) // w[r+1] = w[r] + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
// wr = wRatio_num(0.5) * 2^8 / wRatio_den(2) // wr = wRatio_num(0.5) * 2^8 / wRatio_den(2)
@ -44,7 +47,6 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
eWeight := types.BigMul(types.BigMul(types.NewInt(uint64(totalPowerAtTipsetL2)), types.NewInt(uint64(len(ts.Blocks())))), wr) eWeight := types.BigMul(types.BigMul(types.NewInt(uint64(totalPowerAtTipsetL2)), types.NewInt(uint64(len(ts.Blocks())))), wr)
eWeight = types.BigDiv(eWeight, types.NewInt(build.BlocksPerEpoch)) eWeight = types.BigDiv(eWeight, types.NewInt(build.BlocksPerEpoch))
return types.BigAdd(out, eWeight), nil return types.BigAdd(out, eWeight), nil
} }
@ -52,9 +54,9 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) { func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
bstate := ts.ParentState() bstate := ts.ParentState()
r := vm.NewChainRand(cs, ts.Cids(), ts.Height(), nil) r := NewChainRand(cs, ts.Cids(), ts.Height(), nil)
vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs) vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs)
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)
} }

View File

@ -3,15 +3,16 @@ package vm
import ( import (
"context" "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"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors" "github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"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/types" "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() { func init() {

View File

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

View File

@ -210,8 +210,6 @@ func (m *Miner) GetBestMiningCandidate() (*MiningBase, error) {
return m.lastWork, nil return m.lastWork, nil
} }
if types.BigCmp(bts.Weight(), m.lastWork.ts.Weight()) <= 0 { if types.BigCmp(bts.Weight(), m.lastWork.ts.Weight()) <= 0 {
return m.lastWork, nil return m.lastWork, nil
} }