Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
78ecdf52
Unverified
Commit
78ecdf52
authored
Jan 03, 2024
by
Roberto Bayardo
Committed by
GitHub
Jan 03, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
blob encode/decode API, tests, plus placeholder implementation (#8767)
parent
68c65502
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
143 additions
and
0 deletions
+143
-0
blob.go
op-service/eth/blob.go
+65
-0
blob_test.go
op-service/eth/blob_test.go
+78
-0
No files found.
op-service/eth/blob.go
View file @
78ecdf52
...
...
@@ -2,6 +2,7 @@ package eth
import
(
"crypto/sha256"
"encoding/binary"
"fmt"
"reflect"
...
...
@@ -66,3 +67,67 @@ func KZGToVersionedHash(commitment kzg4844.Commitment) (out common.Hash) {
func
VerifyBlobProof
(
blob
*
Blob
,
commitment
kzg4844
.
Commitment
,
proof
kzg4844
.
Proof
)
error
{
return
kzg4844
.
VerifyBlobProof
(
*
blob
.
KZGBlob
(),
commitment
,
proof
)
}
// FromData encodes the given input data into this blob. The encoding scheme is as follows:
//
// First, field elements are encoded as big-endian uint256 in BLS modulus range. To avoid modulus
// overflow, we can't use the full 32 bytes, so we write data only to the topmost 31 bytes of each.
// TODO: we can optimize this to get a bit more data from the blobs by using the top byte
// partially.
//
// The first field element encodes the length of input data as a little endian uint32 in its
// topmost 4 (out of 31) bytes, and the first 27 bytes of the input data in its remaining 27
// bytes.
//
// The remaining field elements each encode 31 bytes of the remaining input data, up until the end
// of the input.
//
// TODO: version the encoding format to allow for future encoding changes
func
(
b
*
Blob
)
FromData
(
data
Data
)
error
{
if
len
(
data
)
>
MaxBlobDataSize
{
return
fmt
.
Errorf
(
"data is too large for blob. len=%v"
,
len
(
data
))
}
b
.
Clear
()
// encode 4-byte little-endian length value into topmost 4 bytes (out of 31) of first field
// element
binary
.
LittleEndian
.
PutUint32
(
b
[
1
:
5
],
uint32
(
len
(
data
)))
// encode first 27 bytes of input data into remaining bytes of first field element
offset
:=
copy
(
b
[
5
:
32
],
data
)
// encode (up to) 31 bytes of remaining input data at a time into the subsequent field element
for
i
:=
1
;
i
<
4096
;
i
++
{
offset
+=
copy
(
b
[
i
*
32
+
1
:
i
*
32
+
32
],
data
[
offset
:
])
if
offset
==
len
(
data
)
{
break
}
}
if
offset
<
len
(
data
)
{
return
fmt
.
Errorf
(
"failed to fit all data into blob. bytes remaining: %v"
,
len
(
data
)
-
offset
)
}
return
nil
}
// ToData decodes the blob into raw byte data. See FromData above for details on the encoding
// format.
func
(
b
*
Blob
)
ToData
()
(
Data
,
error
)
{
data
:=
make
(
Data
,
4096
*
32
)
for
i
:=
0
;
i
<
4096
;
i
++
{
if
b
[
i
*
32
]
!=
0
{
return
nil
,
fmt
.
Errorf
(
"invalid blob, found non-zero high order byte %x of field element %d"
,
b
[
i
*
32
],
i
)
}
copy
(
data
[
i
*
31
:
i
*
31
+
31
],
b
[
i
*
32
+
1
:
i
*
32
+
32
])
}
// extract the length prefix & trim the output accordingly
dataLen
:=
binary
.
LittleEndian
.
Uint32
(
data
[
:
4
])
data
=
data
[
4
:
]
if
dataLen
>
uint32
(
len
(
data
))
{
return
nil
,
fmt
.
Errorf
(
"invalid blob, length prefix out of range: %d"
,
dataLen
)
}
data
=
data
[
:
dataLen
]
return
data
,
nil
}
func
(
b
*
Blob
)
Clear
()
{
for
i
:=
0
;
i
<
BlobSize
;
i
++
{
b
[
i
]
=
0
}
}
op-service/eth/blob_test.go
0 → 100644
View file @
78ecdf52
package
eth
import
(
"testing"
)
func
TestBlobEncodeDecode
(
t
*
testing
.
T
)
{
cases
:=
[]
string
{
"this is a test of blob encoding/decoding"
,
"short"
,
"
\x00
"
,
"
\x00\x01\x00
"
,
"
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
"
,
"
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
"
,
"
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
"
,
""
,
}
var
b
Blob
for
_
,
c
:=
range
cases
{
data
:=
Data
(
c
)
if
err
:=
b
.
FromData
(
data
);
err
!=
nil
{
t
.
Fatalf
(
"failed to encode bytes: %v"
,
err
)
}
decoded
,
err
:=
b
.
ToData
()
if
err
!=
nil
{
t
.
Fatalf
(
"failed to decode blob: %v"
,
err
)
}
if
string
(
decoded
)
!=
c
{
t
.
Errorf
(
"decoded != input. got: %v, want: %v"
,
decoded
,
Data
(
c
))
}
}
}
func
TestBigBlobEncoding
(
t
*
testing
.
T
)
{
bigData
:=
Data
(
make
([]
byte
,
MaxBlobDataSize
))
bigData
[
MaxBlobDataSize
-
1
]
=
0xFF
var
b
Blob
if
err
:=
b
.
FromData
(
bigData
);
err
!=
nil
{
t
.
Fatalf
(
"failed to encode bytes: %v"
,
err
)
}
decoded
,
err
:=
b
.
ToData
()
if
err
!=
nil
{
t
.
Fatalf
(
"failed to decode blob: %v"
,
err
)
}
if
string
(
decoded
)
!=
string
(
bigData
)
{
t
.
Errorf
(
"decoded blob != big blob input"
)
}
}
func
TestInvalidBlobDecoding
(
t
*
testing
.
T
)
{
data
:=
Data
(
"this is a test of invalid blob decoding"
)
var
b
Blob
if
err
:=
b
.
FromData
(
data
);
err
!=
nil
{
t
.
Fatalf
(
"failed to encode bytes: %v"
,
err
)
}
b
[
32
]
=
0x80
// field elements should never have their highest order bit set
if
_
,
err
:=
b
.
ToData
();
err
==
nil
{
t
.
Errorf
(
"expected error, got none"
)
}
b
[
32
]
=
0x00
b
[
4
]
=
0xFF
// encode an invalid (much too long) length prefix
if
_
,
err
:=
b
.
ToData
();
err
==
nil
{
t
.
Errorf
(
"expected error, got none"
)
}
}
func
TestTooLongDataEncoding
(
t
*
testing
.
T
)
{
// should never be able to encode data that has size the same as that of the blob due to < 256
// bit precision of each field element
data
:=
Data
(
make
([]
byte
,
BlobSize
))
var
b
Blob
err
:=
b
.
FromData
(
data
)
if
err
==
nil
{
t
.
Errorf
(
"expected error, got none"
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment