Skip to content

Commit

Permalink
Try #5288:
Browse files Browse the repository at this point in the history
  • Loading branch information
spacemesh-bors[bot] authored Nov 21, 2023
2 parents a553f80 + 1f5eb0d commit 9be89ca
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 68 deletions.
4 changes: 0 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,6 @@ type BaseConfig struct {

NetworkHRP string `mapstructure:"network-hrp"`

// MinerGoodAtxsPercent is a threshold to decide if tortoise activeset should be
// picked from first block instead of synced data.
MinerGoodAtxsPercent int `mapstructure:"miner-good-atxs-percent"`

RegossipAtxInterval time.Duration `mapstructure:"regossip-atx-interval"`
}

Expand Down
3 changes: 0 additions & 3 deletions config/presets/fastnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ func fastnet() config.Config {
conf.BaseConfig.OptFilterThreshold = 90
conf.BaseConfig.DatabasePruneInterval = time.Minute

// set for systest TestEquivocation
conf.BaseConfig.MinerGoodAtxsPercent = 50

conf.HARE3.Enable = true
conf.HARE3.DisableLayer = types.LayerID(math.MaxUint32)
conf.HARE3.Committee = 800
Expand Down
63 changes: 26 additions & 37 deletions miner/proposal_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,13 @@ type config struct {
networkDelay time.Duration
workersLimit int
minActiveSetWeight []types.EpochMinimalActiveWeight
// used to determine whether a node has enough information on the active set this epoch
goodAtxPercent int
}

func (c *config) MarshalLogObject(encoder log.ObjectEncoder) error {
encoder.AddUint32("layer size", c.layerSize)
encoder.AddUint32("epoch size", c.layersPerEpoch)
encoder.AddUint32("hdist", c.hdist)
encoder.AddDuration("network delay", c.networkDelay)
encoder.AddInt("good atx percent", c.goodAtxPercent)
return nil
}

Expand Down Expand Up @@ -214,12 +211,6 @@ func WithNetworkDelay(delay time.Duration) Opt {
}
}

func WithMinGoodAtxPercent(percent int) Opt {
return func(pb *ProposalBuilder) {
pb.cfg.goodAtxPercent = percent
}
}

