Merge remote-tracking branch 'origin/next' into feat/dyn-base-fee

This commit is contained in:
Łukasz Magiera 2020-08-07 04:15:42 +02:00
commit 0612c2eab9
7 changed files with 121 additions and 49 deletions

View File

@ -107,6 +107,14 @@ type FullNode interface {
// ChainExport returns a stream of bytes with CAR dump of chain data. // ChainExport returns a stream of bytes with CAR dump of chain data.
ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error) ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error)
// MethodGroup: Beacon
// The Beacon method group contains methods for interacting with the random beacon (DRAND)
// BeaconGetEntry returns the beacon entry for the given filecoin epoch. If
// the entry has not yet been produced, the call will block until the entry
// becomes available
BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error)
// GasEstimateFeeCap estimates gas fee cap // GasEstimateFeeCap estimates gas fee cap
GasEstimateFeeCap(context.Context, int64, types.TipSetKey) (types.BigInt, error) GasEstimateFeeCap(context.Context, int64, types.TipSetKey) (types.BigInt, error)

View File

@ -85,6 +85,8 @@ type FullNodeStruct struct {
ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"` ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"`
ChainExport func(context.Context, types.TipSetKey) (<-chan []byte, error) `perm:"read"` ChainExport func(context.Context, types.TipSetKey) (<-chan []byte, error) `perm:"read"`
BeaconGetEntry func(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
GasEsitmateGasPremium func(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"` GasEsitmateGasPremium func(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
GasEstimateGasLimit func(context.Context, *types.Message, types.TipSetKey) (int64, error) `perm:"read"` GasEstimateGasLimit func(context.Context, *types.Message, types.TipSetKey) (int64, error) `perm:"read"`
GasEstimateFeeCap func(context.Context, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"` GasEstimateFeeCap func(context.Context, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
@ -599,6 +601,10 @@ func (c *FullNodeStruct) ChainExport(ctx context.Context, tsk types.TipSetKey) (
return c.Internal.ChainExport(ctx, tsk) return c.Internal.ChainExport(ctx, tsk)
} }
func (c *FullNodeStruct) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
return c.Internal.BeaconGetEntry(ctx, epoch)
}
func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) { func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) {
return c.Internal.SyncState(ctx) return c.Internal.SyncState(ctx)
} }

View File

@ -132,21 +132,23 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
done := make(chan struct{}) done := make(chan struct{})
minedTwo := make(chan struct{}) minedTwo := make(chan struct{})
m2addr, err := sn[1].ActorAddress(context.TODO())
if err != nil {
t.Fatal(err)
}
go func() { go func() {
doneMinedTwo := false
defer close(done) defer close(done)
prevExpect := 0 complChan := minedTwo
for atomic.LoadInt32(&mine) != 0 { for atomic.LoadInt32(&mine) != 0 {
wait := make(chan int, 2) wait := make(chan int)
mdone := func(mined bool, err error) { mdone := func(mined bool, err error) {
go func() {
n := 0 n := 0
if mined { if mined {
n = 1 n = 1
} }
wait <- n wait <- n
}()
} }
if err := sn[0].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil { if err := sn[0].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil {
@ -166,33 +168,28 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
continue continue
} }
for { var nodeOneMined bool
n := 0 for _, node := range sn {
for i, node := range sn {
mb, err := node.MiningBase(ctx) mb, err := node.MiningBase(ctx)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
} }
if len(mb.Cids()) != expect { for _, b := range mb.Blocks() {
log.Warnf("node %d mining base not complete (%d, want %d)", i, len(mb.Cids()), expect) if b.Miner == m2addr {
continue nodeOneMined = true
}
n++
}
if n == len(sn) {
break break
} }
time.Sleep(blocktime)
} }
if prevExpect == 2 && expect == 2 && !doneMinedTwo {
close(minedTwo)
doneMinedTwo = true
} }
prevExpect = expect if nodeOneMined && complChan != nil {
close(complChan)
complChan = nil
}
} }
}() }()

