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
61ac9ada
Unverified
Commit
61ac9ada
authored
Jan 18, 2024
by
refcell.eth
Committed by
GitHub
Jan 19, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(op-challenger): large preimage uploader add leaf support (#9062)
parent
48b9fe26
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
188 additions
and
39 deletions
+188
-39
oracle.go
op-challenger/game/fault/contracts/oracle.go
+3
-12
oracle_test.go
op-challenger/game/fault/contracts/oracle_test.go
+6
-10
large.go
op-challenger/game/fault/preimages/large.go
+82
-6
large_test.go
op-challenger/game/fault/preimages/large_test.go
+34
-4
types.go
op-challenger/game/fault/preimages/types.go
+1
-1
matrix.go
op-challenger/game/keccak/matrix/matrix.go
+6
-5
matrix_test.go
op-challenger/game/keccak/matrix/matrix_test.go
+56
-1
No files found.
op-challenger/game/fault/contracts/oracle.go
View file @
61ac9ada
...
@@ -98,18 +98,9 @@ func (c *PreimageOracleContract) InitLargePreimage(uuid *big.Int, partOffset uin
...
@@ -98,18 +98,9 @@ func (c *PreimageOracleContract) InitLargePreimage(uuid *big.Int, partOffset uin
return
call
.
ToTxCandidate
()
return
call
.
ToTxCandidate
()
}
}
func
(
c
*
PreimageOracleContract
)
AddLeaves
(
uuid
*
big
.
Int
,
leaves
[]
Leaf
,
finalize
bool
)
([]
txmgr
.
TxCandidate
,
error
)
{
func
(
c
*
PreimageOracleContract
)
AddLeaves
(
uuid
*
big
.
Int
,
input
[]
byte
,
commitments
[][
32
]
byte
,
finalize
bool
)
(
txmgr
.
TxCandidate
,
error
)
{
var
txs
[]
txmgr
.
TxCandidate
call
:=
c
.
contract
.
Call
(
methodAddLeavesLPP
,
uuid
,
input
,
commitments
,
finalize
)
for
_
,
leaf
:=
range
leaves
{
return
call
.
ToTxCandidate
()
commitments
:=
[][
32
]
byte
{([
32
]
byte
)(
leaf
.
StateCommitment
.
Bytes
())}
call
:=
c
.
contract
.
Call
(
methodAddLeavesLPP
,
uuid
,
leaf
.
Input
[
:
],
commitments
,
finalize
)
tx
,
err
:=
call
.
ToTxCandidate
()
if
err
!=
nil
{
return
nil
,
err
}
txs
=
append
(
txs
,
tx
)
}
return
txs
,
nil
}
}
func
(
c
*
PreimageOracleContract
)
Squeeze
(
func
(
c
*
PreimageOracleContract
)
Squeeze
(
...
...
op-challenger/game/fault/contracts/oracle_test.go
View file @
61ac9ada
...
@@ -56,23 +56,19 @@ func TestPreimageOracleContract_AddLeaves(t *testing.T) {
...
@@ -56,23 +56,19 @@ func TestPreimageOracleContract_AddLeaves(t *testing.T) {
stubRpc
,
oracle
:=
setupPreimageOracleTest
(
t
)
stubRpc
,
oracle
:=
setupPreimageOracleTest
(
t
)
uuid
:=
big
.
NewInt
(
123
)
uuid
:=
big
.
NewInt
(
123
)
leaves
:=
[]
Leaf
{{
input
:=
[]
byte
{
0x12
}
Input
:
[
136
]
byte
{
0x12
},
commitments
:=
[][
32
]
byte
{{
0x34
}}
Index
:
big
.
NewInt
(
123
),
StateCommitment
:
common
.
Hash
{
0x34
},
}}
finalize
:=
true
finalize
:=
true
stubRpc
.
SetResponse
(
oracleAddr
,
methodAddLeavesLPP
,
batching
.
BlockLatest
,
[]
interface
{}{
stubRpc
.
SetResponse
(
oracleAddr
,
methodAddLeavesLPP
,
batching
.
BlockLatest
,
[]
interface
{}{
uuid
,
uuid
,
leaves
[
0
]
.
Input
[
:
]
,
input
,
[][
32
]
byte
{([
32
]
byte
)(
leaves
[
0
]
.
StateCommitment
.
Bytes
())}
,
commitments
,
finalize
,
finalize
,
},
nil
)
},
nil
)
tx
s
,
err
:=
oracle
.
AddLeaves
(
uuid
,
leave
s
,
finalize
)
tx
,
err
:=
oracle
.
AddLeaves
(
uuid
,
input
,
commitment
s
,
finalize
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
txs
,
1
)
stubRpc
.
VerifyTxCandidate
(
tx
)
stubRpc
.
VerifyTxCandidate
(
txs
[
0
])
}
}
func
TestPreimageOracleContract_Squeeze
(
t
*
testing
.
T
)
{
func
TestPreimageOracleContract_Squeeze
(
t
*
testing
.
T
)
{
...
...
op-challenger/game/fault/preimages/large.go
View file @
61ac9ada
package
preimages
package
preimages
import
(
import
(
"bytes"
"context"
"context"
"crypto/rand"
"crypto/rand"
"errors"
"errors"
"fmt"
"fmt"
"io"
"math/big"
"math/big"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
ethtypes
"github.com/ethereum/go-ethereum/core/types"
ethtypes
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
...
@@ -17,6 +20,24 @@ var errNotSupported = errors.New("not supported")
...
@@ -17,6 +20,24 @@ var errNotSupported = errors.New("not supported")
var
_
PreimageUploader
=
(
*
LargePreimageUploader
)(
nil
)
var
_
PreimageUploader
=
(
*
LargePreimageUploader
)(
nil
)
// MaxLeafsPerChunk is the maximum number of leafs per chunk.
const
MaxLeafsPerChunk
=
300
// MaxChunkSize is the maximum size of a preimage chunk in bytes.
// Notice, the max chunk size must be a multiple of the leaf size.
// The max chunk size is roughly 0.04MB to avoid memory expansion.
const
MaxChunkSize
=
MaxLeafsPerChunk
*
matrix
.
LeafSize
// Chunk is a contigous segment of preimage data.
type
Chunk
struct
{
// Input is the preimage data.
Input
[]
byte
// Commitments are the keccak commitments for each leaf in the chunk.
Commitments
[][
32
]
byte
// Finalize indicates whether the chunk is the final chunk.
Finalize
bool
}
// LargePreimageUploader handles uploading large preimages by
// LargePreimageUploader handles uploading large preimages by
// streaming the merkleized preimage to the PreimageOracle contract,
// streaming the merkleized preimage to the PreimageOracle contract,
// tightly packed across multiple transactions.
// tightly packed across multiple transactions.
...
@@ -32,23 +53,50 @@ func NewLargePreimageUploader(logger log.Logger, txMgr txmgr.TxManager, contract
...
@@ -32,23 +53,50 @@ func NewLargePreimageUploader(logger log.Logger, txMgr txmgr.TxManager, contract
}
}
func
(
p
*
LargePreimageUploader
)
UploadPreimage
(
ctx
context
.
Context
,
parent
uint64
,
data
*
types
.
PreimageOracleData
)
error
{
func
(
p
*
LargePreimageUploader
)
UploadPreimage
(
ctx
context
.
Context
,
parent
uint64
,
data
*
types
.
PreimageOracleData
)
error
{
// todo(proofs#467): generate the full preimage
// Split the preimage data into chunks of size [MaxChunkSize] (except the last chunk).
// todo(proofs#467): run the preimage through the keccak permutation, hashing
stateMatrix
:=
matrix
.
NewStateMatrix
()
// the intermediate state matrix after each block is applied.
chunk
:=
make
([]
byte
,
0
,
MaxChunkSize
)
// todo(proofs#467): split up the preimage into chunks and submit the preimages
calls
:=
[]
Chunk
{}
// and state commitments to the preimage oracle contract using
commitments
:=
make
([][
32
]
byte
,
0
,
MaxLeafsPerChunk
)
// `PreimageOracle.addLeavesLPP` (`_finalize` = false).
in
:=
bytes
.
NewReader
(
data
.
OracleData
)
for
i
:=
0
;
;
i
++
{
// Absorb the next preimage chunk leaf and run the keccak permutation.
leaf
,
err
:=
stateMatrix
.
AbsorbNextLeaf
(
in
)
chunk
=
append
(
chunk
,
leaf
...
)
commitments
=
append
(
commitments
,
stateMatrix
.
StateCommitment
())
// SAFETY: the last leaf will always return an [io.EOF] error from [AbsorbNextLeaf].
if
errors
.
Is
(
err
,
io
.
EOF
)
{
calls
=
append
(
calls
,
Chunk
{
chunk
,
commitments
[
:
],
true
})
break
}
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to absorb leaf: %w"
,
err
)
}
// Only create a call if the chunk is full.
if
len
(
chunk
)
>=
MaxChunkSize
{
calls
=
append
(
calls
,
Chunk
{
chunk
,
commitments
[
:
],
false
})
chunk
=
make
([]
byte
,
0
,
MaxChunkSize
)
commitments
=
make
([][
32
]
byte
,
0
,
MaxLeafsPerChunk
)
}
}
// TODO(client-pod#473): The UUID must be deterministic so the challenger can resume uploads.
// TODO(client-pod#473): The UUID must be deterministic so the challenger can resume uploads.
uuid
,
err
:=
p
.
newUUID
()
uuid
,
err
:=
p
.
newUUID
()
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to generate UUID: %w"
,
err
)
return
fmt
.
Errorf
(
"failed to generate UUID: %w"
,
err
)
}
}
err
=
p
.
initLargePreimage
(
ctx
,
uuid
,
data
.
OracleOffset
,
uint32
(
len
(
data
.
OracleData
)))
err
=
p
.
initLargePreimage
(
ctx
,
uuid
,
data
.
OracleOffset
,
uint32
(
len
(
data
.
OracleData
)))
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to initialize large preimage with uuid: %s: %w"
,
uuid
,
err
)
return
fmt
.
Errorf
(
"failed to initialize large preimage with uuid: %s: %w"
,
uuid
,
err
)
}
}
err
=
p
.
addLargePreimageLeafs
(
ctx
,
uuid
,
calls
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to add leaves to large preimage with uuid: %s: %w"
,
uuid
,
err
)
}
// todo(proofs#467): track the challenge period starting once the full preimage is posted.
// todo(proofs#467): track the challenge period starting once the full preimage is posted.
// todo(proofs#467): once the challenge period is over, call `squeezeLPP` on the preimage oracle contract.
// todo(proofs#467): once the challenge period is over, call `squeezeLPP` on the preimage oracle contract.
...
@@ -74,6 +122,34 @@ func (p *LargePreimageUploader) initLargePreimage(ctx context.Context, uuid *big
...
@@ -74,6 +122,34 @@ func (p *LargePreimageUploader) initLargePreimage(ctx context.Context, uuid *big
return
nil
return
nil
}
}
// addLargePreimageLeafs adds leafs to the large preimage proposal.
// This method **must** be called after calling [initLargePreimage].
// SAFETY: submits transactions in a [Queue] for latency while preserving submission order.
func
(
p
*
LargePreimageUploader
)
addLargePreimageLeafs
(
ctx
context
.
Context
,
uuid
*
big
.
Int
,
chunks
[]
Chunk
)
error
{
queue
:=
txmgr
.
NewQueue
[
int
](
ctx
,
p
.
txMgr
,
10
)
receiptChs
:=
make
([]
chan
txmgr
.
TxReceipt
[
int
],
len
(
chunks
))
for
i
,
chunk
:=
range
chunks
{
tx
,
err
:=
p
.
contract
.
AddLeaves
(
uuid
,
chunk
.
Input
,
chunk
.
Commitments
,
chunk
.
Finalize
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create pre-image oracle tx: %w"
,
err
)
}
receiptChs
[
i
]
=
make
(
chan
txmgr
.
TxReceipt
[
int
],
1
)
queue
.
Send
(
i
,
tx
,
receiptChs
[
i
])
}
for
_
,
receiptCh
:=
range
receiptChs
{
receipt
:=
<-
receiptCh
if
receipt
.
Err
!=
nil
{
return
receipt
.
Err
}
if
receipt
.
Receipt
.
Status
==
ethtypes
.
ReceiptStatusFailed
{
p
.
log
.
Error
(
"LargePreimageUploader add leafs tx successfully published but reverted"
,
"tx_hash"
,
receipt
.
Receipt
.
TxHash
)
}
else
{
p
.
log
.
Debug
(
"LargePreimageUploader add leafs tx successfully published"
,
"tx_hash"
,
receipt
.
Receipt
.
TxHash
)
}
}
return
nil
}
// sendTxAndWait sends a transaction through the [txmgr] and waits for a receipt.
// sendTxAndWait sends a transaction through the [txmgr] and waits for a receipt.
// This sets the tx GasLimit to 0, performing gas estimation online through the [txmgr].
// This sets the tx GasLimit to 0, performing gas estimation online through the [txmgr].
func
(
p
*
LargePreimageUploader
)
sendTxAndWait
(
ctx
context
.
Context
,
candidate
txmgr
.
TxCandidate
)
error
{
func
(
p
*
LargePreimageUploader
)
sendTxAndWait
(
ctx
context
.
Context
,
candidate
txmgr
.
TxCandidate
)
error
{
...
...
op-challenger/game/fault/preimages/large_test.go
View file @
61ac9ada
...
@@ -2,6 +2,7 @@ package preimages
...
@@ -2,6 +2,7 @@ package preimages
import
(
import
(
"context"
"context"
"errors"
"math/big"
"math/big"
"testing"
"testing"
...
@@ -15,6 +16,8 @@ import (
...
@@ -15,6 +16,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
var
mockAddLeavesError
=
errors
.
New
(
"mock add leaves error"
)
func
TestLargePreimageUploader_UploadPreimage
(
t
*
testing
.
T
)
{
func
TestLargePreimageUploader_UploadPreimage
(
t
*
testing
.
T
)
{
t
.
Run
(
"InitFails"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"InitFails"
,
func
(
t
*
testing
.
T
)
{
oracle
,
_
,
contract
:=
newTestLargePreimageUploader
(
t
)
oracle
,
_
,
contract
:=
newTestLargePreimageUploader
(
t
)
...
@@ -24,10 +27,27 @@ func TestLargePreimageUploader_UploadPreimage(t *testing.T) {
...
@@ -24,10 +27,27 @@ func TestLargePreimageUploader_UploadPreimage(t *testing.T) {
require
.
Equal
(
t
,
1
,
contract
.
initCalls
)
require
.
Equal
(
t
,
1
,
contract
.
initCalls
)
})
})
t
.
Run
(
"
Succes
s"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"
AddLeavesFail
s"
,
func
(
t
*
testing
.
T
)
{
oracle
,
_
,
contract
:=
newTestLargePreimageUploader
(
t
)
oracle
,
_
,
contract
:=
newTestLargePreimageUploader
(
t
)
contract
.
addFails
=
true
err
:=
oracle
.
UploadPreimage
(
context
.
Background
(),
0
,
&
types
.
PreimageOracleData
{})
err
:=
oracle
.
UploadPreimage
(
context
.
Background
(),
0
,
&
types
.
PreimageOracleData
{})
require
.
ErrorIs
(
t
,
err
,
mockAddLeavesError
)
require
.
Equal
(
t
,
1
,
contract
.
addCalls
)
})
t
.
Run
(
"Success"
,
func
(
t
*
testing
.
T
)
{
fullLeaf
:=
make
([]
byte
,
matrix
.
LeafSize
)
for
i
:=
0
;
i
<
matrix
.
LeafSize
;
i
++
{
fullLeaf
[
i
]
=
byte
(
i
)
}
oracle
,
_
,
contract
:=
newTestLargePreimageUploader
(
t
)
data
:=
types
.
PreimageOracleData
{
OracleData
:
append
(
fullLeaf
,
fullLeaf
...
),
}
err
:=
oracle
.
UploadPreimage
(
context
.
Background
(),
0
,
&
data
)
require
.
Equal
(
t
,
1
,
contract
.
initCalls
)
require
.
Equal
(
t
,
1
,
contract
.
initCalls
)
require
.
Equal
(
t
,
1
,
contract
.
addCalls
)
require
.
Equal
(
t
,
data
.
OracleData
,
contract
.
addData
)
// TODO(proofs#467): fix this to not error. See LargePreimageUploader.UploadPreimage.
// TODO(proofs#467): fix this to not error. See LargePreimageUploader.UploadPreimage.
require
.
ErrorIs
(
t
,
err
,
errNotSupported
)
require
.
ErrorIs
(
t
,
err
,
errNotSupported
)
})
})
...
@@ -36,13 +56,18 @@ func TestLargePreimageUploader_UploadPreimage(t *testing.T) {
...
@@ -36,13 +56,18 @@ func TestLargePreimageUploader_UploadPreimage(t *testing.T) {
func
newTestLargePreimageUploader
(
t
*
testing
.
T
)
(
*
LargePreimageUploader
,
*
mockTxMgr
,
*
mockPreimageOracleContract
)
{
func
newTestLargePreimageUploader
(
t
*
testing
.
T
)
(
*
LargePreimageUploader
,
*
mockTxMgr
,
*
mockPreimageOracleContract
)
{
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
txMgr
:=
&
mockTxMgr
{}
txMgr
:=
&
mockTxMgr
{}
contract
:=
&
mockPreimageOracleContract
{}
contract
:=
&
mockPreimageOracleContract
{
addData
:
make
([]
byte
,
0
),
}
return
NewLargePreimageUploader
(
logger
,
txMgr
,
contract
),
txMgr
,
contract
return
NewLargePreimageUploader
(
logger
,
txMgr
,
contract
),
txMgr
,
contract
}
}
type
mockPreimageOracleContract
struct
{
type
mockPreimageOracleContract
struct
{
initCalls
int
initCalls
int
initFails
bool
initFails
bool
addCalls
int
addFails
bool
addData
[]
byte
}
}
func
(
s
*
mockPreimageOracleContract
)
InitLargePreimage
(
_
*
big
.
Int
,
_
uint32
,
_
uint32
)
(
txmgr
.
TxCandidate
,
error
)
{
func
(
s
*
mockPreimageOracleContract
)
InitLargePreimage
(
_
*
big
.
Int
,
_
uint32
,
_
uint32
)
(
txmgr
.
TxCandidate
,
error
)
{
...
@@ -52,8 +77,13 @@ func (s *mockPreimageOracleContract) InitLargePreimage(_ *big.Int, _ uint32, _ u
...
@@ -52,8 +77,13 @@ func (s *mockPreimageOracleContract) InitLargePreimage(_ *big.Int, _ uint32, _ u
}
}
return
txmgr
.
TxCandidate
{},
nil
return
txmgr
.
TxCandidate
{},
nil
}
}
func
(
s
*
mockPreimageOracleContract
)
AddLeaves
(
_
*
big
.
Int
,
_
[]
contracts
.
Leaf
,
_
bool
)
([]
txmgr
.
TxCandidate
,
error
)
{
func
(
s
*
mockPreimageOracleContract
)
AddLeaves
(
_
*
big
.
Int
,
input
[]
byte
,
_
[][
32
]
byte
,
_
bool
)
(
txmgr
.
TxCandidate
,
error
)
{
return
[]
txmgr
.
TxCandidate
{},
nil
s
.
addCalls
++
s
.
addData
=
append
(
s
.
addData
,
input
...
)
if
s
.
addFails
{
return
txmgr
.
TxCandidate
{},
mockAddLeavesError
}
return
txmgr
.
TxCandidate
{},
nil
}
}
func
(
s
*
mockPreimageOracleContract
)
Squeeze
(
_
common
.
Address
,
_
*
big
.
Int
,
_
*
matrix
.
StateMatrix
,
_
contracts
.
Leaf
,
_
contracts
.
MerkleProof
,
_
contracts
.
Leaf
,
_
contracts
.
MerkleProof
)
(
txmgr
.
TxCandidate
,
error
)
{
func
(
s
*
mockPreimageOracleContract
)
Squeeze
(
_
common
.
Address
,
_
*
big
.
Int
,
_
*
matrix
.
StateMatrix
,
_
contracts
.
Leaf
,
_
contracts
.
MerkleProof
,
_
contracts
.
Leaf
,
_
contracts
.
MerkleProof
)
(
txmgr
.
TxCandidate
,
error
)
{
return
txmgr
.
TxCandidate
{},
nil
return
txmgr
.
TxCandidate
{},
nil
...
...
op-challenger/game/fault/preimages/types.go
View file @
61ac9ada
...
@@ -23,6 +23,6 @@ type PreimageUploader interface {
...
@@ -23,6 +23,6 @@ type PreimageUploader interface {
// PreimageOracleContract is the interface for interacting with the PreimageOracle contract.
// PreimageOracleContract is the interface for interacting with the PreimageOracle contract.
type
PreimageOracleContract
interface
{
type
PreimageOracleContract
interface
{
InitLargePreimage
(
uuid
*
big
.
Int
,
partOffset
uint32
,
claimedSize
uint32
)
(
txmgr
.
TxCandidate
,
error
)
InitLargePreimage
(
uuid
*
big
.
Int
,
partOffset
uint32
,
claimedSize
uint32
)
(
txmgr
.
TxCandidate
,
error
)
AddLeaves
(
uuid
*
big
.
Int
,
leaves
[]
contracts
.
Leaf
,
finalize
bool
)
([]
txmgr
.
TxCandidate
,
error
)
AddLeaves
(
uuid
*
big
.
Int
,
input
[]
byte
,
commitments
[][
32
]
byte
,
finalize
bool
)
(
txmgr
.
TxCandidate
,
error
)
Squeeze
(
claimant
common
.
Address
,
uuid
*
big
.
Int
,
stateMatrix
*
matrix
.
StateMatrix
,
preState
contracts
.
Leaf
,
preStateProof
contracts
.
MerkleProof
,
postState
contracts
.
Leaf
,
postStateProof
contracts
.
MerkleProof
)
(
txmgr
.
TxCandidate
,
error
)
Squeeze
(
claimant
common
.
Address
,
uuid
*
big
.
Int
,
stateMatrix
*
matrix
.
StateMatrix
,
preState
contracts
.
Leaf
,
preStateProof
contracts
.
MerkleProof
,
postState
contracts
.
Leaf
,
postStateProof
contracts
.
MerkleProof
)
(
txmgr
.
TxCandidate
,
error
)
}
}
op-challenger/game/keccak/matrix/matrix.go
View file @
61ac9ada
...
@@ -43,7 +43,7 @@ func (d *StateMatrix) PackState() []byte {
...
@@ -43,7 +43,7 @@ func (d *StateMatrix) PackState() []byte {
// AbsorbNextLeaf reads up to [LeafSize] bytes from in and absorbs them into the state matrix.
// AbsorbNextLeaf reads up to [LeafSize] bytes from in and absorbs them into the state matrix.
// If EOF is reached while reading, the state matrix is finalized and [io.EOF] is returned.
// If EOF is reached while reading, the state matrix is finalized and [io.EOF] is returned.
func
(
d
*
StateMatrix
)
AbsorbNextLeaf
(
in
io
.
Reader
)
error
{
func
(
d
*
StateMatrix
)
AbsorbNextLeaf
(
in
io
.
Reader
)
([]
byte
,
error
)
{
data
:=
make
([]
byte
,
LeafSize
)
data
:=
make
([]
byte
,
LeafSize
)
read
:=
0
read
:=
0
final
:=
false
final
:=
false
...
@@ -53,15 +53,16 @@ func (d *StateMatrix) AbsorbNextLeaf(in io.Reader) error {
...
@@ -53,15 +53,16 @@ func (d *StateMatrix) AbsorbNextLeaf(in io.Reader) error {
final
=
true
final
=
true
break
break
}
else
if
err
!=
nil
{
}
else
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
read
+=
n
read
+=
n
}
}
d
.
AbsorbLeaf
(
data
[
:
read
],
final
)
leafData
:=
data
[
:
read
]
d
.
AbsorbLeaf
(
leafData
,
final
)
if
final
{
if
final
{
return
io
.
EOF
return
leafData
,
io
.
EOF
}
}
return
nil
return
leafData
,
nil
}
}
// AbsorbLeaf absorbs the specified data into the keccak sponge.
// AbsorbLeaf absorbs the specified data into the keccak sponge.
...
...
op-challenger/game/keccak/matrix/matrix_test.go
View file @
61ac9ada
...
@@ -89,7 +89,7 @@ func TestReferenceCommitmentsFromReader(t *testing.T) {
...
@@ -89,7 +89,7 @@ func TestReferenceCommitmentsFromReader(t *testing.T) {
commitments
:=
[]
common
.
Hash
{
s
.
StateCommitment
()}
commitments
:=
[]
common
.
Hash
{
s
.
StateCommitment
()}
in
:=
bytes
.
NewReader
(
test
.
Input
)
in
:=
bytes
.
NewReader
(
test
.
Input
)
for
{
for
{
err
:=
s
.
AbsorbNextLeaf
(
in
)
_
,
err
:=
s
.
AbsorbNextLeaf
(
in
)
if
errors
.
Is
(
err
,
io
.
EOF
)
{
if
errors
.
Is
(
err
,
io
.
EOF
)
{
commitments
=
append
(
commitments
,
s
.
StateCommitment
())
commitments
=
append
(
commitments
,
s
.
StateCommitment
())
break
break
...
@@ -106,6 +106,61 @@ func TestReferenceCommitmentsFromReader(t *testing.T) {
...
@@ -106,6 +106,61 @@ func TestReferenceCommitmentsFromReader(t *testing.T) {
}
}
}
}
func
TestMatrix_AbsorbNextLeaf
(
t
*
testing
.
T
)
{
fullLeaf
:=
make
([]
byte
,
LeafSize
)
for
i
:=
0
;
i
<
LeafSize
;
i
++
{
fullLeaf
[
i
]
=
byte
(
i
)
}
tests
:=
[]
struct
{
name
string
input
[]
byte
leafs
[][]
byte
errs
[]
error
}{
{
name
:
"empty"
,
input
:
[]
byte
{},
leafs
:
[][]
byte
{{}},
errs
:
[]
error
{
io
.
EOF
},
},
{
name
:
"single"
,
input
:
fullLeaf
,
leafs
:
[][]
byte
{
fullLeaf
},
errs
:
[]
error
{
io
.
EOF
},
},
{
name
:
"single-overflow"
,
input
:
append
(
fullLeaf
,
byte
(
9
)),
leafs
:
[][]
byte
{
fullLeaf
,
{
byte
(
9
)}},
errs
:
[]
error
{
nil
,
io
.
EOF
},
},
{
name
:
"double"
,
input
:
append
(
fullLeaf
,
fullLeaf
...
),
leafs
:
[][]
byte
{
fullLeaf
,
fullLeaf
},
errs
:
[]
error
{
nil
,
io
.
EOF
},
},
}
for
_
,
test
:=
range
tests
{
test
:=
test
t
.
Run
(
test
.
name
,
func
(
t
*
testing
.
T
)
{
state
:=
NewStateMatrix
()
in
:=
bytes
.
NewReader
(
test
.
input
)
for
i
,
leaf
:=
range
test
.
leafs
{
buf
,
err
:=
state
.
AbsorbNextLeaf
(
in
)
if
errors
.
Is
(
err
,
io
.
EOF
)
{
require
.
Equal
(
t
,
test
.
errs
[
i
],
err
)
break
}
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
leaf
,
buf
)
}
})
}
}
func
FuzzKeccak
(
f
*
testing
.
F
)
{
func
FuzzKeccak
(
f
*
testing
.
F
)
{
f
.
Fuzz
(
func
(
t
*
testing
.
T
,
number
,
time
uint64
,
data
[]
byte
)
{
f
.
Fuzz
(
func
(
t
*
testing
.
T
,
number
,
time
uint64
,
data
[]
byte
)
{
s
:=
NewStateMatrix
()
s
:=
NewStateMatrix
()
...
...
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