Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/mithril/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -2743,11 +2743,19 @@ postBootstrap:
ParentChainedMerkleRoot: tip.AlpenglowChainedMerkleRoot,
HasParentChainedMerkleRoot: tip.HasAlpenglowChainedMerkleRoot,
ParentLastEntryHash: tip.LastEntryHash,
ParentLastBlockhash: tip.LastBlockhash,
ParentBlockHeight: tip.BlockHeight,
LatestEvictedBlockhash: tip.LatestEvictedBlockhash,
EpochRewardsActive: tip.EpochRewardsActive,
PrevNumSigs: tip.PrevNumSigs,
PrevFeeGovernor: tip.PrevFeeGovernor,
AcctsLtHash: tip.AcctsLtHash,
Features: tip.Features,
BankSysvars: tip.BankSysvars,
EpochStakes: tip.EpochStakes,
TotalEpochStake: tip.TotalEpochStake,
NanosecondClockAccount: tip.NanosecondClockAccount,
HasNanosecondClockAccount: tip.HasNanosecondClockAccount,
UnrootedRead: tip.UnrootedRead,
TransactionStatuses: tip.TransactionStatuses,
}
Expand Down
24 changes: 12 additions & 12 deletions pkg/blockprod/commit_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ package blockprod
import (
b "github.com/Overclock-Validator/mithril/pkg/block"
"github.com/Overclock-Validator/mithril/pkg/fees"
"github.com/Overclock-Validator/mithril/pkg/global"
"github.com/Overclock-Validator/mithril/pkg/sealevel"
"github.com/gagliardetto/solana-go"
)

// LeaderBlockInput captures forged leader state for AccountsDB commit.
type LeaderBlockInput struct {
Bank *WorkingBank
EpochSchedule *sealevel.SysvarEpochSchedule
ParentSlot uint64
ParentBankhash solana.Hash
PrevNumSigs uint64
PrevFeeGovernor *sealevel.FeeRateGovernor
EntryBlockhash solana.Hash
TxFeeAccumulator fees.TxFeeInfoAccumulator
Bank *WorkingBank
ParentSlot uint64
ParentBankhash solana.Hash
ParentLastBlockhash solana.Hash
ParentBlockHeight uint64
PrevNumSigs uint64
PrevFeeGovernor *sealevel.FeeRateGovernor
EntryBlockhash solana.Hash
TxFeeAccumulator fees.TxFeeInfoAccumulator
}

func BuildLeaderBlock(in LeaderBlockInput) *b.Block {
Expand All @@ -28,22 +28,22 @@ func BuildLeaderBlock(in LeaderBlockInput) *b.Block {
ParentSlot: in.ParentSlot,
Leader: bank.Leader(),
Transactions: bank.ForgedTransactions(),
Epoch: in.EpochSchedule.GetEpoch(slot),
Epoch: bank.SlotCtx().Epoch,
Features: bank.SlotCtx().Features,
// Agave resets Bank.signature_count for every child bank. The parent
// count is used only to derive this slot's fee governor; it is not part
// of this slot's bank-hash signature count.
NumSignatures: bank.NumSignatures(),
PrevNumSignatures: in.PrevNumSigs,
PrevFeeRateGovernor: in.PrevFeeGovernor,
LastBlockhash: global.LatestBlockHash(),
LastBlockhash: in.ParentLastBlockhash,
Blockhash: in.EntryBlockhash,
BlockHeight: in.ParentBlockHeight + 1,
}
copy(block.ParentBankhash[:], in.ParentBankhash[:])
block.FeeRateGovernor = sealevel.NewFeeRateGovernorDerived(block.PrevFeeRateGovernor, block.PrevNumSignatures)
if block.FeeRateGovernor.PrevLamportsPerSignature == 0 {
block.FeeRateGovernor.PrevLamportsPerSignature = 5000
}
block.BlockHeight = global.BlockHeight() + 1
return block
}
17 changes: 10 additions & 7 deletions pkg/blockprod/commit_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ func TestBuildLeaderBlockSignatureCountIsBankLocal(t *testing.T) {
}

