Skip to content

Commit

Permalink
missing file
Browse files Browse the repository at this point in the history
  • Loading branch information
srene committed Oct 10, 2024
1 parent 94da675 commit 9c25e73
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 62 deletions.
17 changes: 10 additions & 7 deletions block/stateupdate_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@ func (v *StateUpdateValidator) ValidateStateUpdate(batch *settlement.ResultRetri
numBlocks := batch.EndHeight - batch.StartHeight + 1
if uint64(len(daBlocks)) != numBlocks {
daBlocks = []*types.Block{}
daBatch := v.blockManager.Retriever.RetrieveBatches(batch.MetaData.DA)
if daBatch.Code != da.StatusSuccess {
return daBatch.Error
var daBatch da.ResultRetrieveBatch
for {
daBatch = v.blockManager.Retriever.RetrieveBatches(batch.MetaData.DA)
if daBatch.Code == da.StatusSuccess {
break
}
}
for _, batch := range daBatch.Batches {
daBlocks = append(daBlocks, batch.Blocks...)
Expand Down Expand Up @@ -118,7 +121,7 @@ func (v *StateUpdateValidator) ValidateP2PBlocks(daBlocks []*types.Block, p2pBlo
return err
}
if !bytes.Equal(p2pBlockHash, daBlockHash) {
return fmt.Errorf("p2p block different from DA block. p2p height: %d, DA height: %d", p2pBlocks[i].Header.Height, daBlock.Header.Height)
return types.NewErrStateUpdateDoubleSigningFraud(daBlock.Header.Height)
}
i++
if i == len(p2pBlocks) {
Expand All @@ -140,16 +143,16 @@ func (v *StateUpdateValidator) ValidateDaBlocks(slBatch *settlement.ResultRetrie
for i, bd := range slBatch.BlockDescriptors {
// height check
if bd.Height != daBlocks[i].Header.Height {
return fmt.Errorf("height mismatch between state update and DA batch. State index: %d SL height: %d DA height: %d", slBatch.StateIndex, bd.Height, daBlocks[i].Header.Height)
return types.NewErrStateUpdateHeightNotMatchingFraud(slBatch.StateIndex, bd.Height, daBlocks[i].Header.Height)
}
// we compare the state root between SL state info and DA block
if !bytes.Equal(bd.StateRoot, daBlocks[i].Header.AppHash[:]) {
return fmt.Errorf("state root mismatch between state update and DA batch. State index: %d: Height: %d State root SL: %d State root DA: %d", slBatch.StateIndex, bd.Height, bd.StateRoot, daBlocks[i].Header.AppHash[:])
return types.NewErrStateUpdateStateRootNotMatchingFraud(slBatch.StateIndex, bd.Height, bd.StateRoot, daBlocks[i].Header.AppHash[:])
}

// we compare the timestamp between SL state info and DA block
if !bd.Timestamp.Equal(daBlocks[i].Header.GetTimestamp()) {
return fmt.Errorf("timestamp mismatch between state update and DA batch. State index: %d: Height: %d Timestamp SL: %s Timestamp DA: %s", slBatch.StateIndex, bd.Height, bd.Timestamp.UTC(), daBlocks[i].Header.GetTimestamp().UTC())
return types.NewErrStateUpdateTimestampNotMatchingFraud(slBatch.StateIndex, bd.Height, bd.Timestamp, daBlocks[i].Header.GetTimestamp())
}
}

Expand Down
118 changes: 64 additions & 54 deletions block/stateupdate_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package block_test

import (
"crypto/rand"
"fmt"
"errors"
"testing"
"time"

Expand Down Expand Up @@ -40,44 +40,46 @@ func TestStateUpdateValidator_ValidateP2PBlocks(t *testing.T) {
mixedBatch[2] = doubleSignedBatch.Blocks[2]

tests := []struct {
name string
daBlocks []*types.Block
p2pBlocks []*types.Block
wantErr bool
name string
daBlocks []*types.Block
p2pBlocks []*types.Block
expectedErrType interface{}
}{
{
name: "Empty blocks",
daBlocks: []*types.Block{},
p2pBlocks: []*types.Block{},
wantErr: false,
name: "Empty blocks",
daBlocks: []*types.Block{},
p2pBlocks: []*types.Block{},
expectedErrType: nil,
},
{
name: "Matching blocks",
daBlocks: batch.Blocks,
p2pBlocks: batch.Blocks,
wantErr: false,
name: "Matching blocks",
daBlocks: batch.Blocks,
p2pBlocks: batch.Blocks,
expectedErrType: nil,
},
{
name: "double signing",
daBlocks: batch.Blocks,
p2pBlocks: doubleSignedBatch.Blocks,
wantErr: true,
name: "double signing",
daBlocks: batch.Blocks,
p2pBlocks: doubleSignedBatch.Blocks,
expectedErrType: types.ErrStateUpdateDoubleSigningFraud{},
},
{
name: "mixed blocks",
daBlocks: batch.Blocks,
p2pBlocks: mixedBatch,
wantErr: true,
name: "mixed blocks",
daBlocks: batch.Blocks,
p2pBlocks: mixedBatch,
expectedErrType: types.ErrStateUpdateDoubleSigningFraud{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validator.ValidateP2PBlocks(tt.daBlocks, tt.p2pBlocks)
if tt.wantErr {
assert.Error(t, err)
} else {
// Check the result
if tt.expectedErrType == nil {
assert.NoError(t, err)
} else {
assert.True(t, errors.As(err, &tt.expectedErrType),
"expected error of type %T, got %T", tt.expectedErrType, err)
}
})
}
Expand All @@ -94,10 +96,10 @@ func TestStateUpdateValidator_ValidateDaBlocks(t *testing.T) {
require.NoError(t, err)

tests := []struct {
name string
slBatch *settlement.ResultRetrieveBatch
daBlocks []*types.Block
expectedError error
name string
slBatch *settlement.ResultRetrieveBatch
daBlocks []*types.Block
expectedErrType interface{}
}{
{
name: "Happy path - all validations pass",
Expand All @@ -112,8 +114,8 @@ func TestStateUpdateValidator_ValidateDaBlocks(t *testing.T) {
StateIndex: 1,
},
},
daBlocks: batch.Blocks,
expectedError: nil,
daBlocks: batch.Blocks,
expectedErrType: nil,
},
{
name: "Error - number of blocks mismatch",
Expand All @@ -128,8 +130,8 @@ func TestStateUpdateValidator_ValidateDaBlocks(t *testing.T) {
StateIndex: 1,
},
},
daBlocks: []*types.Block{batch.Blocks[0]},
expectedError: fmt.Errorf("num blocks mismatch between state update and DA batch. State index: 1 State update blocks: 2 DA batch blocks: 1"),
daBlocks: []*types.Block{batch.Blocks[0]},
expectedErrType: types.ErrStateUpdateHeightNotMatchingFraud{},
},
{
name: "Error - height mismatch",
Expand All @@ -144,8 +146,8 @@ func TestStateUpdateValidator_ValidateDaBlocks(t *testing.T) {
StateIndex: 1,
},
},
daBlocks: batch.Blocks,
expectedError: fmt.Errorf("height mismatch between state update and DA batch. State index: 1 SL height: 101 DA height: 1"),
daBlocks: batch.Blocks,
expectedErrType: types.ErrStateUpdateHeightNotMatchingFraud{},
},
{
name: "Error - state root mismatch",
Expand All @@ -160,8 +162,8 @@ func TestStateUpdateValidator_ValidateDaBlocks(t *testing.T) {
StateIndex: 1,
},
},
daBlocks: batch.Blocks,
expectedError: fmt.Errorf("state root mismatch between state update and DA batch. State index: 1: Height: 2 State root SL: %d State root DA: %d", []byte{1, 2, 3, 4}, batch.Blocks[0].Header.AppHash[:]),
daBlocks: batch.Blocks,
expectedErrType: types.ErrStateUpdateStateRootNotMatchingFraud{},
},
{
name: "Error - timestamp mismatch",
Expand All @@ -176,19 +178,22 @@ func TestStateUpdateValidator_ValidateDaBlocks(t *testing.T) {
StateIndex: 1,
},
},
daBlocks: batch.Blocks,
expectedError: fmt.Errorf("timestamp mismatch between state update and DA batch. State index: 1: Height: 2 Timestamp SL: %s Timestamp DA: %s",
batch.Blocks[1].Header.GetTimestamp().UTC().Add(1*time.Second), batch.Blocks[1].Header.GetTimestamp().UTC()),
daBlocks: batch.Blocks,
expectedErrType: types.ErrStateUpdateTimestampNotMatchingFraud{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

// validate DA blocks
err := validator.ValidateDaBlocks(tt.slBatch, tt.daBlocks)

if tt.expectedError != nil {
assert.EqualError(t, err, tt.expectedError.Error())
} else {
// Check the result
if tt.expectedErrType == nil {
assert.NoError(t, err)
} else {
assert.True(t, errors.As(err, &tt.expectedErrType),
"expected error of type %T, got %T", tt.expectedErrType, err)
}
})
}
Expand Down Expand Up @@ -228,49 +233,49 @@ func TestStateUpdateValidator_ValidateStateUpdate(t *testing.T) {
p2pBlocks bool
doubleSignedBlocks []*types.Block
stateUpdateFraud string
expectedError error
expectedErrType interface{}
}{
{
name: "Successful validation applied from DA",
p2pBlocks: false,
doubleSignedBlocks: nil,
stateUpdateFraud: "",
expectedError: nil,
expectedErrType: nil,
},
{
name: "Successful validation applied from P2P",
p2pBlocks: true,
doubleSignedBlocks: nil,
stateUpdateFraud: "",
expectedError: nil,
expectedErrType: nil,
},
{
name: "Failed validation blocks not matching",
p2pBlocks: true,
stateUpdateFraud: "",
doubleSignedBlocks: doubleSigned,
expectedError: fmt.Errorf("p2p block different from DA block. p2p height: 1, DA height: 1"),
expectedErrType: types.ErrStateUpdateDoubleSigningFraud{},
},
{
name: "Failed validation wrong state roots",
p2pBlocks: true,
stateUpdateFraud: "stateroot",
doubleSignedBlocks: doubleSigned,
expectedError: fmt.Errorf("state root mismatch between state update and DA batch. State index: 1: Height: 1 State root SL: [] State root DA: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]"),
expectedErrType: types.ErrStateUpdateStateRootNotMatchingFraud{},
},
{
name: "Failed validation wrong timestamps",
p2pBlocks: true,
stateUpdateFraud: "timestamp",
doubleSignedBlocks: doubleSigned,
expectedError: fmt.Errorf("timestamp mismatch between state update and DA batch. State index: 1: Height: 1 Timestamp SL: 1970-01-01 00:00:01.000004567 +0000 UTC Timestamp DA: 1970-01-01 00:00:00.000004567 +0000 UTC"),
expectedErrType: types.ErrStateUpdateTimestampNotMatchingFraud{},
},
{
name: "Failed validation wrong height",
p2pBlocks: true,
stateUpdateFraud: "height",
doubleSignedBlocks: doubleSigned,
expectedError: fmt.Errorf("height mismatch between state update and DA batch. State index: 1 SL height: 2 DA height: 1"),
expectedErrType: types.ErrStateUpdateHeightNotMatchingFraud{},
},
}
for _, tc := range testCases {
Expand Down Expand Up @@ -318,6 +323,11 @@ func TestStateUpdateValidator_ValidateStateUpdate(t *testing.T) {
StateIndex: 1,
},
}

// Create the StateUpdateValidator
validator := block.NewStateUpdateValidator(testutil.NewLogger(t), manager)

// set fraud data
switch tc.stateUpdateFraud {
case "stateroot":
slBatch.BlockDescriptors[0].StateRoot = []byte{}
Expand All @@ -326,8 +336,6 @@ func TestStateUpdateValidator_ValidateStateUpdate(t *testing.T) {
case "height":
slBatch.BlockDescriptors[0].Height = 2
}
// Create the StateUpdateValidator
validator := block.NewStateUpdateValidator(testutil.NewLogger(t), manager)

if tc.doubleSignedBlocks != nil {
batch.Blocks = tc.doubleSignedBlocks
Expand All @@ -344,14 +352,16 @@ func TestStateUpdateValidator_ValidateStateUpdate(t *testing.T) {
} else {
manager.ProcessNextDABatch(slBatch.MetaData.DA)
}
// Call the function

// validate the state update
err = validator.ValidateStateUpdate(slBatch)

// Check the result
if tc.expectedError == nil {
if tc.expectedErrType == nil {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, tc.expectedError.Error())
assert.True(t, errors.As(err, &tc.expectedErrType),
"expected error of type %T, got %T", tc.expectedErrType, err)
}

})
Expand Down
2 changes: 1 addition & 1 deletion block/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (m *Manager) ValidateLoop(ctx context.Context) error {
batch, err := m.SLClient.GetBatchAtHeight(currH)
if err != nil {
m.logger.Error("failed batch retrieval", "error", err)
break
continue
}
// validate batch
err = m.validator.ValidateStateUpdate(batch)
Expand Down
Loading

0 comments on commit 9c25e73

Please sign in to comment.