Skip to content

Commit 6d9cbcc

Browse files
authored
Update conformance to v1 without Ancestry (#423)
1 parent 2038789 commit 6d9cbcc

File tree

6 files changed

+97
-17
lines changed

6 files changed

+97
-17
lines changed

internal/statetransition/state_transition.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ func UpdateState(s *state.State, newBlock block.Block, chain *store.Chain, trie
5454
return err
5555
}
5656

57-
if err := ValidatePreimages(newBlock.Extrinsic.EP, s.Services); err != nil {
58-
return err
59-
}
60-
6157
// TODO: verify header offenders marker.
6258

6359
// Update SAFROLE state.
@@ -80,6 +76,10 @@ func UpdateState(s *state.State, newBlock block.Block, chain *store.Chain, trie
8076
return fmt.Errorf("failed to verify block header: %w", err)
8177
}
8278

79+
if err := ValidatePreimages(newBlock.Extrinsic.EP, s.Services); err != nil {
80+
return err
81+
}
82+
8383
// ρ‡ ≺ (EA, ρ†) (eq. 4.13 v0.7.0) and R* ≺ (EA, ρ†) (eq 4.15 v0.7.0)
8484
intermediateCoreAssignments, availableWorkReports, err := assuring.CalculateIntermediateCoreAssignmentsAndAvailableWorkReports(newBlock.Extrinsic.EA, s.ValidatorState.CurrentValidators, intermediateCoreAssignments, newBlock.Header)
8585
if err != nil {
@@ -184,9 +184,6 @@ func isPreimagesSortedUnique(preimages block.PreimageExtrinsic) bool {
184184
// ValidatePreimages implements equations 12.39 and 12.40 v0.7.0
185185
// checks that the preimages are ordered, unique and solicited by a service
186186
func ValidatePreimages(preimages block.PreimageExtrinsic, serviceState service.ServiceState) error {
187-
if !isPreimagesSortedUnique(preimages) {
188-
return errors.New("preimages not sorted unique")
189-
}
190187

191188
for _, preimage := range preimages {
192189
serviceId := block.ServiceId(preimage.ServiceIndex)
@@ -198,6 +195,9 @@ func ValidatePreimages(preimages block.PreimageExtrinsic, serviceState service.S
198195
return errors.New("preimage unneeded")
199196
}
200197
}
198+
if !isPreimagesSortedUnique(preimages) {
199+
return errors.New("preimages not sorted unique")
200+
}
201201

202202
return nil
203203
}

pkg/conformance/cmd/main.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"log"
6+
7+
"github.com/eigerco/strawberry/internal/store"
8+
"github.com/eigerco/strawberry/pkg/conformance"
9+
"github.com/eigerco/strawberry/pkg/db/pebble"
10+
)
11+
12+
func main() {
13+
socketPath := flag.String("socket", "/tmp/jam_target.sock", "Path to the socket for the fuzzer to connect to")
14+
flag.Parse()
15+
16+
// Ensure no extra positional arguments
17+
if flag.NArg() > 0 {
18+
log.Fatalf("unexpected arguments: %v", flag.Args())
19+
}
20+
21+
db, err := pebble.NewKVStore()
22+
if err != nil {
23+
log.Fatalf("failed to create kv store: %v", err)
24+
}
25+
26+
defer func() {
27+
if err := db.Close(); err != nil {
28+
log.Printf("error closing database: %v", err)
29+
}
30+
}()
31+
32+
chain := store.NewChain(db)
33+
trieStore := store.NewTrie(chain)
34+
35+
appName := []byte("strawberry")
36+
appVersion := conformance.Version{Major: 0, Minor: 0, Patch: 1}
37+
jamVersion := conformance.Version{Major: 0, Minor: 7, Patch: 0}
38+
features := conformance.FeatureFork
39+
node := conformance.NewNode(*socketPath, chain, trieStore, appName, appVersion, jamVersion, features)
40+
if err := node.Start(); err != nil {
41+
log.Fatalf("Failed to start Node: %v", err)
42+
}
43+
}

pkg/conformance/messages.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (v Version) String() string {
3636

3737
type PeerInfo struct {
3838
FuzzVersion uint8
39-
FuzzFeatures uint32
39+
FuzzFeatures Features
4040
JamVersion Version
4141
AppVersion Version
4242
Name []byte

pkg/conformance/node.go

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ import (
2323
"github.com/eigerco/strawberry/internal/store"
2424
)
2525

26+
type Features uint32
27+
28+
const (
29+
FeatureNone Features = 0
30+
FeatureAncestry Features = 1
31+
FeatureFork Features = 2
32+
FeatureAncestryAndFork Features = 3
33+
FeatureReserved Features = 2147483648
34+
)
35+
2636
// Node is a conformance testing node complying with fuzzer protocol https://github.com/davxy/jam-stuff/tree/main/fuzz-proto
2737
// opens a connection via a unix socket and listens to fuzzer messages and updates the state accordingly
2838
type Node struct {
@@ -38,11 +48,13 @@ type Node struct {
3848
}
3949

4050
// NewNode create a new conformance testing node
41-
func NewNode(socketPath string, chain *store.Chain, trie *store.Trie, appName []byte, appVersion, jamVersion Version) *Node {
51+
func NewNode(socketPath string, chain *store.Chain, trie *store.Trie, appName []byte, appVersion, jamVersion Version, features Features) *Node {
4252
peerInfo := PeerInfo{
43-
Name: appName,
44-
AppVersion: appVersion,
45-
JamVersion: jamVersion,
53+
FuzzVersion: 1,
54+
FuzzFeatures: features,
55+
JamVersion: jamVersion,
56+
AppVersion: appVersion,
57+
Name: appName,
4658
}
4759
return &Node{
4860
socketPath: socketPath,
@@ -56,8 +68,11 @@ func NewNode(socketPath string, chain *store.Chain, trie *store.Trie, appName []
5668

5769
// Start starts the node server
5870
func (n *Node) Start() error {
71+
// If the socket file exists, try to remove it.
5972
if _, err := os.Stat(n.socketPath); err == nil {
60-
os.Remove(n.socketPath)
73+
if err := os.Remove(n.socketPath); err != nil {
74+
return fmt.Errorf("failed to remove existing socket file: %v", err)
75+
}
6176
}
6277

6378
// Listen on the Unix socket
@@ -83,7 +98,11 @@ func (n *Node) Stop() error {
8398
}
8499

85100
func (n *Node) handleConnection(conn net.Conn) {
86-
defer conn.Close()
101+
defer func() {
102+
if err := conn.Close(); err != nil {
103+
log.Printf("error closing connection: %v", err)
104+
}
105+
}()
87106
for {
88107
ctx := context.Background()
89108

@@ -116,8 +135,17 @@ func (n *Node) handleConnection(conn net.Conn) {
116135
responseMsg = NewMessage(Error{Message: []byte("Chain error: block header verification failure: BadSealSignature")})
117136
} else if strings.Contains(err.Error(), "unexpected author") {
118137
responseMsg = NewMessage(Error{Message: []byte("Chain error: block header verification failure: UnexpectedAuthor")})
138+
// responseMsg = NewMessage(Error{Message: []byte("Chain error: block verification failure: unexpected author")}) //fauty vectors have the error in different format
119139
} else if strings.Contains(err.Error(), "epoch marker") {
120140
responseMsg = NewMessage(Error{Message: []byte("Chain error: block header verification failure: InvalidEpochMark")})
141+
// responseMsg = NewMessage(Error{Message: []byte("Chain error: block header verification failure: InvalidEpochMark")}) //fauty vectors have the error in different format
142+
} else if strings.Contains(err.Error(), "winning ticket marker") {
143+
responseMsg = NewMessage(Error{Message: []byte("Chain error: block header verification failure: InvalidTicketsMark")})
144+
// responseMsg = NewMessage(Error{Message: []byte("Chain error: block verification failure: invalid tickets mark")}) //fauty vectors have the error in different format
145+
} else if strings.Contains(err.Error(), "core unauthorized") {
146+
responseMsg = NewMessage(Error{Message: []byte("Chain error: block execution failure: reports error: code unauthorized")})
147+
} else if strings.Contains(err.Error(), "future report slot") {
148+
responseMsg = NewMessage(Error{Message: []byte("Chain error: block execution failure: reports error: report refers to slot in the future")})
121149
} else {
122150
return
123151
}

pkg/conformance/node_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ func TestMessage(t *testing.T) {
4646
appName := []byte("app name")
4747
appVersion := Version{1, 2, 3}
4848
jamVersion := Version{4, 5, 6}
49+
features := FeatureFork
4950

5051
go func() {
51-
n := NewNode(socketPath, chain, trieStore, appName, appVersion, jamVersion)
52+
n := NewNode(socketPath, chain, trieStore, appName, appVersion, jamVersion, features)
5253
if err := n.Start(); err != nil {
5354
t.Logf("failed to start Node: %v", err)
5455
}

pkg/conformance/traces_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func (StateRootChoice) isFuzzerType() {}
6060
func (ImportBlockChoice) isFuzzerType() {}
6161
func (GetStateChoice) isFuzzerType() {}
6262

63-
var tracesDir = "traces/no_forks"
63+
var tracesDir = "traces/forks"
6464

6565
func getFuzzerFileNames(t *testing.T) []string {
6666
files, err := filepath.Glob(tracesDir + "/*fuzzer*.bin")
@@ -142,7 +142,8 @@ func createTargetNode(t *testing.T) (*Node, func()) {
142142
appName := []byte("polkajam")
143143
appVersion := Version{Major: 0, Minor: 1, Patch: 25}
144144
jamVersion := Version{Major: 0, Minor: 7, Patch: 0}
145-
node := NewNode(socketPath, chain, trieStore, appName, appVersion, jamVersion)
145+
features := FeatureFork
146+
node := NewNode(socketPath, chain, trieStore, appName, appVersion, jamVersion, features)
146147
cleanup := func() {
147148
db.Close()
148149
os.Remove(socketPath)
@@ -193,6 +194,13 @@ func TestNoForksTraces(t *testing.T) {
193194
respMsg := &Message{}
194195
err = jam.Unmarshal(response.Content, respMsg)
195196
require.NoError(t, err)
197+
// If running the faulty folder traces/faulty
198+
// 29 is expected to return wrong state root in order to trigger the fuzzer to request `GetState`
199+
// 30 is supposed to return wrong state as we have different state compared expected due to 20
200+
// `In this scenario, the target responds with its current state, which is expected not to match a correctly computed state.`
201+
// if i != 29 && i != 30 {
202+
// require.Equal(t, respMsg.Get(), expected)
203+
// }
196204
require.Equal(t, respMsg.Get(), expected)
197205
})
198206
}

0 commit comments

Comments
 (0)