View File

@ -133,7 +133,7 @@ tailLoop:
continue continue
} }
// this chain needs to be trimmed // this chain needs to be trimmed
last = i last += i
continue tailLoop continue tailLoop
} }

View File

@ -6,10 +6,11 @@ import (
"crypto/rand" "crypto/rand"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
"sync" "sync"
"time" "time"
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/specs-actors/actors/crypto"
@ -147,6 +148,11 @@ func (m *Miner) mine(ctx context.Context) {
default: default:
} }
var base *MiningBase
var onDone func(bool, error)
var injectNulls abi.ChainEpoch
for {
prebase, err := m.GetBestMiningCandidate(ctx) prebase, err := m.GetBestMiningCandidate(ctx)
if err != nil { if err != nil {
log.Errorf("failed to get best mining candidate: %s", err) log.Errorf("failed to get best mining candidate: %s", err)
@ -154,18 +160,37 @@ func (m *Miner) mine(ctx context.Context) {
continue continue
} }
if base != nil && base.TipSet.Height() == prebase.TipSet.Height() && base.NullRounds == prebase.NullRounds {
break
}
if base != nil {
onDone(false, nil)
}
// TODO: need to change the orchestration here. the problem is that
// we are waiting *after* we enter this loop and selecta mining
// candidate, which is almost certain to change in multiminer
// tests. Instead, we should block before entering the loop, so
// that when the test 'MineOne' function is triggered, we pull our
// best mining candidate at that time.
// Wait until propagation delay period after block we plan to mine on // Wait until propagation delay period after block we plan to mine on
onDone, injectNulls, err := m.waitFunc(ctx, prebase.TipSet.MinTimestamp()) onDone, injectNulls, err = m.waitFunc(ctx, prebase.TipSet.MinTimestamp())
if err != nil { if err != nil {
log.Error(err) log.Error(err)
continue continue
} }
base, err := m.GetBestMiningCandidate(ctx) // just wait for the beacon entry to become available before we select our final mining base
_, err = m.api.BeaconGetEntry(ctx, prebase.TipSet.Height()+prebase.NullRounds+1)
if err != nil { if err != nil {
log.Errorf("failed to get best mining candidate: %s", err) log.Errorf("failed getting beacon entry: %s", err)
continue continue
} }
base = prebase
}
if base.TipSet.Equals(lastBase.TipSet) && lastBase.NullRounds == base.NullRounds { if base.TipSet.Equals(lastBase.TipSet) && lastBase.NullRounds == base.NullRounds {
log.Warnf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.TipSet.Cids(), lastBase.NullRounds) log.Warnf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.TipSet.Cids(), lastBase.NullRounds)
m.niceSleep(time.Duration(build.BlockDelaySecs) * time.Second) m.niceSleep(time.Duration(build.BlockDelaySecs) * time.Second)

View File

@ -25,6 +25,7 @@ type FullNodeAPI struct {
full.MsigAPI full.MsigAPI
full.WalletAPI full.WalletAPI
full.SyncAPI full.SyncAPI
full.BeaconAPI
} }
var _ api.FullNode = &FullNodeAPI{} var _ api.FullNode = &FullNodeAPI{}

35
node/impl/full/beacon.go Normal file
View File

@ -0,0 +1,35 @@
package full
import (
"context"
"fmt"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"go.uber.org/fx"
)
type BeaconAPI struct {
fx.In
Beacon beacon.RandomBeacon
}
func (a *BeaconAPI) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
rr := a.Beacon.MaxBeaconRoundForEpoch(epoch, types.BeaconEntry{})
e := a.Beacon.Entry(ctx, rr)
select {
case be, ok := <-e:
if !ok {
return nil, fmt.Errorf("beacon get returned no value")
}
if be.Err != nil {
return nil, be.Err
}
return &be.Entry, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}