Skip to content

Commit

Permalink
Update Validity Conditions to Match Spec (#1611)
Browse files Browse the repository at this point in the history
* validity conditions to match master

* update tests across repo
  • Loading branch information
rauljordan authored Feb 15, 2019
1 parent c8a170d commit d174c4e
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 42 deletions.
5 changes: 2 additions & 3 deletions beacon-chain/blockchain/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package blockchain

import (
"context"
"errors"
"fmt"
"time"

Expand Down Expand Up @@ -265,8 +264,8 @@ func (c *ChainService) ReceiveBlock(block *pb.BeaconBlock, beaconState *pb.Beaco
return nil, fmt.Errorf("could not tree hash incoming block: %v", err)
}

if block.Slot == 0 {
return nil, errors.New("cannot process a genesis block: received block with slot 0")
if block.Slot == params.BeaconConfig().GenesisSlot {
return nil, fmt.Errorf("cannot process a genesis block: received block with slot %d", params.BeaconConfig().GenesisSlot)
}

// Save blocks with higher slot numbers in cache.
Expand Down
15 changes: 3 additions & 12 deletions beacon-chain/blockchain/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ func TestRunningChainServiceFaultyPOWChain(t *testing.T) {
chainService.cancel()
exitRoutine <- true

testutil.AssertLogsContain(t, hook, "unable to retrieve POW chain reference block failed")
testutil.AssertLogsContain(t, hook, "unable to retrieve POW chain reference block")
}

func setupGenesisState(t *testing.T, cs *ChainService, beaconState *pb.BeaconState) ([32]byte, *pb.BeaconState) {
Expand Down Expand Up @@ -666,15 +666,6 @@ func TestIsBlockReadyForProcessing(t *testing.T) {
t.Fatalf("unable to get root of canonical head: %v", err)
}

block2 := &pb.BeaconBlock{
ParentRootHash32: parentRoot[:],
Slot: 10,
}

if err := chainService.isBlockReadyForProcessing(block2, beaconState); err == nil {
t.Fatal("block processing succeeded despite block slot being invalid")
}

beaconState.LatestEth1Data = &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
Expand All @@ -684,7 +675,7 @@ func TestIsBlockReadyForProcessing(t *testing.T) {
currentSlot := uint64(1)
attestationSlot := uint64(0)

block3 := &pb.BeaconBlock{
block2 := &pb.BeaconBlock{
Slot: currentSlot,
StateRootHash32: stateRoot[:],
ParentRootHash32: parentRoot[:],
Expand All @@ -706,7 +697,7 @@ func TestIsBlockReadyForProcessing(t *testing.T) {

chainService.enablePOWChain = true

if err := chainService.isBlockReadyForProcessing(block3, beaconState); err != nil {
if err := chainService.isBlockReadyForProcessing(block2, beaconState); err != nil {
t.Fatalf("block processing failed despite being a valid block: %v", err)
}
}
8 changes: 0 additions & 8 deletions beacon-chain/core/blocks/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"bytes"
"encoding/binary"
"fmt"
"time"

"github.com/prysmaticlabs/prysm/beacon-chain/utils"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
Expand Down Expand Up @@ -41,13 +40,6 @@ func NewGenesisBlock(stateRoot []byte) *pb.BeaconBlock {
return block
}

// IsSlotValid compares the slot to the system clock to determine if the block is valid.
func IsSlotValid(slot uint64, genesisTime time.Time) bool {
slotDuration := time.Duration(slot*params.BeaconConfig().SlotDuration) * time.Second
validTimeThreshold := genesisTime.Add(slotDuration)
return clock.Now().After(validTimeThreshold)
}

// BlockRoot returns the block root stored in the BeaconState for a given slot.
// It returns an error if the requested block root is not within the BeaconState.
// Spec pseudocode definition:
Expand Down
27 changes: 14 additions & 13 deletions beacon-chain/core/blocks/validity_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"time"

"github.com/prysmaticlabs/prysm/shared/params"

"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
Expand Down Expand Up @@ -38,35 +40,34 @@ func IsValidBlock(
return fmt.Errorf("unprocessed parent block as it is not saved in the db: %#x", parentRoot)
}

// Pre-Processing Condition 2:
// The state is updated up to block.slot -1.

if state.Slot != block.Slot-1 {
return fmt.Errorf(
"block slot is not valid %d as it is supposed to be %d", block.Slot, state.Slot+1)
}

if enablePOWChain {
h := common.BytesToHash(state.LatestEth1Data.DepositRootHash32)
h := common.BytesToHash(state.LatestEth1Data.BlockHash32)
powBlock, err := GetPOWBlock(ctx, h)
if err != nil {
return fmt.Errorf("unable to retrieve POW chain reference block %v", err)
return fmt.Errorf("unable to retrieve POW chain reference block: %v", err)
}

// Pre-Processing Condition 3:
// Pre-Processing Condition 2:
// The block pointed to by the state in state.processed_pow_receipt_root has
// been processed in the ETH 1.0 chain.
if powBlock == nil {
return fmt.Errorf("proof-of-Work chain reference in state does not exist %#x", state.LatestEth1Data.DepositRootHash32)
return fmt.Errorf("proof-of-Work chain reference in state does not exist: %#x", state.LatestEth1Data.BlockHash32)
}
}

// Pre-Processing Condition 4:
// The node's local time is greater than or equal to
// state.genesis_time + block.slot * SLOT_DURATION.
// state.genesis_time + (block.slot-GENESIS_SLOT)* SLOT_DURATION.
if !IsSlotValid(block.Slot, genesisTime) {
return fmt.Errorf("slot of block is too high: %d", block.Slot)
}

return nil
}

// IsSlotValid compares the slot to the system clock to determine if the block is valid.
func IsSlotValid(slot uint64, genesisTime time.Time) bool {
slotDuration := time.Duration((slot-params.BeaconConfig().GenesisSlot)*params.BeaconConfig().SlotDuration) * time.Second
validTimeThreshold := genesisTime.Add(slotDuration)
return clock.Now().After(validTimeThreshold)
}
18 changes: 12 additions & 6 deletions beacon-chain/core/blocks/validity_conditions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"testing"
"time"

"github.com/prysmaticlabs/prysm/shared/params"

"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
Expand Down Expand Up @@ -42,10 +44,10 @@ func TestBadBlock(t *testing.T) {
db := &mockDB{}
powClient := &mockPOWClient{}

beaconState.Slot = 3
beaconState.Slot = params.BeaconConfig().GenesisSlot + 3

block := &pb.BeaconBlock{
Slot: 4,
Slot: params.BeaconConfig().GenesisSlot + 4,
}

genesisTime := time.Unix(0, 0)
Expand All @@ -57,15 +59,19 @@ func TestBadBlock(t *testing.T) {
t.Fatal("block is valid despite not having a parent")
}

block.Slot = 3
block.Slot = params.BeaconConfig().GenesisSlot + 3
db.hasBlock = true

beaconState.LatestEth1Data = &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
}
if err := IsValidBlock(ctx, beaconState, block, true,
db.HasBlock, powClient.BlockByHash, genesisTime); err == nil {
t.Fatalf("block is valid despite having an invalid slot %d", block.Slot)
}

block.Slot = 4
block.Slot = params.BeaconConfig().GenesisSlot + 4
powClient.blockExists = false
beaconState.LatestEth1Data = &pb.Eth1Data{
DepositRootHash32: []byte{2},
Expand Down Expand Up @@ -94,11 +100,11 @@ func TestValidBlock(t *testing.T) {
db := &mockDB{}
powClient := &mockPOWClient{}

beaconState.Slot = 3
beaconState.Slot = params.BeaconConfig().GenesisSlot + 3
db.hasBlock = true

block := &pb.BeaconBlock{
Slot: 4,
Slot: params.BeaconConfig().GenesisSlot + 4,
}

genesisTime := time.Unix(0, 0)
Expand Down

0 comments on commit d174c4e

Please sign in to comment.