Skip to content

Commit

Permalink
Add created/updated test vectors and fix implementation. Fix all plac…
Browse files Browse the repository at this point in the history
…es where we use $ like , as it looks like $ shouldn't be used
  • Loading branch information
carlos-romano committed Jan 15, 2025
1 parent efb28fe commit b1192d8
Show file tree
Hide file tree
Showing 53 changed files with 1,487 additions and 924 deletions.
14 changes: 13 additions & 1 deletion internal/block/guarantee.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package block

import (
"fmt"

"github.com/eigerco/strawberry/internal/common"
"github.com/eigerco/strawberry/internal/crypto"
"github.com/eigerco/strawberry/internal/jamtime"
"github.com/eigerco/strawberry/pkg/serialization/codec/jam"
Expand Down Expand Up @@ -167,3 +167,15 @@ func (w *WorkReport) Hash() (crypto.Hash, error) {
}
return crypto.HashData(jsonData), nil
}

func (w *WorkReport) OutputSizeIsValid() bool {
totalOutputSize := 0
for _, result := range w.WorkResults {
if result.IsSuccessful() {
totalOutputSize += len(result.Output.Inner.([]byte))
}
}
totalOutputSize += len(w.Output)

return totalOutputSize <= common.MaxWorkPackageSizeBytes
}
7 changes: 5 additions & 2 deletions internal/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const (
SizeOfSegment = 4104 // WG = WP*WE = 4104: The size of a segment in octets.
MaxWorkPackageSize = 12 * 1 << 20 // WB = 12 MB: The maximum size of an encoded work-package in octets (including extrinsic data and import implications).
ErasureCodingChunkSize = 684 // WE = 684: The basic size of erasure-coded pieces in octets.
MaxAllocatedGasAccumulation = 100_000 // GA = 100,000: The gas allocated to invoke a work-report’s Accumulation logic.
MaxAllocatedGasIsAuthorized = 1_000_000 // GI = 1,000,000: The gas allocated to invoke a work-package’s Is-Authorized logic.
MaxAllocatedGasAccumulation = 10_00_000 // GA: The gas allocated to invoke a work-report’s Accumulation logic.
MaxAllocatedGasIsAuthorized = 50_000_000 // GI: The gas allocated to invoke a work-package’s Is-Authorized logic.
WorkReportMaxSumOfDependencies = 8 // (J) The maximum sum of dependency items in a work-report.
MinWorkPackageResultsSize = 1 // () The minimum amount of work items in a package.
MaxWorkPackageResultsSize = 4 // (I) The maximum amount of work items in a package.
MaxWorkPackageSizeBytes = 48 * 1024 // (WR) Maximum size of a serialized work-package in bytes
)
4 changes: 2 additions & 2 deletions internal/common/constants_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const (
SizeOfSegment = 4104
MaxWorkPackageSize = 12 * 1 << 20
ErasureCodingChunkSize = 684
MaxAllocatedGasAccumulation = 100_000
MaxAllocatedGasIsAuthorized = 1_000_000
MaxAllocatedGasAccumulation = 10_000_000
WorkReportMaxSumOfDependencies = 8
MaxWorkPackageSizeBytes = 48 * 1024
)
4 changes: 2 additions & 2 deletions internal/merkle/binary_tree/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func ComputeNode(blobs [][]byte, hashFunc func([]byte) crypto.Hash) []byte {
left := ComputeNode(blobs[:mid], hashFunc)
right := ComputeNode(blobs[mid:], hashFunc)

// Concatenate "$node", left, and right
combined := append([]byte("$node"), append(left, right...)...)
// Concatenate "node", left, and right
combined := append([]byte("node"), append(left, right...)...)

return convertHashToBlob(hashFunc(combined))
}
22 changes: 11 additions & 11 deletions internal/merkle/binary_tree/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestComputeNode(t *testing.T) {
expected: func() []byte {
hash1 := convertHashToBlob(testutils.MockHashData([]byte("blob1")))
hash2 := convertHashToBlob(testutils.MockHashData([]byte("blob2")))
combined := append([]byte("$node"), append(hash1, hash2...)...)
combined := append([]byte("node"), append(hash1, hash2...)...)
return convertHashToBlob(testutils.MockHashData(combined))
}(),
},
Expand All @@ -64,14 +64,14 @@ func TestComputeNode(t *testing.T) {
// Right side (blob2 and blob3)
hash2 := convertHashToBlob(testutils.MockHashData([]byte("blob2")))
hash3 := convertHashToBlob(testutils.MockHashData([]byte("blob3")))
rightNode := append([]byte("$node"), append(hash2, hash3...)...)
rightNode := append([]byte("node"), append(hash2, hash3...)...)
rightHash := convertHashToBlob(testutils.MockHashData(rightNode))

// Left side (blob1)
leftHash := convertHashToBlob(testutils.MockHashData([]byte("blob1")))

// Combine
combined := append([]byte("$node"), append(leftHash, rightHash...)...)
combined := append([]byte("node"), append(leftHash, rightHash...)...)
return convertHashToBlob(testutils.MockHashData(combined))
}(),
},
Expand All @@ -87,16 +87,16 @@ func TestComputeNode(t *testing.T) {
// Left subtree
hash1 := convertHashToBlob(testutils.MockHashData([]byte("blob1")))
hash2 := convertHashToBlob(testutils.MockHashData([]byte("blob2")))
leftNode := append([]byte("$node"), append(hash1, hash2...)...)
leftNode := append([]byte("node"), append(hash1, hash2...)...)
leftHash := convertHashToBlob(testutils.MockHashData(leftNode))

// Right subtree
hash3 := convertHashToBlob(testutils.MockHashData([]byte("blob3")))
hash4 := convertHashToBlob(testutils.MockHashData([]byte("blob4")))
rightNode := append([]byte("$node"), append(hash3, hash4...)...)
rightNode := append([]byte("node"), append(hash3, hash4...)...)
rightHash := convertHashToBlob(testutils.MockHashData(rightNode))

combined := append([]byte("$node"), append(leftHash, rightHash...)...)
combined := append([]byte("node"), append(leftHash, rightHash...)...)
return convertHashToBlob(testutils.MockHashData(combined))
}(),
},
Expand All @@ -109,10 +109,10 @@ func TestComputeNode(t *testing.T) {
},
expected: func() []byte {
emptyHash := convertHashToBlob(testutils.MockHashData([]byte{}))
rightNode := append([]byte("$node"), append(emptyHash, emptyHash...)...)
rightNode := append([]byte("node"), append(emptyHash, emptyHash...)...)
rightHash := convertHashToBlob(testutils.MockHashData(rightNode))
leftHash := convertHashToBlob(testutils.MockHashData([]byte{}))
combined := append([]byte("$node"), append(leftHash, rightHash...)...)
combined := append([]byte("node"), append(leftHash, rightHash...)...)
return convertHashToBlob(testutils.MockHashData(combined))
}(),
},
Expand All @@ -125,7 +125,7 @@ func TestComputeNode(t *testing.T) {
expected: func() []byte {
hash1 := convertHashToBlob(testutils.MockHashData(createBlob(1024)))
hash2 := convertHashToBlob(testutils.MockHashData(createBlob(2048)))
combined := append([]byte("$node"), append(hash1, hash2...)...)
combined := append([]byte("node"), append(hash1, hash2...)...)
return convertHashToBlob(testutils.MockHashData(combined))
}(),
},
Expand All @@ -140,13 +140,13 @@ func TestComputeNode(t *testing.T) {
// Right side (large blob and empty blob)
hash2 := convertHashToBlob(testutils.MockHashData(createBlob(1024)))
hash3 := convertHashToBlob(testutils.MockHashData([]byte("")))
rightNode := append([]byte("$node"), append(hash2, hash3...)...)
rightNode := append([]byte("node"), append(hash2, hash3...)...)
rightHash := convertHashToBlob(testutils.MockHashData(rightNode))

// Left side (small blob)
leftHash := convertHashToBlob(testutils.MockHashData([]byte("small")))

combined := append([]byte("$node"), append(leftHash, rightHash...)...)
combined := append([]byte("node"), append(leftHash, rightHash...)...)
return convertHashToBlob(testutils.MockHashData(combined))
}(),
},
Expand Down
4 changes: 2 additions & 2 deletions internal/merkle/binary_tree/trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ func TestComputeTraceProperties(t *testing.T) {
for i := len(trace) - 1; i >= 0; i-- {
var combined []byte
if idx%2 == 0 {
combined = append([]byte("$node"), append(current, trace[i]...)...)
combined = append([]byte("node"), append(current, trace[i]...)...)
} else {
combined = append([]byte("$node"), append(trace[i], current...)...)
combined = append([]byte("node"), append(trace[i], current...)...)
}
current = convertHashToBlob(testutils.MockHashData(combined))
idx /= 2
Expand Down
6 changes: 3 additions & 3 deletions internal/merkle/binary_tree/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ func GetLeafPage(blobs [][]byte, pageIndex, x int, hashFunc func([]byte) crypto.
pageStart := (1 << x) * pageIndex // 2^x * i
pageEnd := min(pageStart+1<<x, len(blobs)) // min(2^x * i + 2^x, |v|)

// Select and hash leaves from the range with "$leaf" prefix
// Select and hash leaves from the range with "leaf" prefix
leaveHashes := make([]crypto.Hash, 0, pageEnd-pageStart)
for j := pageStart; j < pageEnd; j++ {
prefixedLeaf := append([]byte("$leaf"), blobs[j]...)
prefixedLeaf := append([]byte("leaf"), blobs[j]...)
leaveHashes = append(leaveHashes, hashFunc(prefixedLeaf))
}

Expand All @@ -88,7 +88,7 @@ func preprocessForConstantDepth(blobs [][]byte, hashFunc func([]byte) crypto.Has

// Process each input: H($leaf ~ vi) for i < |v|
for i := 0; i < len(blobs); i++ {
combined := append([]byte("$leaf"), blobs[i]...)
combined := append([]byte("leaf"), blobs[i]...)
result[i] = convertHashToBlob(hashFunc(combined))
} // positions ≥ len(blobs) are already zero hashes, so no action needed

Expand Down
72 changes: 36 additions & 36 deletions internal/merkle/binary_tree/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestComputeWellBalancedRoot(t *testing.T) {
expected: func() crypto.Hash {
left := testutils.MockHashData([]byte("blob1"))
right := testutils.MockHashData([]byte("blob2"))
combined := append([]byte("$node"), append(convertHashToBlob(left), convertHashToBlob(right)...)...)
combined := append([]byte("node"), append(convertHashToBlob(left), convertHashToBlob(right)...)...)
return testutils.MockHashData(combined)
}(),
},
Expand All @@ -46,8 +46,8 @@ func TestComputeWellBalancedRoot(t *testing.T) {
[]byte("blob3"),
},
expected: func() crypto.Hash {
// Should expect just one $node prefix
return testutils.MockHashData(append([]byte("$node"), []byte("blob1")...))
// Should expect just one node prefix
return testutils.MockHashData(append([]byte("node"), []byte("blob1")...))
}(),
},
}
Expand Down Expand Up @@ -75,7 +75,7 @@ func TestComputeConstantDepthRoot(t *testing.T) {
name: "single_blob",
blobs: [][]byte{[]byte("blob1")},
expected: func() crypto.Hash {
leafHash := testutils.MockHashData(append([]byte("$leaf"), []byte("blob1")...))
leafHash := testutils.MockHashData(append([]byte("leaf"), []byte("blob1")...))
return leafHash
}(),
},
Expand All @@ -86,9 +86,9 @@ func TestComputeConstantDepthRoot(t *testing.T) {
[]byte("blob2"),
},
expected: func() crypto.Hash {
h1 := testutils.MockHashData(append([]byte("$leaf"), []byte("blob1")...))
h2 := testutils.MockHashData(append([]byte("$leaf"), []byte("blob2")...))
combined := append([]byte("$node"), append(convertHashToBlob(h1), convertHashToBlob(h2)...)...)
h1 := testutils.MockHashData(append([]byte("leaf"), []byte("blob1")...))
h2 := testutils.MockHashData(append([]byte("leaf"), []byte("blob2")...))
combined := append([]byte("node"), append(convertHashToBlob(h1), convertHashToBlob(h2)...)...)
return testutils.MockHashData(combined)
}(),
},
Expand All @@ -100,13 +100,13 @@ func TestComputeConstantDepthRoot(t *testing.T) {
[]byte("blob3"),
},
expected: func() crypto.Hash {
h1 := testutils.MockHashData(append([]byte("$leaf"), []byte("blob1")...))
h2 := testutils.MockHashData(append([]byte("$leaf"), []byte("blob2")...))
h12 := testutils.MockHashData(append([]byte("$node"), append(convertHashToBlob(h1), convertHashToBlob(h2)...)...))
h3 := testutils.MockHashData(append([]byte("$leaf"), []byte("blob3")...))
h1 := testutils.MockHashData(append([]byte("leaf"), []byte("blob1")...))
h2 := testutils.MockHashData(append([]byte("leaf"), []byte("blob2")...))
h12 := testutils.MockHashData(append([]byte("node"), append(convertHashToBlob(h1), convertHashToBlob(h2)...)...))
h3 := testutils.MockHashData(append([]byte("leaf"), []byte("blob3")...))
h4 := crypto.Hash{} // Zero hash for padding
h34 := testutils.MockHashData(append([]byte("$node"), append(convertHashToBlob(h3), convertHashToBlob(h4)...)...))
combined := append([]byte("$node"), append(convertHashToBlob(h12), convertHashToBlob(h34)...)...)
h34 := testutils.MockHashData(append([]byte("node"), append(convertHashToBlob(h3), convertHashToBlob(h4)...)...))
combined := append([]byte("node"), append(convertHashToBlob(h12), convertHashToBlob(h34)...)...)
return testutils.MockHashData(combined)
}(),
},
Expand Down Expand Up @@ -148,7 +148,7 @@ func TestGetLeafPage(t *testing.T) {
i: 0,
x: 0,
expected: []crypto.Hash{
testutils.MockHashData(append([]byte("$leaf"), []byte("1")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("1")...)),
},
},
{
Expand All @@ -159,8 +159,8 @@ func TestGetLeafPage(t *testing.T) {
i: 0,
x: 1,
expected: []crypto.Hash{
testutils.MockHashData(append([]byte("$leaf"), []byte("1")...)),
testutils.MockHashData(append([]byte("$leaf"), []byte("2")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("1")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("2")...)),
},
},
{
Expand All @@ -171,8 +171,8 @@ func TestGetLeafPage(t *testing.T) {
i: 1,
x: 1,
expected: []crypto.Hash{
testutils.MockHashData(append([]byte("$leaf"), []byte("3")...)),
testutils.MockHashData(append([]byte("$leaf"), []byte("4")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("3")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("4")...)),
},
},
{
Expand All @@ -183,7 +183,7 @@ func TestGetLeafPage(t *testing.T) {
i: 2,
x: 1,
expected: []crypto.Hash{
testutils.MockHashData(append([]byte("$leaf"), []byte("5")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("5")...)),
},
},
{
Expand All @@ -195,10 +195,10 @@ func TestGetLeafPage(t *testing.T) {
i: 0,
x: 2,
expected: []crypto.Hash{
testutils.MockHashData(append([]byte("$leaf"), []byte("1")...)),
testutils.MockHashData(append([]byte("$leaf"), []byte("2")...)),
testutils.MockHashData(append([]byte("$leaf"), []byte("3")...)),
testutils.MockHashData(append([]byte("$leaf"), []byte("4")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("1")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("2")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("3")...)),
testutils.MockHashData(append([]byte("leaf"), []byte("4")...)),
},
},
}
Expand Down Expand Up @@ -241,10 +241,10 @@ func TestGeneratePageProof(t *testing.T) {
i: 0,
x: 1,
expected: func() []crypto.Hash {
h34 := testutils.MockHashData(append([]byte("$node"),
h34 := testutils.MockHashData(append([]byte("node"),
append(
convertHashToBlob(testutils.MockHashData(append([]byte("$leaf"), []byte("3")...))),
convertHashToBlob(testutils.MockHashData(append([]byte("$leaf"), []byte("4")...)))...,
convertHashToBlob(testutils.MockHashData(append([]byte("leaf"), []byte("3")...))),
convertHashToBlob(testutils.MockHashData(append([]byte("leaf"), []byte("4")...)))...,
)...,
))
return []crypto.Hash{h34}
Expand All @@ -259,18 +259,18 @@ func TestGeneratePageProof(t *testing.T) {
i: 0,
x: 2,
expected: func() []crypto.Hash {
h5678 := testutils.MockHashData(append([]byte("$node"),
h5678 := testutils.MockHashData(append([]byte("node"),
append(
convertHashToBlob(testutils.MockHashData(append([]byte("$node"),
convertHashToBlob(testutils.MockHashData(append([]byte("node"),
append(
convertHashToBlob(testutils.MockHashData(append([]byte("$leaf"), []byte("5")...))),
convertHashToBlob(testutils.MockHashData(append([]byte("$leaf"), []byte("6")...)))...,
convertHashToBlob(testutils.MockHashData(append([]byte("leaf"), []byte("5")...))),
convertHashToBlob(testutils.MockHashData(append([]byte("leaf"), []byte("6")...)))...,
)...,
))),
convertHashToBlob(testutils.MockHashData(append([]byte("$node"),
convertHashToBlob(testutils.MockHashData(append([]byte("node"),
append(
convertHashToBlob(testutils.MockHashData(append([]byte("$leaf"), []byte("7")...))),
convertHashToBlob(testutils.MockHashData(append([]byte("$leaf"), []byte("8")...)))...,
convertHashToBlob(testutils.MockHashData(append([]byte("leaf"), []byte("7")...))),
convertHashToBlob(testutils.MockHashData(append([]byte("leaf"), []byte("8")...)))...,
)...,
)))...,
)...,
Expand Down Expand Up @@ -329,7 +329,7 @@ func TestPageProofReconstruction(t *testing.T) {
nextLevel := make([]crypto.Hash, (len(level)+1)/2)
for i := 0; i < len(level); i += 2 {
if i+1 < len(level) {
nodeInput := append([]byte("$node"),
nodeInput := append([]byte("node"),
append(convertHashToBlob(level[i]),
convertHashToBlob(level[i+1])...)...)
nextLevel[i/2] = testutils.MockHashData(nodeInput)
Expand All @@ -350,9 +350,9 @@ func TestPageProofReconstruction(t *testing.T) {
for i := len(proof) - 1; i >= 0; i-- {
var combined []byte
if idx%2 == 0 {
combined = append([]byte("$node"), append(current, convertHashToBlob(proof[i])...)...)
combined = append([]byte("node"), append(current, convertHashToBlob(proof[i])...)...)
} else {
combined = append([]byte("$node"), append(convertHashToBlob(proof[i]), current...)...)
combined = append([]byte("node"), append(convertHashToBlob(proof[i]), current...)...)
}
current = convertHashToBlob(testutils.MockHashData(combined))
idx /= 2
Expand Down
7 changes: 4 additions & 3 deletions internal/merkle/mountain_ranges/mmr.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (m *MMR) Encode(peaks []*crypto.Hash) ([]byte, error) {
return encoded, nil
}

// SuperPeak implements M_R function from equation (E.10) Graypaper 0.5.4
// SuperPeak implements M_R function from equation (E.10) Graypaper 0.5.3
func (m *MMR) SuperPeak(peaks []*crypto.Hash, hashFunc func([]byte) crypto.Hash) crypto.Hash {
// Filter out nil peaks while preserving order
validPeaks := make([]*crypto.Hash, 0, len(peaks))
Expand All @@ -78,12 +78,13 @@ func (m *MMR) SuperPeak(peaks []*crypto.Hash, hashFunc func([]byte) crypto.Hash)
return *validPeaks[0]
}

// H_K($peak ~ M_R(h...|h|-1) ~ h|h|-1)
// H_K($peak ~ M_R(h...|h|-1) ~ h|h|-1).
lastHash := *validPeaks[len(validPeaks)-1]

subPeak := m.SuperPeak(validPeaks[:len(validPeaks)-1], hashFunc)

combined := append([]byte("$peak"), subPeak[:]...)
combined := append([]byte("node"), subPeak[:]...) // Graypaper 0.5.3
//combined := append([]byte("peak"), subPeak[:]...) // Graypaper 0.5.4 TODO: [Issue 219] Uncomment once test vectors are updated).
combined = append(combined, lastHash[:]...)
result := hashFunc(combined)

Expand Down
4 changes: 2 additions & 2 deletions internal/merkle/mountain_ranges/mmr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func TestSuperPeak(t *testing.T) {
expected: func() crypto.Hash {
h1 := mockHashData([]byte("1"))
h2 := mockHashData([]byte("2"))
combined := append([]byte("$peak"), h1[:]...)
combined := append([]byte("node"), h1[:]...)
combined = append(combined, h2[:]...)
hash := mockHashData(combined)
return hash
Expand All @@ -138,7 +138,7 @@ func TestSuperPeak(t *testing.T) {
expected: func() crypto.Hash {
h1 := mockHashData([]byte("1"))
h2 := mockHashData([]byte("2"))
combined := append([]byte("$peak"), h1[:]...)
combined := append([]byte("node"), h1[:]...)
combined = append(combined, h2[:]...)
hash := mockHashData(combined)
return hash
Expand Down
Loading

0 comments on commit b1192d8

Please sign in to comment.