Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add created/updated reporting test vectors and fix implementations #222

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_000_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
)
5 changes: 3 additions & 2 deletions internal/common/constants_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const (
SizeOfSegment = 4104
MaxWorkPackageSize = 12 * 1 << 20
ErasureCodingChunkSize = 684
MaxAllocatedGasAccumulation = 100_000
MaxAllocatedGasIsAuthorized = 1_000_000
MaxAllocatedGasAccumulation = 10_000_000
MaxAllocatedGasIsAuthorized = 50_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
Loading