// WithSigners guarantees that builder will start execution with provided list of signers.
// Should be after logging.
func WithSigners(signers ...*signing.EdSigner) Opt {
Expand Down Expand Up @@ -383,14 +374,17 @@ func (pb *ProposalBuilder) initSharedData(ctx context.Context, lid types.LayerID
weight, set, err := generateActiveSet(
pb.logger,
pb.cdb,
lid,
pb.shared.epoch,
pb.clock.LayerToTime(pb.shared.epoch.FirstLayer()),
pb.cfg.goodAtxPercent,
pb.cfg.networkDelay,
)
if err != nil {
return err
}
sort.Slice(set, func(i, j int) bool {
return bytes.Compare(set[i].Bytes(), set[j].Bytes()) < 0
})
pb.shared.active.set = set
pb.shared.active.weight = weight
}
Expand Down Expand Up @@ -713,15 +707,29 @@ func activesFromFirstBlock(
func generateActiveSet(
logger log.Log,
cdb *datastore.CachedDB,
current types.LayerID,
target types.EpochID,
epochStart time.Time,
goodAtxPercent int,
networkDelay time.Duration,
) (uint64, []types.ATXID, error) {
if !current.FirstInEpoch() {
totalWeight, set, err := activesFromFirstBlock(cdb, target)
if err != nil {
logger.With().Warning("failed to get active set from first block", log.Err(err))
} else if len(set) == 0 || totalWeight == 0 {
logger.With().Warning("empty active set from first block")
} else {
logger.With().Info("miner active set from first block",
log.Uint64("total weight", totalWeight),
log.Int("set size", len(set)),
)
return totalWeight, set, nil
}
}
var (
totalWeight uint64
set []types.ATXID
numOmitted = 0
numOmitted int
)
if err := cdb.IterateEpochATXHeaders(target, func(header *types.ActivationTxHeader) error {
grade, err := gradeAtx(cdb, header.NodeID, header.Received, epochStart, networkDelay)
Expand All @@ -745,33 +753,14 @@ func generateActiveSet(
}); err != nil {
return 0, nil, err
}

if total := numOmitted + len(set); total == 0 {
if len(set) == 0 || totalWeight == 0 {
return 0, nil, fmt.Errorf("empty active set")
} else if numOmitted*100/total > 100-goodAtxPercent {
// if the node is not synced during `targetEpoch-1`, it doesn't have the correct receipt timestamp
// for all the atx and malfeasance proof. this active set is not usable.
// TODO: change after timing info of ATXs and malfeasance proofs is sync'ed from peers as well
var err error
totalWeight, set, err = activesFromFirstBlock(cdb, target)
if err != nil {
return 0, nil, err
}
logger.With().Info("miner not synced during prior epoch, active set from first block",
log.Int("all atx", total),
log.Int("num omitted", numOmitted),
log.Int("num block atx", len(set)),
)
} else {
logger.With().Info("active set selected for proposal using grades",
log.Int("num atx", len(set)),
log.Int("num omitted", numOmitted),
log.Int("min atx good pct", goodAtxPercent),
)
}
sort.Slice(set, func(i, j int) bool {
return bytes.Compare(set[i].Bytes(), set[j].Bytes()) < 0
})
logger.With().Info("active set selected using grades",
log.Uint64("total weight", totalWeight),
log.Int("num atx", len(set)),
log.Int("num omitted", numOmitted),
)
return totalWeight, set, nil
}

Expand Down
120 changes: 101 additions & 19 deletions miner/proposal_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,6 @@ func TestBuild(t *testing.T) {
desc: "first block activeset",
opts: []Opt{
WithNetworkDelay(10 * time.Second),
WithMinGoodAtxPercent(50),
},
steps: []step{
{
Expand All @@ -498,45 +497,128 @@ func TestBuild(t *testing.T) {
gatx(types.ATXID{2}, 2, types.NodeID{2}, 1, genAtxWithReceived(time.Unix(20, 0))),
gatx(types.ATXID{3}, 2, types.NodeID{3}, 1, genAtxWithReceived(time.Unix(20, 0))),
},
expectErr: "first block",
},
{
lid: 16,
activeset: gactiveset(types.ATXID{2}, types.ATXID{3}),
ballots: []*types.Ballot{
gballot(types.BallotID{11}, types.ATXID{3}, types.NodeID{5}, 15, &types.EpochData{
ActiveSetHash: gactiveset(types.ATXID{2}, types.ATXID{3}).Hash(),
}),
},
blocks: []*types.Block{
gblock(15, types.ATXID{4}), // this atx and ballot doesn't exist
gblock(15, types.ATXID{3}),
},
expectErr: "actives get ballot",
opinion: &types.Opinion{Hash: types.Hash32{1}},
txs: []types.TransactionID{},
latestComplete: 15,
expectProposal: expectProposal(
signer, 16, types.ATXID{1}, types.Opinion{Hash: types.Hash32{1}},
expectEpochData(
gactiveset(types.ATXID{2}, types.ATXID{3}),
25,
types.Beacon{1},
),
expectCounters(signer, 3, types.Beacon{1}, 777, 2, 5, 11, 19, 22, 24),
),
},
},
},
{
desc: "first block not in the first layer",
opts: []Opt{
WithNetworkDelay(10 * time.Second),
},
steps: []step{
{
lid: 16,
lid: 17,
beacon: types.Beacon{1},
atxs: []*types.VerifiedActivationTx{
gatx(types.ATXID{1}, 2, signer.NodeID(), 1, genAtxWithNonce(777)),
gatx(types.ATXID{2}, 2, types.NodeID{2}, 1, genAtxWithReceived(time.Unix(20, 0))),
gatx(types.ATXID{3}, 2, types.NodeID{3}, 1, genAtxWithReceived(time.Unix(20, 0))),
},
activeset: gactiveset(types.ATXID{2}, types.ATXID{3}),
ballots: []*types.Ballot{
gballot(types.BallotID{11}, types.ATXID{4}, types.NodeID{5}, 15, &types.EpochData{
ActiveSetHash: gactiveset(types.ATXID{1}, types.ATXID{2}).Hash(),
gballot(types.BallotID{11}, types.ATXID{3}, types.NodeID{5}, 15, &types.EpochData{
ActiveSetHash: gactiveset(types.ATXID{2}, types.ATXID{3}).Hash(),
}),
},
expectErr: "get active hash for ballot",
blocks: []*types.Block{
gblock(16, types.ATXID{3}),
},
opinion: &types.Opinion{Hash: types.Hash32{1}},
txs: []types.TransactionID{},
latestComplete: 16,
expectProposal: expectProposal(
signer, 17, types.ATXID{1}, types.Opinion{Hash: types.Hash32{1}},
expectEpochData(
gactiveset(types.ATXID{2}, types.ATXID{3}),
25,
types.Beacon{1},
),
expectCounters(signer, 3, types.Beacon{1}, 777, 3, 7, 10, 14, 15, 21),
),
},
},
},
{
desc: "first block empty",
opts: []Opt{
WithNetworkDelay(10 * time.Second),
},
steps: []step{
{
lid: 16,
activeset: gactiveset(types.ATXID{1}, types.ATXID{2}),
expectErr: "get ATXs from DB: get id 0400000000",
lid: 16,
beacon: types.Beacon{1},
atxs: []*types.VerifiedActivationTx{
gatx(types.ATXID{1}, 2, signer.NodeID(), 1, genAtxWithNonce(777)),
gatx(types.ATXID{2}, 2, types.NodeID{2}, 1, genAtxWithNonce(777)),
gatx(types.ATXID{3}, 2, types.NodeID{3}, 1, genAtxWithReceived(time.Unix(20, 0))),
},
blocks: []*types.Block{
gblock(15),
},
opinion: &types.Opinion{Hash: types.Hash32{1}},
txs: []types.TransactionID{},
latestComplete: 15,
expectProposal: expectProposal(
signer, 16, types.ATXID{1}, types.Opinion{Hash: types.Hash32{1}},
expectEpochData(
gactiveset(types.ATXID{1}, types.ATXID{2}),
25,
types.Beacon{1},
),
expectCounters(signer, 3, types.Beacon{1}, 777, 2, 5, 11, 19, 22, 24),
),
},
},
},
{
desc: "first block missing ballot",
opts: []Opt{
WithNetworkDelay(10 * time.Second),
},
steps: []step{
{
lid: 16,
lid: 16,
beacon: types.Beacon{1},
atxs: []*types.VerifiedActivationTx{
gatx(types.ATXID{4}, 2, types.NodeID{4}, 1, genAtxWithReceived(time.Unix(20, 0))),
gatx(types.ATXID{1}, 2, signer.NodeID(), 1, genAtxWithNonce(777)),
gatx(types.ATXID{2}, 2, types.NodeID{2}, 1, genAtxWithNonce(777)),
gatx(types.ATXID{3}, 2, types.NodeID{3}, 1, genAtxWithReceived(time.Unix(20, 0))),
},
blocks: []*types.Block{
gblock(15, types.ATXID{4}),
},
opinion: &types.Opinion{Hash: types.Hash32{1}},
txs: []types.TransactionID{},
latestComplete: 15,
expectProposal: expectProposal(
signer, 16, types.ATXID{1}, types.Opinion{Hash: types.Hash32{1}},
expectEpochData(
gactiveset(types.ATXID{1}, types.ATXID{2}, types.ATXID{4}),
16,
gactiveset(types.ATXID{1}, types.ATXID{2}),
25,
types.Beacon{1},
),
expectCounters(signer, 3, types.Beacon{1}, 777, 2, 5, 11),
expectCounters(signer, 3, types.Beacon{1}, 777, 2, 5, 11, 19, 22, 24),
),
},
},
Expand Down
5 changes: 0 additions & 5 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -845,10 +845,6 @@ func (app *App) initServices(ctx context.Context) error {
blocks.WithGeneratorLogger(app.addLogger(BlockGenLogger, lg)),
)

minerGoodAtxPct := 90
if app.Config.MinerGoodAtxsPercent > 0 {
minerGoodAtxPct = app.Config.MinerGoodAtxsPercent
}
proposalBuilder := miner.New(
app.clock,
app.cachedDB,
Expand All @@ -862,7 +858,6 @@ func (app *App) initServices(ctx context.Context) error {
miner.WithHdist(app.Config.Tortoise.Hdist),
// TODO(dshulyak) ???
miner.WithNetworkDelay(app.Config.HARE3.PreroundDelay),
miner.WithMinGoodAtxPercent(minerGoodAtxPct),
miner.WithLogger(app.addLogger(ProposalBuilderLogger, lg)),
)
proposalBuilder.Register(app.edSgn)
Expand Down

0 comments on commit 9be89ca

Please sign in to comment.