block := BuildLeaderBlock(LeaderBlockInput{
Bank: env.Bank,
EpochSchedule: &sealevel.SysvarEpochSchedule{SlotsPerEpoch: 54_000},
ParentSlot: 41,
ParentBankhash: solana.Hash{1},
PrevNumSigs: 1_750,
PrevFeeGovernor: &sealevel.FeeRateGovernor{LamportsPerSignature: 5_000},
EntryBlockhash: solana.Hash{2},
Bank: env.Bank,
ParentSlot: 41,
ParentBankhash: solana.Hash{1},
ParentLastBlockhash: solana.Hash{3},
ParentBlockHeight: 39,
PrevNumSigs: 1_750,
PrevFeeGovernor: &sealevel.FeeRateGovernor{LamportsPerSignature: 5_000},
EntryBlockhash: solana.Hash{2},
})

require.Equal(t, uint64(1_750), block.PrevNumSignatures)
require.Equal(t, uint64(5), block.NumSignatures)
require.Equal(t, solana.Hash{3}, solana.Hash(block.LastBlockhash))
require.Equal(t, uint64(40), block.BlockHeight)
}
57 changes: 40 additions & 17 deletions pkg/blockprod/leader.go
Original file line number Diff line number Diff line change
Expand Up @@ -999,21 +999,26 @@ func (l *LeaderLoop) finishActiveSlotLocked() {
footerRewards = l.rewardCerts.BuildForLeaderSlot(slot)
}

