mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Update Beacon/Validator Flags to Disable Reward/Cross-Link Checking by Default (#597)
* flag updates * enable att validity, cross links, rewards * tests all pass * fix race * fix cov * fix flag * fix conf * fix race * fix gazelle
This commit is contained in:
@@ -33,19 +33,26 @@ type ChainService struct {
|
||||
canonicalCrystallizedStateFeed *event.Feed
|
||||
blocksPendingProcessing [][32]byte
|
||||
lock sync.Mutex
|
||||
devMode bool
|
||||
genesisTimestamp time.Time
|
||||
slotAlignmentDuration uint64
|
||||
enableCrossLinks bool
|
||||
enableRewardChecking bool
|
||||
enableAttestationValidity bool
|
||||
enablePOWChain bool
|
||||
}
|
||||
|
||||
// Config options for the service.
|
||||
type Config struct {
|
||||
BeaconBlockBuf int
|
||||
IncomingBlockBuf int
|
||||
Chain *BeaconChain
|
||||
Web3Service *powchain.Web3Service
|
||||
BeaconDB ethdb.Database
|
||||
DevMode bool
|
||||
BeaconBlockBuf int
|
||||
IncomingBlockBuf int
|
||||
Chain *BeaconChain
|
||||
Web3Service *powchain.Web3Service
|
||||
BeaconDB ethdb.Database
|
||||
DevMode bool
|
||||
EnableCrossLinks bool
|
||||
EnableRewardChecking bool
|
||||
EnableAttestationValidity bool
|
||||
EnablePOWChain bool
|
||||
}
|
||||
|
||||
// NewChainService instantiates a new service instance that will
|
||||
@@ -64,7 +71,10 @@ func NewChainService(ctx context.Context, cfg *Config) (*ChainService, error) {
|
||||
canonicalBlockFeed: new(event.Feed),
|
||||
canonicalCrystallizedStateFeed: new(event.Feed),
|
||||
blocksPendingProcessing: [][32]byte{},
|
||||
devMode: cfg.DevMode,
|
||||
enablePOWChain: cfg.EnablePOWChain,
|
||||
enableCrossLinks: cfg.EnableCrossLinks,
|
||||
enableRewardChecking: cfg.EnableRewardChecking,
|
||||
enableAttestationValidity: cfg.EnableAttestationValidity,
|
||||
slotAlignmentDuration: params.GetConfig().SlotDuration,
|
||||
}, nil
|
||||
}
|
||||
@@ -247,7 +257,12 @@ func (c *ChainService) updateHead(slotInterval <-chan time.Time) {
|
||||
var stateTransitioned bool
|
||||
|
||||
for cState.IsCycleTransition(parentBlock.SlotNumber()) {
|
||||
cState, aState, err = cState.NewStateRecalculations(aState, block)
|
||||
cState, aState, err = cState.NewStateRecalculations(
|
||||
aState,
|
||||
block,
|
||||
c.enableCrossLinks,
|
||||
c.enableRewardChecking,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("Initialize new cycle transition failed: %v", err)
|
||||
continue
|
||||
@@ -255,7 +270,12 @@ func (c *ChainService) updateHead(slotInterval <-chan time.Time) {
|
||||
stateTransitioned = true
|
||||
}
|
||||
|
||||
aState, err = aState.CalculateNewActiveState(block, cState, parentBlock.SlotNumber())
|
||||
aState, err = aState.CalculateNewActiveState(
|
||||
block,
|
||||
cState,
|
||||
parentBlock.SlotNumber(),
|
||||
c.enableAttestationValidity,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("Compute active state failed: %v", err)
|
||||
continue
|
||||
@@ -321,7 +341,7 @@ func (c *ChainService) blockProcessing() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !c.devMode && !c.doesPoWBlockExist(block) {
|
||||
if c.enablePOWChain && !c.doesPoWBlockExist(block) {
|
||||
log.Debugf("Proof-of-Work chain reference in block does not exist")
|
||||
continue
|
||||
}
|
||||
@@ -345,7 +365,7 @@ func (c *ChainService) blockProcessing() {
|
||||
aState := c.chain.ActiveState()
|
||||
cState := c.chain.CrystallizedState()
|
||||
|
||||
if valid := block.IsValid(c, aState, cState, parent.SlotNumber()); !valid {
|
||||
if valid := block.IsValid(c, aState, cState, parent.SlotNumber(), c.enableAttestationValidity); !valid {
|
||||
log.Debugf("Block failed validity conditions: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -315,6 +315,7 @@ func TestRunningChainServiceFaultyPOWChain(t *testing.T) {
|
||||
BeaconDB: db.DB(),
|
||||
Chain: beaconChain,
|
||||
Web3Service: web3Service,
|
||||
EnablePOWChain: true,
|
||||
}
|
||||
chainService, _ := NewChainService(ctx, cfg)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ VERSION:
|
||||
app.Action = startNode
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
utils.DevFlag,
|
||||
utils.DemoConfigFlag,
|
||||
utils.SimulatorFlag,
|
||||
utils.VrcContractFlag,
|
||||
utils.PubKeyFlag,
|
||||
@@ -69,6 +69,10 @@ VERSION:
|
||||
utils.CertFlag,
|
||||
utils.KeyFlag,
|
||||
utils.GenesisJSON,
|
||||
utils.EnableCrossLinks,
|
||||
utils.EnableRewardChecking,
|
||||
utils.EnableAttestationValidity,
|
||||
utils.EnablePOWChain,
|
||||
cmd.DataDirFlag,
|
||||
cmd.VerbosityFlag,
|
||||
cmd.EnableTracingFlag,
|
||||
|
||||
@@ -55,8 +55,8 @@ func NewBeaconNode(ctx *cli.Context) (*BeaconNode, error) {
|
||||
stop: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Use demo config values if dev flag is set.
|
||||
if ctx.GlobalBool(utils.DevFlag.Name) {
|
||||
// Use demo config values if demo config flag is set.
|
||||
if ctx.GlobalBool(utils.DemoConfigFlag.Name) {
|
||||
params.SetEnv("demo")
|
||||
}
|
||||
|
||||
@@ -170,25 +170,32 @@ func (b *BeaconNode) registerBlockchainService(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
var web3Service *powchain.Web3Service
|
||||
devMode := ctx.GlobalBool(utils.DevFlag.Name)
|
||||
if !devMode {
|
||||
enablePOWChain := ctx.GlobalBool(utils.EnablePOWChain.Name)
|
||||
if enablePOWChain {
|
||||
if err := b.services.FetchService(&web3Service); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
enableCrossLinks := ctx.GlobalBool(utils.EnableCrossLinks.Name)
|
||||
enableRewardChecking := ctx.GlobalBool(utils.EnableRewardChecking.Name)
|
||||
enableAttestationValidity := ctx.GlobalBool(utils.EnableAttestationValidity.Name)
|
||||
|
||||
beaconChain, err := blockchain.NewBeaconChain(genesisJSON, b.db.DB())
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not register blockchain service: %v", err)
|
||||
}
|
||||
|
||||
blockchainService, err := blockchain.NewChainService(context.TODO(), &blockchain.Config{
|
||||
BeaconDB: b.db.DB(),
|
||||
Web3Service: web3Service,
|
||||
Chain: beaconChain,
|
||||
BeaconBlockBuf: 10,
|
||||
IncomingBlockBuf: 100, // Big buffer to accommodate other feed subscribers.
|
||||
DevMode: devMode,
|
||||
BeaconDB: b.db.DB(),
|
||||
Web3Service: web3Service,
|
||||
Chain: beaconChain,
|
||||
BeaconBlockBuf: 10,
|
||||
IncomingBlockBuf: 100, // Big buffer to accommodate other feed subscribers.
|
||||
EnablePOWChain: enablePOWChain,
|
||||
EnableCrossLinks: enableCrossLinks,
|
||||
EnableRewardChecking: enableRewardChecking,
|
||||
EnableAttestationValidity: enableAttestationValidity,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not register blockchain service: %v", err)
|
||||
@@ -210,7 +217,7 @@ func (b *BeaconNode) registerService() error {
|
||||
}
|
||||
|
||||
func (b *BeaconNode) registerPOWChainService(ctx *cli.Context) error {
|
||||
if ctx.GlobalBool(utils.DevFlag.Name) {
|
||||
if !ctx.GlobalBool(utils.EnablePOWChain.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -285,8 +292,8 @@ func (b *BeaconNode) registerSimulatorService(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
var web3Service *powchain.Web3Service
|
||||
var devMode = ctx.GlobalBool(utils.DevFlag.Name)
|
||||
if !devMode {
|
||||
var enablePOWChain = ctx.GlobalBool(utils.EnablePOWChain.Name)
|
||||
if enablePOWChain {
|
||||
if err := b.services.FetchService(&web3Service); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -305,7 +312,7 @@ func (b *BeaconNode) registerSimulatorService(ctx *cli.Context) error {
|
||||
P2P: p2pService,
|
||||
Web3Service: web3Service,
|
||||
ChainService: chainService,
|
||||
DevMode: devMode,
|
||||
EnablePOWChain: enablePOWChain,
|
||||
}
|
||||
simulatorService := simulator.NewSimulator(context.TODO(), cfg)
|
||||
return b.services.RegisterService(simulatorService)
|
||||
@@ -323,8 +330,8 @@ func (b *BeaconNode) registerRPCService(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
var web3Service *powchain.Web3Service
|
||||
var devMode = ctx.GlobalBool(utils.DevFlag.Name)
|
||||
if !devMode {
|
||||
var enablePOWChain = ctx.GlobalBool(utils.EnablePOWChain.Name)
|
||||
if enablePOWChain {
|
||||
if err := b.services.FetchService(&web3Service); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -342,7 +349,7 @@ func (b *BeaconNode) registerRPCService(ctx *cli.Context) error {
|
||||
ChainService: chainService,
|
||||
AttestationService: attestationService,
|
||||
POWChainService: web3Service,
|
||||
DevMode: devMode,
|
||||
EnablePOWChain: enablePOWChain,
|
||||
})
|
||||
|
||||
return b.services.RegisterService(rpcService)
|
||||
|
||||
@@ -20,6 +20,7 @@ func TestNodeValidator_Builds(t *testing.T) {
|
||||
set.String("web3provider", "ws//127.0.0.1:8546", "web3 provider ws or IPC endpoint")
|
||||
tmp := fmt.Sprintf("%s/datadir", os.TempDir())
|
||||
set.String("datadir", tmp, "node data directory")
|
||||
set.Bool("enable-powchain", true, "enable powchain")
|
||||
|
||||
context := cli.NewContext(app, set, nil)
|
||||
|
||||
@@ -47,7 +48,8 @@ func TestNodeStart(t *testing.T) {
|
||||
set.String("web3provider", "ws//127.0.0.1:8546", "web3 provider ws or IPC endpoint")
|
||||
tmp := fmt.Sprintf("%s/datadir", os.TempDir())
|
||||
set.String("datadir", tmp, "node data directory")
|
||||
set.Bool("dev", true, "dev mode")
|
||||
set.Bool("enable-powchain", false, "no powchain service")
|
||||
set.Bool("demo-config", true, "demo configuration")
|
||||
|
||||
context := cli.NewContext(app, set, nil)
|
||||
|
||||
@@ -68,7 +70,8 @@ func TestNodeClose(t *testing.T) {
|
||||
set.String("web3provider", "ws//127.0.0.1:8546", "web3 provider ws or IPC endpoint")
|
||||
tmp := fmt.Sprintf("%s/datadir", os.TempDir())
|
||||
set.String("datadir", tmp, "node data directory")
|
||||
set.Bool("dev", true, "dev mode")
|
||||
set.Bool("enable-powchain", false, "no powchain service")
|
||||
set.Bool("demo-config", true, "demo configuration")
|
||||
|
||||
context := cli.NewContext(app, set, nil)
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ type Service struct {
|
||||
canonicalBlockChan chan *types.Block
|
||||
canonicalStateChan chan *types.CrystallizedState
|
||||
incomingAttestation chan *types.Attestation
|
||||
devMode bool
|
||||
enablePOWChain bool
|
||||
slotAlignmentDuration time.Duration
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ type Config struct {
|
||||
ChainService chainService
|
||||
POWChainService powChainService
|
||||
AttestationService attestationService
|
||||
DevMode bool
|
||||
EnablePOWChain bool
|
||||
}
|
||||
|
||||
// NewRPCService creates a new instance of a struct implementing the BeaconServiceServer
|
||||
@@ -107,7 +107,7 @@ func NewRPCService(ctx context.Context, cfg *Config) *Service {
|
||||
canonicalBlockChan: make(chan *types.Block, cfg.SubscriptionBuf),
|
||||
canonicalStateChan: make(chan *types.CrystallizedState, cfg.SubscriptionBuf),
|
||||
incomingAttestation: make(chan *types.Attestation, cfg.SubscriptionBuf),
|
||||
devMode: cfg.DevMode,
|
||||
enablePOWChain: cfg.EnablePOWChain,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,8 +208,8 @@ func (s *Service) CurrentAssignmentsAndGenesisTime(ctx context.Context, req *pb.
|
||||
// sends the request into a beacon block that can then be included in a canonical chain.
|
||||
func (s *Service) ProposeBlock(ctx context.Context, req *pb.ProposeRequest) (*pb.ProposeResponse, error) {
|
||||
var powChainHash common.Hash
|
||||
if s.devMode {
|
||||
powChainHash = common.BytesToHash([]byte("stub"))
|
||||
if !s.enablePOWChain {
|
||||
powChainHash = common.BytesToHash([]byte{byte(req.GetSlotNumber())})
|
||||
} else {
|
||||
powChainHash = s.powChainService.LatestBlockHash()
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ type Simulator struct {
|
||||
web3Service types.POWChainService
|
||||
chainService types.StateFetcher
|
||||
beaconDB ethdb.Database
|
||||
devMode bool
|
||||
enablePOWChain bool
|
||||
delay time.Duration
|
||||
slotNum uint64
|
||||
broadcastedBlocks map[[32]byte]*types.Block
|
||||
@@ -44,7 +44,7 @@ type Config struct {
|
||||
Web3Service types.POWChainService
|
||||
ChainService types.StateFetcher
|
||||
BeaconDB ethdb.Database
|
||||
DevMode bool
|
||||
EnablePOWChain bool
|
||||
}
|
||||
|
||||
// DefaultConfig options for the simulator.
|
||||
@@ -66,7 +66,7 @@ func NewSimulator(ctx context.Context, cfg *Config) *Simulator {
|
||||
chainService: cfg.ChainService,
|
||||
beaconDB: cfg.BeaconDB,
|
||||
delay: cfg.Delay,
|
||||
devMode: cfg.DevMode,
|
||||
enablePOWChain: cfg.EnablePOWChain,
|
||||
slotNum: 1,
|
||||
broadcastedBlocks: make(map[[32]byte]*types.Block),
|
||||
broadcastedBlockHashes: [][32]byte{},
|
||||
@@ -165,10 +165,10 @@ func (sim *Simulator) run(delayChan <-chan time.Time, done <-chan struct{}) {
|
||||
log.WithField("currentSlot", sim.slotNum).Debug("Current slot")
|
||||
|
||||
var powChainRef []byte
|
||||
if !sim.devMode {
|
||||
if sim.enablePOWChain {
|
||||
powChainRef = sim.web3Service.LatestBlockHash().Bytes()
|
||||
} else {
|
||||
powChainRef = []byte("stub")
|
||||
powChainRef = []byte{byte(sim.slotNum)}
|
||||
}
|
||||
|
||||
block := types.NewBlock(&pb.BeaconBlock{
|
||||
|
||||
@@ -60,7 +60,7 @@ func TestLifecycle(t *testing.T) {
|
||||
Web3Service: &mockPOWChainService{},
|
||||
ChainService: &mockChainService{},
|
||||
BeaconDB: db,
|
||||
DevMode: false,
|
||||
EnablePOWChain: true,
|
||||
}
|
||||
sim := NewSimulator(context.Background(), cfg)
|
||||
|
||||
@@ -85,7 +85,7 @@ func TestBroadcastBlockHash(t *testing.T) {
|
||||
Web3Service: &mockPOWChainService{},
|
||||
ChainService: &mockChainService{},
|
||||
BeaconDB: db,
|
||||
DevMode: false,
|
||||
EnablePOWChain: false,
|
||||
}
|
||||
sim := NewSimulator(context.Background(), cfg)
|
||||
|
||||
@@ -121,7 +121,7 @@ func TestBlockRequest(t *testing.T) {
|
||||
Web3Service: &mockPOWChainService{},
|
||||
ChainService: &mockChainService{},
|
||||
BeaconDB: db,
|
||||
DevMode: true,
|
||||
EnablePOWChain: false,
|
||||
}
|
||||
sim := NewSimulator(context.Background(), cfg)
|
||||
|
||||
@@ -167,7 +167,7 @@ func TestLastSimulatedSession(t *testing.T) {
|
||||
Web3Service: &mockPOWChainService{},
|
||||
ChainService: &mockChainService{},
|
||||
BeaconDB: db,
|
||||
DevMode: true,
|
||||
EnablePOWChain: false,
|
||||
}
|
||||
sim := NewSimulator(context.Background(), cfg)
|
||||
if err := db.Put([]byte("last-simulated-block"), []byte{}); err != nil {
|
||||
|
||||
@@ -202,7 +202,11 @@ func (a *ActiveState) calculateNewVoteCache(block *Block, cState *CrystallizedSt
|
||||
|
||||
// CalculateNewActiveState returns the active state for `block` based on its own state.
|
||||
// This method should not modify its own state.
|
||||
func (a *ActiveState) CalculateNewActiveState(block *Block, cState *CrystallizedState, parentSlot uint64) (*ActiveState, error) {
|
||||
func (a *ActiveState) CalculateNewActiveState(
|
||||
block *Block,
|
||||
cState *CrystallizedState,
|
||||
parentSlot uint64,
|
||||
enableAttestationValidity bool) (*ActiveState, error) {
|
||||
// Derive the new set of pending attestations.
|
||||
newPendingAttestations := a.appendNewAttestations(block.data.Attestations)
|
||||
|
||||
@@ -212,16 +216,22 @@ func (a *ActiveState) CalculateNewActiveState(block *Block, cState *Crystallized
|
||||
return nil, fmt.Errorf("failed to update recent block hashes: %v", err)
|
||||
}
|
||||
|
||||
log.Debugf("Calculating new active state. Crystallized state lastStateRecalc is %d", cState.LastStateRecalc())
|
||||
|
||||
// With a valid beacon block, we can compute its attestations and store its votes/deposits in cache.
|
||||
newBlockVoteCache, err := a.calculateNewVoteCache(block, cState)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update vote cache: %v", err)
|
||||
blockVoteCache := a.blockVoteCache
|
||||
|
||||
if enableAttestationValidity {
|
||||
blockVoteCache, err = a.calculateNewVoteCache(block, cState)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update vote cache: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return NewActiveState(&pb.ActiveState{
|
||||
PendingAttestations: newPendingAttestations,
|
||||
RecentBlockHashes: newRecentBlockHashes,
|
||||
}, newBlockVoteCache), nil
|
||||
}, blockVoteCache), nil
|
||||
}
|
||||
|
||||
// getSignedParentHashes returns all the parent hashes stored in active state up to last cycle length.
|
||||
|
||||
@@ -253,7 +253,20 @@ func TestCalculateNewActiveState(t *testing.T) {
|
||||
RecentBlockHashes: recentBlockHashes,
|
||||
}, nil)
|
||||
|
||||
aState, err = aState.CalculateNewActiveState(block, cState, 0)
|
||||
aState, err = aState.CalculateNewActiveState(block, cState, 0, false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to calculate new active state: %v", err)
|
||||
}
|
||||
|
||||
if len(aState.PendingAttestations()) != 2 {
|
||||
t.Fatalf("expected 2 pending attestations, got %d", len(aState.PendingAttestations()))
|
||||
}
|
||||
|
||||
if len(aState.RecentBlockHashes()) != 2*int(params.GetConfig().CycleLength) {
|
||||
t.Fatalf("incorrect number of items in RecentBlockHashes: %d", len(aState.RecentBlockHashes()))
|
||||
}
|
||||
|
||||
aState, err = aState.CalculateNewActiveState(block, cState, 0, true)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to calculate new active state: %v", err)
|
||||
}
|
||||
|
||||
@@ -147,7 +147,12 @@ func (b *Block) isSlotValid() bool {
|
||||
// IsValid is called to decide if an incoming p2p block can be processed. It checks for following conditions:
|
||||
// 1.) Ensure local time is large enough to process this block's slot.
|
||||
// 2.) Verify that the parent block's proposer's attestation is included.
|
||||
func (b *Block) IsValid(chain chainSearchService, aState *ActiveState, cState *CrystallizedState, parentSlot uint64) bool {
|
||||
func (b *Block) IsValid(
|
||||
chain chainSearchService,
|
||||
aState *ActiveState,
|
||||
cState *CrystallizedState,
|
||||
parentSlot uint64,
|
||||
enableAttestationValidity bool) bool {
|
||||
_, err := b.Hash()
|
||||
if err != nil {
|
||||
log.Errorf("Could not hash incoming block: %v", err)
|
||||
@@ -186,6 +191,18 @@ func (b *Block) IsValid(chain chainSearchService, aState *ActiveState, cState *C
|
||||
}
|
||||
}
|
||||
|
||||
if enableAttestationValidity {
|
||||
log.Debugf("Checking block validity. Recent block hash is %d",
|
||||
aState.data.RecentBlockHashes[0],
|
||||
)
|
||||
for index, attestation := range b.Attestations() {
|
||||
if !b.isAttestationValid(index, chain, aState, cState, parentSlot) {
|
||||
log.Debugf("attestation invalid: %v", attestation)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,10 @@ func TestBlockValidity(t *testing.T) {
|
||||
t.Fatalf("failed attestation validation")
|
||||
}
|
||||
|
||||
if !b.IsValid(chainService, aState, cState, parentSlot) {
|
||||
if !b.IsValid(chainService, aState, cState, parentSlot, false) {
|
||||
t.Fatalf("failed block validation")
|
||||
}
|
||||
if !b.IsValid(chainService, aState, cState, parentSlot, true) {
|
||||
t.Fatalf("failed block validation")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,10 +258,10 @@ func (c *CrystallizedState) getAttesterIndices(attestation *pb.AggregatedAttesta
|
||||
// NewStateRecalculations computes the new crystallized state, given the previous crystallized state
|
||||
// and the current active state. This method is called during a cycle transition.
|
||||
// We also check for dynasty transition and compute for a new dynasty if necessary during this transition.
|
||||
func (c *CrystallizedState) NewStateRecalculations(aState *ActiveState, block *Block) (*CrystallizedState, *ActiveState, error) {
|
||||
func (c *CrystallizedState) NewStateRecalculations(aState *ActiveState, block *Block, enableCrossLinks bool, enableRewardChecking bool) (*CrystallizedState, *ActiveState, error) {
|
||||
var blockVoteBalance uint64
|
||||
var lastStateRecalcCycleBack uint64
|
||||
var rewardedValidators []*pb.ValidatorRecord
|
||||
var newValidators []*pb.ValidatorRecord
|
||||
var newCrossLinkRecords []*pb.CrosslinkRecord
|
||||
var err error
|
||||
|
||||
@@ -282,6 +282,12 @@ func (c *CrystallizedState) NewStateRecalculations(aState *ActiveState, block *B
|
||||
lastStateRecalcCycleBack = lastStateRecalc - params.GetConfig().CycleLength
|
||||
}
|
||||
|
||||
// If reward checking is disabled, the new set of validators for the cycle
|
||||
// will remain the same.
|
||||
if !enableRewardChecking {
|
||||
newValidators = c.data.Validators
|
||||
}
|
||||
|
||||
// walk through all the slots from LastStateRecalc - cycleLength to LastStateRecalc - 1.
|
||||
for i := uint64(0); i < params.GetConfig().CycleLength; i++ {
|
||||
var voterIndices []uint32
|
||||
@@ -293,14 +299,15 @@ func (c *CrystallizedState) NewStateRecalculations(aState *ActiveState, block *B
|
||||
voterIndices = blockVoteCache[blockHash].VoterIndices
|
||||
|
||||
// Apply Rewards for each slot.
|
||||
rewardedValidators = casper.CalculateRewards(
|
||||
slot,
|
||||
voterIndices,
|
||||
c.Validators(),
|
||||
c.CurrentDynasty(),
|
||||
blockVoteBalance,
|
||||
timeSinceFinality)
|
||||
|
||||
if enableRewardChecking {
|
||||
newValidators = casper.CalculateRewards(
|
||||
slot,
|
||||
voterIndices,
|
||||
c.Validators(),
|
||||
c.CurrentDynasty(),
|
||||
blockVoteBalance,
|
||||
timeSinceFinality)
|
||||
}
|
||||
} else {
|
||||
blockVoteBalance = 0
|
||||
}
|
||||
@@ -319,9 +326,11 @@ func (c *CrystallizedState) NewStateRecalculations(aState *ActiveState, block *B
|
||||
finalizedSlot = slot - params.GetConfig().CycleLength - 1
|
||||
}
|
||||
|
||||
newCrossLinkRecords, err = c.processCrosslinks(aState.PendingAttestations(), slot, block.SlotNumber())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
if enableCrossLinks {
|
||||
newCrossLinkRecords, err = c.processCrosslinks(aState.PendingAttestations(), slot, block.SlotNumber())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +352,7 @@ func (c *CrystallizedState) NewStateRecalculations(aState *ActiveState, block *B
|
||||
newCrystallizedState := NewCrystallizedState(&pb.CrystallizedState{
|
||||
DynastySeed: c.data.DynastySeed,
|
||||
ShardAndCommitteesForSlots: ShardAndCommitteesForSlots,
|
||||
Validators: rewardedValidators,
|
||||
Validators: newValidators,
|
||||
LastStateRecalc: lastStateRecalc + params.GetConfig().CycleLength,
|
||||
LastJustifiedSlot: justifiedSlot,
|
||||
JustifiedStreak: justifiedStreak,
|
||||
|
||||
@@ -55,7 +55,7 @@ func TestInitialDeriveCrystallizedState(t *testing.T) {
|
||||
}},
|
||||
})
|
||||
|
||||
newCState, _, err := cState.NewStateRecalculations(aState, block)
|
||||
newCState, _, err := cState.NewStateRecalculations(aState, block, false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to derive new crystallized state: %v", err)
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func TestNextDeriveCrystallizedSlot(t *testing.T) {
|
||||
aState := NewGenesisActiveState()
|
||||
block := NewBlock(nil)
|
||||
|
||||
cState, _, err = cState.NewStateRecalculations(aState, block)
|
||||
cState, _, err = cState.NewStateRecalculations(aState, block, false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to derive next crystallized state: %v", err)
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func TestNextDeriveCrystallizedSlot(t *testing.T) {
|
||||
RecentBlockHashes: recentBlockHashes,
|
||||
}, voteCache)
|
||||
|
||||
cState, _, err = cState.NewStateRecalculations(aState, block)
|
||||
cState, _, err = cState.NewStateRecalculations(aState, block, false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to derive crystallized state: %v", err)
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func TestNextDeriveCrystallizedSlot(t *testing.T) {
|
||||
t.Fatalf("expected finalized slot to equal %d: got %d", 0, cState.LastFinalizedSlot())
|
||||
}
|
||||
|
||||
cState, _, err = cState.NewStateRecalculations(aState, block)
|
||||
cState, _, err = cState.NewStateRecalculations(aState, block, false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to derive crystallized state: %v", err)
|
||||
}
|
||||
@@ -147,6 +147,23 @@ func TestNextDeriveCrystallizedSlot(t *testing.T) {
|
||||
if cState.LastFinalizedSlot() != params.GetConfig().CycleLength-2 {
|
||||
t.Fatalf("expected finalized slot to equal %d: got %d", params.GetConfig().CycleLength-2, cState.LastFinalizedSlot())
|
||||
}
|
||||
|
||||
cState, _, err = cState.NewStateRecalculations(aState, block, true, true)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to derive crystallized state: %v", err)
|
||||
}
|
||||
if cState.LastStateRecalc() != 4*params.GetConfig().CycleLength {
|
||||
t.Fatalf("expected last state recalc to equal %d: got %d", 3*params.GetConfig().CycleLength, cState.LastStateRecalc())
|
||||
}
|
||||
if cState.LastJustifiedSlot() != 3*params.GetConfig().CycleLength-1 {
|
||||
t.Fatalf("expected justified slot to equal %d: got %d", 2*params.GetConfig().CycleLength-1, cState.LastJustifiedSlot())
|
||||
}
|
||||
if cState.JustifiedStreak() != 4*params.GetConfig().CycleLength {
|
||||
t.Fatalf("expected justified streak to equal %d: got %d", 2*params.GetConfig().CycleLength, cState.JustifiedStreak())
|
||||
}
|
||||
if cState.LastFinalizedSlot() != 2*params.GetConfig().CycleLength-2 {
|
||||
t.Fatalf("expected finalized slot to equal %d: got %d", params.GetConfig().CycleLength-2, cState.LastFinalizedSlot())
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessCrosslinks(t *testing.T) {
|
||||
|
||||
@@ -5,12 +5,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// DevFlag enables a local-development version of the beacon chain that stubs out
|
||||
// a web3 PoW chain and other items related to signature verification. This allows
|
||||
// a user to advance a beacon chain locally.
|
||||
DevFlag = cli.BoolFlag{
|
||||
Name: "dev",
|
||||
Usage: "Run the beacon chain in local development mode",
|
||||
// DemoConfigFlag determines whether to launch a beacon chain using demo parameters
|
||||
// such as shorter cycle length, fewer shards, and more.
|
||||
DemoConfigFlag = cli.BoolFlag{
|
||||
Name: "demo-config",
|
||||
Usage: " Run the beacon node using demo paramteres (i.e. shorter cycles, fewer shards and committees)",
|
||||
}
|
||||
// SimulatorFlag determines if a node will run only as a simulator service.
|
||||
SimulatorFlag = cli.BoolFlag{
|
||||
@@ -55,4 +54,29 @@ var (
|
||||
Name: "genesis-json",
|
||||
Usage: "Beacon node will bootstrap genesis state defined in genesis.json",
|
||||
}
|
||||
// EnablePOWChain tells the beacon node to use a real web3 endpoint. Disabled by default.
|
||||
EnablePOWChain = cli.BoolFlag{
|
||||
Name: "enable-powchain",
|
||||
Usage: "Enable a real, web3 proof-of-work chain endpoint in the beacon node",
|
||||
}
|
||||
// EnableCrossLinks tells the beacon node to enable the verification of shard cross-links
|
||||
// during block processing. Disabled by default.
|
||||
EnableCrossLinks = cli.BoolFlag{
|
||||
Name: "enable-cross-links",
|
||||
Usage: "Enable cross-link verification in the beacon chain",
|
||||
}
|
||||
// EnableRewardChecking tells the beacon node to apply Casper FFG rewards/penalties to validators
|
||||
// at each cycle transition. This can mutate the validator set as bad validators can get kicked off.
|
||||
// Disabled by default.
|
||||
EnableRewardChecking = cli.BoolFlag{
|
||||
Name: "enable-reward-checking",
|
||||
Usage: "Enable Casper FFG reward/penalty applications at each cycle transition",
|
||||
}
|
||||
// EnableAttestationValidity in the beacon node. This enables a few more verification
|
||||
// conditions during block processing and the creation of a block vote cache
|
||||
// for attestations. Disabled by default.
|
||||
EnableAttestationValidity = cli.BoolFlag{
|
||||
Name: "enable-attestations-validity",
|
||||
Usage: "Enable the verification of attestation validity in a beacon node",
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user