diff --git a/beacon-chain/blockchain/service.go b/beacon-chain/blockchain/service.go index d5c6015c19..9457c4eff1 100644 --- a/beacon-chain/blockchain/service.go +++ b/beacon-chain/blockchain/service.go @@ -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 } diff --git a/beacon-chain/blockchain/service_test.go b/beacon-chain/blockchain/service_test.go index b4da12359d..9759a8e82f 100644 --- a/beacon-chain/blockchain/service_test.go +++ b/beacon-chain/blockchain/service_test.go @@ -315,6 +315,7 @@ func TestRunningChainServiceFaultyPOWChain(t *testing.T) { BeaconDB: db.DB(), Chain: beaconChain, Web3Service: web3Service, + EnablePOWChain: true, } chainService, _ := NewChainService(ctx, cfg) diff --git a/beacon-chain/main.go b/beacon-chain/main.go index 1bb295c24a..0fdd93dd03 100644 --- a/beacon-chain/main.go +++ b/beacon-chain/main.go @@ -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, diff --git a/beacon-chain/node/node.go b/beacon-chain/node/node.go index 34aa3b15b1..789f3fb14f 100644 --- a/beacon-chain/node/node.go +++ b/beacon-chain/node/node.go @@ -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) diff --git a/beacon-chain/node/node_test.go b/beacon-chain/node/node_test.go index 2334b951ef..000921a486 100644 --- a/beacon-chain/node/node_test.go +++ b/beacon-chain/node/node_test.go @@ -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) diff --git a/beacon-chain/rpc/service.go b/beacon-chain/rpc/service.go index aece89d339..a121ca308f 100644 --- a/beacon-chain/rpc/service.go +++ b/beacon-chain/rpc/service.go @@ -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() } diff --git a/beacon-chain/simulator/service.go b/beacon-chain/simulator/service.go index 9c7700c782..cbc4a6f484 100644 --- a/beacon-chain/simulator/service.go +++ b/beacon-chain/simulator/service.go @@ -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{ diff --git a/beacon-chain/simulator/service_test.go b/beacon-chain/simulator/service_test.go index cdd4c693c1..3b9baa3cb6 100644 --- a/beacon-chain/simulator/service_test.go +++ b/beacon-chain/simulator/service_test.go @@ -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 { diff --git a/beacon-chain/types/active_state.go b/beacon-chain/types/active_state.go index 983d54179e..30b439ccdc 100644 --- a/beacon-chain/types/active_state.go +++ b/beacon-chain/types/active_state.go @@ -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. diff --git a/beacon-chain/types/active_state_test.go b/beacon-chain/types/active_state_test.go index 67263f55e4..7d29f2f996 100644 --- a/beacon-chain/types/active_state_test.go +++ b/beacon-chain/types/active_state_test.go @@ -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) } diff --git a/beacon-chain/types/block.go b/beacon-chain/types/block.go index 3ed53878d0..f107fa9901 100644 --- a/beacon-chain/types/block.go +++ b/beacon-chain/types/block.go @@ -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 } diff --git a/beacon-chain/types/block_test.go b/beacon-chain/types/block_test.go index 28faa146f5..7efa265b87 100644 --- a/beacon-chain/types/block_test.go +++ b/beacon-chain/types/block_test.go @@ -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") } } diff --git a/beacon-chain/types/crystallized_state.go b/beacon-chain/types/crystallized_state.go index caaa124633..6559cde81e 100644 --- a/beacon-chain/types/crystallized_state.go +++ b/beacon-chain/types/crystallized_state.go @@ -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, diff --git a/beacon-chain/types/crystallized_state_test.go b/beacon-chain/types/crystallized_state_test.go index 0ee619d869..772ed9d0bb 100644 --- a/beacon-chain/types/crystallized_state_test.go +++ b/beacon-chain/types/crystallized_state_test.go @@ -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) { diff --git a/beacon-chain/utils/flags.go b/beacon-chain/utils/flags.go index 70935c6dd9..ab4acb46ed 100644 --- a/beacon-chain/utils/flags.go +++ b/beacon-chain/utils/flags.go @@ -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", + } )