if l.accountsDb == nil || l.epochSchedule == nil || l.activeSess == nil {
l.failProductionWindowLocked(slot, leaderReasonFinalizationUnavailable, "accounts DB, epoch schedule, or broadcast session is unavailable")
if l.accountsDb == nil || l.activeSess == nil {
l.failProductionWindowLocked(slot, leaderReasonFinalizationUnavailable, "accounts DB or broadcast session is unavailable")
l.abortActiveSlotLocked()
return
}
parentLastBlockhash := l.parentCtx.ParentLastBlockhash
if parentLastBlockhash == (solana.Hash{}) {
parentLastBlockhash = l.parentCtx.ParentLastEntryHash
}

producedBlock := BuildLeaderBlock(LeaderBlockInput{
Bank: l.activeBank,
EpochSchedule: l.epochSchedule,
ParentSlot: l.parentCtx.ParentSlot,
ParentBankhash: l.parentCtx.ParentBankhash,
PrevNumSigs: l.parentCtx.PrevNumSigs,
PrevFeeGovernor: l.parentCtx.PrevFeeGovernor,
EntryBlockhash: tickHash,
TxFeeAccumulator: l.activeBank.TxFeeAccumulator(),
Bank: l.activeBank,
ParentSlot: l.parentCtx.ParentSlot,
ParentBankhash: l.parentCtx.ParentBankhash,
ParentLastBlockhash: parentLastBlockhash,
ParentBlockHeight: l.parentCtx.ParentBlockHeight,
PrevNumSigs: l.parentCtx.PrevNumSigs,
PrevFeeGovernor: l.parentCtx.PrevFeeGovernor,
EntryBlockhash: tickHash,
TxFeeAccumulator: l.activeBank.TxFeeAccumulator(),
})
producedBlock.SkipRewardCert = append([]byte(nil), footerRewards.Skip...)
producedBlock.NotarRewardCert = append([]byte(nil), footerRewards.Notar...)
Expand All @@ -1033,7 +1038,6 @@ func (l *LeaderLoop) finishActiveSlotLocked() {
AcctsDb: l.accountsDb,
SlotCtx: l.activeBank.SlotCtx(),
Block: producedBlock,
EpochSchedule: l.epochSchedule,
TxFeeAccumulator: l.activeBank.TxFeeAccumulator(),
AlpenglowClock: l.alpenglowClock,
AlpenglowShredVersion: l.shredVersion,
Expand Down Expand Up @@ -1139,6 +1143,14 @@ func (l *LeaderLoop) startSlotLocked(slot uint64) error {
if l.parentContext != nil {
parentCtx = l.parentContext(slot)
}
epochSchedule := l.epochSchedule
if parentCtx.BankSysvars != nil {
if bankEpochSchedule, ok := parentCtx.BankSysvars.EpochSchedule(); ok {
epochSchedule = &bankEpochSchedule
} else {
return fmt.Errorf("%w: EpochSchedule missing for replay parent slot %d", errParentNotReady, parentCtx.ParentSlot)
}
}
parentSlot := parentCtx.ParentSlot
if slot == 0 {
parentSlot = 0
Expand All @@ -1152,7 +1164,7 @@ func (l *LeaderLoop) startSlotLocked(slot uint64) error {
if slot > 0 && parentCtx.ParentBankhash == (solana.Hash{}) {
return fmt.Errorf("%w: parent bankhash missing for slot %d", errParentNotReady, parentSlot)
}
if slot > 0 && l.epochSchedule != nil && l.epochSchedule.GetEpoch(parentSlot) != l.epochSchedule.GetEpoch(slot) {
if slot > 0 && epochSchedule != nil && epochSchedule.GetEpoch(parentSlot) != epochSchedule.GetEpoch(slot) {
return fmt.Errorf("%w: parent block is slot %d", errEpochTransitionProductionUnsupported, parentSlot)
}
if parentCtx.EpochRewardsActive {
Expand All @@ -1164,6 +1176,14 @@ func (l *LeaderLoop) startSlotLocked(slot uint64) error {
if slot > 0 && parentCtx.PrevFeeGovernor == nil {
return fmt.Errorf("%w: parent fee rate governor missing for replay parent slot %d", errParentNotReady, parentSlot)
}
if slot > 0 && l.accountsDb != nil && parentCtx.BankSysvars == nil {
return fmt.Errorf("%w: bank sysvar snapshot missing for replay parent slot %d", errParentNotReady, parentSlot)
}
if slot > 0 && l.accountsDb != nil {
if err := parentCtx.BankSysvars.ValidateForExecution(); err != nil {
return fmt.Errorf("%w: invalid bank sysvar snapshot for replay parent slot %d: %v", errParentNotReady, parentSlot, err)
}
}
if slot > 0 && parentCtx.ReplayGeneration == 0 {
return fmt.Errorf("%w: replay generation missing for parent slot %d", errParentNotReady, parentSlot)
}
Expand Down Expand Up @@ -1191,22 +1211,25 @@ func (l *LeaderLoop) startSlotLocked(slot uint64) error {
Broadcaster: l.broadcaster,
UserAgent: l.userAgent,
})
slotCtx, err := NewLeaderSlotCtx(slot, parentSlot, l.accountsDb, parentCtx, l.epochSchedule)
slotCtx, err := NewLeaderSlotCtx(slot, parentSlot, l.accountsDb, parentCtx, epochSchedule)
if err != nil {
return fmt.Errorf("new leader slot ctx: %w", err)
}
if l.accountsDb != nil && l.epochSchedule != nil {
if l.accountsDb != nil && epochSchedule != nil {
prepBlock := &b.Block{
Slot: slot,
ParentSlot: parentSlot,
Epoch: l.epochSchedule.GetEpoch(slot),
Epoch: epochSchedule.GetEpoch(slot),
ParentBankhash: parentCtx.ParentBankhash,
}
if err := replay.PrepareLeaderSlotSysvars(slotCtx, prepBlock, l.epochSchedule, l.alpenglowClock); err != nil {
if err := replay.PrepareLeaderSlotSysvars(slotCtx, prepBlock, l.alpenglowClock); err != nil {
return fmt.Errorf("prepare leader sysvars: %w", err)
}
}
startEntryHash := parentCtx.ParentLastEntryHash
startEntryHash := parentCtx.ParentLastBlockhash
if startEntryHash == (solana.Hash{}) {
startEntryHash = parentCtx.ParentLastEntryHash
}
if startEntryHash == (solana.Hash{}) {
startEntryHash = parentCtx.ParentBankhash
}
Expand Down
Loading
Loading