Compare commits

..

39 Commits

Author SHA1 Message Date
colinlyguo
106f409a02 tweak and bump version 2023-08-05 16:00:33 +08:00
colinlyguo
b42a17580b go mod tidy and bump version 2023-08-05 03:41:04 +08:00
colinlyguo
47bf98eb30 address comments 2023-08-05 03:32:29 +08:00
colinlyguo
e3a49fc041 happy path integration test 2023-08-04 22:31:56 +08:00
colinlyguo
72355067b8 fix get task and proof 2023-08-04 20:56:52 +08:00
georgehao
fcf34edbfb feat(coordinator): add prover rest api (#716)
Co-authored-by: colinlyguo <colinlyguo@scroll.io>
2023-08-04 20:48:17 +08:00
georgehao
d11de12637 Merge branch 'develop' of github.com:scroll-tech/scroll into pull-model-prover-client 2023-08-04 17:01:31 +08:00
colin
3be3f9926a Merge branch 'develop' into pull-model-prover-client 2023-08-04 15:22:39 +08:00
colin
ba51b5794d Merge branch 'develop' into pull-model-prover-client 2023-08-04 14:37:08 +08:00
colinlyguo
f22efbff22 tweak integration-test 2023-08-03 20:02:26 +08:00
colin
8f92ca9010 Merge branch 'develop' into pull-model-prover-client 2023-08-03 19:33:16 +08:00
colinlyguo
2c69352948 fix 2023-08-03 19:17:22 +08:00
colinlyguo
0652852c16 address comments 2023-08-03 19:01:46 +08:00
colinlyguo
bbb4ca6d76 revert flag change 2023-08-03 17:56:26 +08:00
colinlyguo
1b542830af add mock_proof_submission config 2023-08-03 17:38:25 +08:00
colinlyguo
975e61afe4 tweak 2023-08-03 17:12:45 +08:00
colinlyguo
7bf538f287 refactor error code 2023-08-03 17:08:26 +08:00
colinlyguo
58fc8a3add remove signature 2023-08-03 16:30:27 +08:00
colinlyguo
bf9dabd9b7 tweak login request 2023-08-03 15:54:50 +08:00
colinlyguo
beea5754cb add retry mechanism for JWT expiration 2023-08-03 15:46:14 +08:00
colin
d0c82f78ad Merge branch 'develop' into pull-model-prover-client 2023-08-03 15:03:02 +08:00
colinlyguo
3913a7397c run goimport 2023-08-03 15:01:51 +08:00
colinlyguo
c63e25a9bf add login auth 2023-08-03 14:57:24 +08:00
colinlyguo
8960849677 address comments 2023-08-03 13:39:31 +08:00
colinlyguo
24d8658ddb address comments 2023-08-03 13:11:12 +08:00
colinlyguo
f88f883b6a simplify http body result marshal 2023-08-03 11:46:57 +08:00
colinlyguo
c8fd76dd02 trigger ci 2023-08-02 16:48:04 +08:00
colin
b82bbedaca Merge branch 'develop' into pull-model-prover-client 2023-08-02 16:36:14 +08:00
colinlyguo
1ea0dcd0ae bump version 2023-08-02 16:35:42 +08:00
colinlyguo
e87bdbabe2 tweak code 2023-08-02 16:32:41 +08:00
colinlyguo
4db1565ba3 comment out prover start process test (coordinator not support login yet) 2023-08-02 03:13:36 +08:00
colinlyguo
2425374362 fix 2023-08-02 03:05:06 +08:00
colinlyguo
89b2e3133a scrollfmt 2023-08-02 02:44:42 +08:00
colinlyguo
5b7a2bb40c bump version 2023-08-02 02:36:18 +08:00
colinlyguo
0466e2d201 add retry configs 2023-08-02 02:32:05 +08:00
colinlyguo
f86cbb2bcb fix 2023-08-02 02:14:30 +08:00
colin
712c2c5ad3 Merge branch 'develop' into pull-model-prover-client 2023-08-02 01:54:47 +08:00
colinlyguo
a8a5db9a18 fix 2023-08-01 22:27:45 +08:00
colinlyguo
61d8b48b73 a commit 2023-08-01 21:05:13 +08:00
106 changed files with 768 additions and 1094 deletions

File diff suppressed because one or more lines are too long

View File

@@ -53,11 +53,11 @@ func (m *MsgProofUpdater) Start() {
continue
}
latestBatchIndexWithProof, err := m.l2SentMsgOrm.GetLatestL2SentMsgBatchIndex(m.ctx)
log.Info("latest batc with proof", "batch_index", latestBatchIndexWithProof)
if err != nil {
log.Error("MsgProofUpdater: Can not get latest L2SentMsgBatchIndex: ", "err", err)
continue
}
log.Info("latest batch with proof", "batch_index", latestBatchIndexWithProof)
var start uint64
if latestBatchIndexWithProof < 0 {
start = 1

View File

@@ -15,7 +15,6 @@ func Route(router *gin.Engine, conf *config.Config) {
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))

View File

@@ -204,7 +204,7 @@ func (c *CrossMsg) DeleteL1CrossMsgAfterHeight(ctx context.Context, height uint6
// GetL2CrossMsgByHash returns layer2 cross message by given hash
func (c *CrossMsg) GetL2CrossMsgByHash(ctx context.Context, l2Hash common.Hash) (*CrossMsg, error) {
var result CrossMsg
err := c.db.WithContext(ctx).Model(&CrossMsg{}).Where("layer2_hash = ? AND msg_type = ?", l2Hash.String(), Layer2Msg).First(&result).Error
err := c.db.WithContext(ctx).Model(&CrossMsg{}).Where("layer2_hash = ? AND msg_type = ?", l2Hash.String(), Layer1Msg).First(&result).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil

View File

@@ -2,7 +2,6 @@ package orm
import (
"context"
"errors"
"fmt"
"time"
@@ -103,9 +102,6 @@ func (l *L2SentMsg) GetLatestL2SentMsgBatchIndex(ctx context.Context) (int64, er
Select("batch_index").
First(&result).
Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
return -1, nil
}
if err != nil {
return -1, fmt.Errorf("L2SentMsg.GetLatestL2SentMsgBatchIndex error: %w", err)
}

View File

@@ -1,6 +1,7 @@
package utils
import (
"bytes"
"context"
"encoding/binary"
"errors"
@@ -75,14 +76,6 @@ func GetBatchRangeFromCalldataV2(calldata []byte) (uint64, uint64, uint64, error
method := backendabi.ScrollChainV2ABI.Methods["commitBatch"]
values, err := method.Inputs.Unpack(calldata[4:])
if err != nil {
// special case: import genesis batch
method = backendabi.ScrollChainV2ABI.Methods["importGenesisBatch"]
_, err2 := method.Inputs.Unpack(calldata[4:])
if err2 == nil {
// genesis batch
return 0, 0, 0, nil
}
// none of "commitBatch" and "importGenesisBatch" match, give up
return 0, 0, 0, err
}
args := commitBatchArgs{}
@@ -117,3 +110,48 @@ func GetBatchRangeFromCalldataV2(calldata []byte) (uint64, uint64, uint64, error
return batchIndex, startBlock, finishBlock, err
}
// GetBatchRangeFromCalldataV1 find the block range from calldata, both inclusive.
func GetBatchRangeFromCalldataV1(calldata []byte) ([]uint64, []uint64, []uint64, error) {
var batchIndices []uint64
var startBlocks []uint64
var finishBlocks []uint64
if bytes.Equal(calldata[0:4], common.Hex2Bytes("cb905499")) {
// commitBatches
method := backendabi.ScrollChainABI.Methods["commitBatches"]
values, err := method.Inputs.Unpack(calldata[4:])
if err != nil {
return batchIndices, startBlocks, finishBlocks, err
}
args := make([]backendabi.IScrollChainBatch, len(values))
err = method.Inputs.Copy(&args, values)
if err != nil {
return batchIndices, startBlocks, finishBlocks, err
}
for i := 0; i < len(args); i++ {
batchIndices = append(batchIndices, args[i].BatchIndex)
startBlocks = append(startBlocks, args[i].Blocks[0].BlockNumber)
finishBlocks = append(finishBlocks, args[i].Blocks[len(args[i].Blocks)-1].BlockNumber)
}
} else if bytes.Equal(calldata[0:4], common.Hex2Bytes("8c73235d")) {
// commitBatch
method := backendabi.ScrollChainABI.Methods["commitBatch"]
values, err := method.Inputs.Unpack(calldata[4:])
if err != nil {
return batchIndices, startBlocks, finishBlocks, err
}
args := backendabi.IScrollChainBatch{}
err = method.Inputs.Copy(&args, values)
if err != nil {
return batchIndices, startBlocks, finishBlocks, err
}
batchIndices = append(batchIndices, args.BatchIndex)
startBlocks = append(startBlocks, args.Blocks[0].BlockNumber)
finishBlocks = append(finishBlocks, args.Blocks[len(args.Blocks)-1].BlockNumber)
} else {
return batchIndices, startBlocks, finishBlocks, errors.New("invalid selector")
}
return batchIndices, startBlocks, finishBlocks, nil
}

View File

@@ -1,6 +1,7 @@
package utils_test
import (
"os"
"testing"
"github.com/ethereum/go-ethereum/common"
@@ -33,11 +34,31 @@ func TestGetBatchRangeFromCalldataV2(t *testing.T) {
assert.Equal(t, start, uint64(10))
assert.Equal(t, finish, uint64(20))
assert.Equal(t, batchIndex, uint64(2))
// genesis batch
batchIndex, start, finish, err = utils.GetBatchRangeFromCalldataV2(common.Hex2Bytes("3fdeecb200000000000000000000000000000000000000000000000000000000000000402dcb5308098d24a37fc1487a229fcedb09fa4343ede39cbad365bc925535bb09000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000c252bc9780c4d83cf11f14b8cd03c92c4d18ce07710ba836d31d12da216c8330000000000000000000000000000000000000000000000000000000000000000000000000000000"))
assert.NoError(t, err)
assert.Equal(t, start, uint64(0))
assert.Equal(t, finish, uint64(0))
assert.Equal(t, batchIndex, uint64(0))
}
func TestGetBatchRangeFromCalldataV1(t *testing.T) {
calldata, err := os.ReadFile("../testdata/commit-batches-0x3095e91db7ba4a6fbf4654d607db322e58ff5579c502219c8024acaea74cf311.txt")
assert.NoError(t, err)
// multiple batches
batchIndices, startBlocks, finishBlocks, err := utils.GetBatchRangeFromCalldataV1(common.Hex2Bytes(string(calldata[:])))
assert.NoError(t, err)
assert.Equal(t, len(batchIndices), 5)
assert.Equal(t, len(startBlocks), 5)
assert.Equal(t, len(finishBlocks), 5)
assert.Equal(t, batchIndices[0], uint64(1))
assert.Equal(t, batchIndices[1], uint64(2))
assert.Equal(t, batchIndices[2], uint64(3))
assert.Equal(t, batchIndices[3], uint64(4))
assert.Equal(t, batchIndices[4], uint64(5))
assert.Equal(t, startBlocks[0], uint64(1))
assert.Equal(t, startBlocks[1], uint64(6))
assert.Equal(t, startBlocks[2], uint64(7))
assert.Equal(t, startBlocks[3], uint64(19))
assert.Equal(t, startBlocks[4], uint64(20))
assert.Equal(t, finishBlocks[0], uint64(5))
assert.Equal(t, finishBlocks[1], uint64(6))
assert.Equal(t, finishBlocks[2], uint64(18))
assert.Equal(t, finishBlocks[3], uint64(19))
assert.Equal(t, finishBlocks[4], uint64(20))
}

File diff suppressed because one or more lines are too long

View File

@@ -15,8 +15,8 @@ func TestEventSignature(t *testing.T) {
assert.Equal(L1RelayedMessageEventSignature, common.HexToHash("4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c"))
assert.Equal(L1FailedRelayedMessageEventSignature, common.HexToHash("99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f"))
assert.Equal(L1CommitBatchEventSignature, common.HexToHash("2c32d4ae151744d0bf0b9464a3e897a1d17ed2f1af71f7c9a75f12ce0d28238f"))
assert.Equal(L1FinalizeBatchEventSignature, common.HexToHash("26ba82f907317eedc97d0cbef23de76a43dd6edb563bdb6e9407645b950a7a2d"))
assert.Equal(L1CommitBatchEventSignature, common.HexToHash("2cdc615c74452778c0fb6184735e014c13aad2b62774fe0b09bd1dcc2cc14a62"))
assert.Equal(L1FinalizeBatchEventSignature, common.HexToHash("9d3058a3cb9739a2527f22dd9a4138065844037d3004254952e2458d808cc364"))
assert.Equal(L1QueueTransactionEventSignature, common.HexToHash("69cfcb8e6d4192b8aba9902243912587f37e550d75c1fa801491fce26717f37e"))

View File

@@ -110,7 +110,7 @@ func action(ctx *cli.Context) error {
go utils.Loop(subCtx, 2*time.Second, l2relayer.ProcessPendingBatches)
go utils.Loop(subCtx, 60*time.Second, l2relayer.ProcessCommittedBatches)
go utils.Loop(subCtx, 2*time.Second, l2relayer.ProcessCommittedBatches)
// Finish start all rollup relayer functions.
log.Info("Start rollup-relayer successfully")

View File

@@ -376,14 +376,9 @@ func (r *Layer2Relayer) ProcessPendingBatches() {
txID := batch.Hash + "-commit"
txHash, err := r.rollupSender.SendTransaction(txID, &r.cfg.RollupContractAddress, big.NewInt(0), calldata, 0)
if err != nil {
log.Error(
"Failed to send commitBatch tx to layer1",
"index", batch.Index,
"hash", batch.Hash,
"RollupContractAddress", r.cfg.RollupContractAddress,
"calldata", common.Bytes2Hex(calldata),
"err", err,
)
if !errors.Is(err, sender.ErrNoAvailableAccount) && !errors.Is(err, sender.ErrFullPending) {
log.Error("Failed to send commitBatch tx to layer1 ", "err", err)
}
return
}
@@ -429,6 +424,7 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
return
case types.ProvingTaskVerified:
log.Info("Start to roll up zk proof", "hash", hash)
success := false
var parentBatchStateRoot string
if batch.Index > 0 {
@@ -442,14 +438,24 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
parentBatchStateRoot = parentBatch.StateRoot
}
defer func() {
// TODO: need to revisit this and have a more fine-grained error handling
if !success {
log.Info("Failed to upload the proof, change rollup status to RollupFinalizeFailed", "hash", hash)
if err = r.batchOrm.UpdateRollupStatus(r.ctx, hash, types.RollupFinalizeFailed); err != nil {
log.Warn("UpdateRollupStatus failed", "hash", hash, "err", err)
}
}
}()
aggProof, err := r.batchOrm.GetVerifiedProofByHash(r.ctx, hash)
if err != nil {
log.Error("get verified proof by hash failed", "hash", hash, "err", err)
log.Warn("get verified proof by hash failed", "hash", hash, "err", err)
return
}
if err = aggProof.SanityCheck(); err != nil {
log.Error("agg_proof sanity check fails", "hash", hash, "error", err)
log.Warn("agg_proof sanity check fails", "hash", hash, "error", err)
return
}
@@ -472,18 +478,8 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
finalizeTxHash := &txHash
if err != nil {
if !errors.Is(err, sender.ErrNoAvailableAccount) && !errors.Is(err, sender.ErrFullPending) {
// This can happen normally if we try to finalize 2 or more
// batches around the same time. The 2nd tx might fail since
// the client does not see the 1st tx's updates at this point.
// TODO: add more fine-grained error handling
log.Error(
"finalizeBatchWithProof in layer1 failed",
"index", batch.Index,
"hash", batch.Hash,
"RollupContractAddress", r.cfg.RollupContractAddress,
"calldata", common.Bytes2Hex(data),
"err", err,
)
log.Error("finalizeBatchWithProof in layer1 failed",
"index", batch.Index, "hash", batch.Hash, "err", err)
}
return
}
@@ -493,31 +489,13 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
// record and sync with db, @todo handle db error
err = r.batchOrm.UpdateFinalizeTxHashAndRollupStatus(r.ctx, hash, finalizeTxHash.String(), types.RollupFinalizing)
if err != nil {
log.Error("UpdateFinalizeTxHashAndRollupStatus failed",
log.Warn("UpdateFinalizeTxHashAndRollupStatus failed",
"index", batch.Index, "batch hash", batch.Hash,
"tx hash", finalizeTxHash.String(), "err", err)
}
success = true
r.processingFinalization.Store(txID, hash)
case types.ProvingTaskFailed:
// We were unable to prove this batch. There are two possibilities:
// (a) Prover bug. In this case, we should fix and redeploy the prover.
// In the meantime, we continue to commit batches to L1 as well as
// proposing and proving chunks and batches.
// (b) Unprovable batch, e.g. proof overflow. In this case we need to
// stop the ledger, fix the limit, revert all the violating blocks,
// chunks and batches and all subsequent ones, and resume, i.e. this
// case requires manual resolution.
log.Error(
"batch proving failed",
"Index", batch.Index,
"Hash", batch.Hash,
"ProverAssignedAt", batch.ProverAssignedAt,
"ProvedAt", batch.ProvedAt,
"ProofTimeSec", batch.ProofTimeSec,
)
return
default:
log.Error("encounter unreachable case in ProcessCommittedBatches", "proving status", status)
}

View File

@@ -90,9 +90,10 @@ func testL2RelayerProcessCommittedBatches(t *testing.T) {
statuses, err := batchOrm.GetRollupStatusByHashList(context.Background(), []string{batch.Hash})
assert.NoError(t, err)
assert.Equal(t, 1, len(statuses))
// no valid proof, rollup status remains the same
assert.Equal(t, types.RollupCommitted, statuses[0])
assert.Equal(t, types.RollupFinalizeFailed, statuses[0])
err = batchOrm.UpdateRollupStatus(context.Background(), batch.Hash, types.RollupCommitted)
assert.NoError(t, err)
proof := &message.BatchProof{
Proof: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
}

View File

@@ -56,13 +56,13 @@ contract MockBridgeL1 {
/// @notice Emitted when a new batch is committed.
/// @param batchHash The hash of the batch.
event CommitBatch(uint256 indexed batchIndex, bytes32 indexed batchHash);
event CommitBatch(bytes32 indexed batchHash);
/// @notice Emitted when a batch is finalized.
/// @param batchHash The hash of the batch
/// @param stateRoot The state root on layer 2 after this batch.
/// @param withdrawRoot The merkle root on layer2 after this batch.
event FinalizeBatch(uint256 indexed batchIndex, bytes32 indexed batchHash, bytes32 stateRoot, bytes32 withdrawRoot);
event FinalizeBatch(bytes32 indexed batchHash, bytes32 stateRoot, bytes32 withdrawRoot);
/***********
* Structs *
@@ -130,7 +130,7 @@ contract MockBridgeL1 {
function commitBatch(
uint8 /*version*/,
bytes calldata _parentBatchHeader,
bytes calldata /*parentBatchHeader*/,
bytes[] memory chunks,
bytes calldata /*skippedL1MessageBitmap*/
) external {
@@ -138,17 +138,6 @@ contract MockBridgeL1 {
uint256 _chunksLength = chunks.length;
require(_chunksLength > 0, "batch is empty");
// decode batch index
uint256 headerLength = _parentBatchHeader.length;
uint256 parentBatchPtr;
uint256 parentBatchIndex;
assembly {
parentBatchPtr := mload(0x40)
calldatacopy(parentBatchPtr, _parentBatchHeader.offset, headerLength)
mstore(0x40, add(parentBatchPtr, headerLength))
parentBatchIndex := shr(192, mload(add(parentBatchPtr, 1)))
}
uint256 dataPtr;
assembly {
dataPtr := mload(0x40)
@@ -180,29 +169,18 @@ contract MockBridgeL1 {
}
bytes32 _batchHash = BatchHeaderV0Codec.computeBatchHash(batchPtr, 89);
committedBatches[0] = _batchHash;
emit CommitBatch(parentBatchIndex + 1, _batchHash);
emit CommitBatch(_batchHash);
}
function finalizeBatchWithProof(
bytes calldata batchHeader,
bytes calldata /*batchHeader*/,
bytes32 /*prevStateRoot*/,
bytes32 postStateRoot,
bytes32 withdrawRoot,
bytes calldata /*aggrProof*/
) external {
// decode batch index
uint256 headerLength = batchHeader.length;
uint256 batchPtr;
uint256 batchIndex;
assembly {
batchPtr := mload(0x40)
calldatacopy(batchPtr, batchHeader.offset, headerLength)
mstore(0x40, add(batchPtr, headerLength))
batchIndex := shr(192, mload(add(batchPtr, 1)))
}
bytes32 _batchHash = committedBatches[0];
emit FinalizeBatch(batchIndex, _batchHash, postStateRoot, withdrawRoot);
emit FinalizeBatch(_batchHash, postStateRoot, withdrawRoot);
}
/**********************

View File

@@ -1,31 +0,0 @@
# Download Go dependencies
FROM scrolltech/go-alpine-builder:1.19 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/
COPY ./prover-stats-api/go.* ./prover-stats-api/
COPY ./prover/go.* ./prover/
COPY ./tests/integration-test/go.* ./tests/integration-test/
COPY ./bridge-history-api/go.* ./bridge-history-api/
# Support mainland environment.
#ENV GOPROXY="https://goproxy.cn,direct"
RUN go mod download -x
# Build prover-stats-api
FROM base as builder
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
cd /src/prover-stats-api/cmd/ && go build -v -p 4 -o /bin/prover-stats-api
# Pull prover-stats-api into a second stage deploy alpine container \
FROM alpine:latest
COPY --from=builder /bin/prover-stats-api /bin/
ENTRYPOINT ["prover-stats-api"]

View File

@@ -83,9 +83,7 @@ func (c *Cmd) Write(data []byte) (int, error) {
out := string(data)
if verbose || c.openLog {
fmt.Printf("%s:\n\t%v", c.name, out)
} else if strings.Contains(strings.ToLower(out), "error") ||
strings.Contains(strings.ToLower(out), "warning") ||
strings.Contains(strings.ToLower(out), "info") {
} else if strings.Contains(strings.ToLower(out), "error") || strings.Contains(strings.ToLower(out), "warning") || strings.Contains(strings.ToLower(out), "info") {
fmt.Printf("%s:\n\t%v", c.name, out)
}
go c.checkFuncs.IterCb(func(_ string, value interface{}) {

View File

@@ -32,7 +32,7 @@ dependencies = [
[[package]]
name = "aggregator"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"ark-std",
"env_logger 0.10.0",
@@ -432,7 +432,7 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "bus-mapping"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"eth-types",
"ethers-core",
@@ -630,12 +630,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "convert_case"
version = "0.6.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8"
[[package]]
name = "core-foundation-sys"
@@ -1048,7 +1045,7 @@ dependencies = [
[[package]]
name = "eth-types"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"ethers-core",
"ethers-signers",
@@ -1141,12 +1138,13 @@ dependencies = [
[[package]]
name = "ethers-core"
version = "0.17.0"
source = "git+https://github.com/scroll-tech/ethers-rs.git?branch=v0.17.0#739ec9a0df8daf536937739c87e85612bd73212f"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ebdd63c828f58aa067f40f9adcbea5e114fb1f90144b3a1e2858e0c9b1ff4e8"
dependencies = [
"arrayvec",
"bytes",
"chrono",
"convert_case 0.6.0",
"convert_case 0.5.0",
"elliptic-curve",
"ethabi",
"fastrlp",
@@ -1225,7 +1223,7 @@ dependencies = [
[[package]]
name = "external-tracer"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"eth-types",
"geth-utils",
@@ -1438,7 +1436,7 @@ dependencies = [
[[package]]
name = "gadgets"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"digest 0.7.6",
"eth-types",
@@ -1478,7 +1476,7 @@ dependencies = [
[[package]]
name = "geth-utils"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"env_logger 0.9.3",
"gobuild 0.1.0-alpha.2 (git+https://github.com/scroll-tech/gobuild.git)",
@@ -2076,7 +2074,7 @@ dependencies = [
[[package]]
name = "keccak256"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"env_logger 0.9.3",
"eth-types",
@@ -2263,7 +2261,7 @@ dependencies = [
[[package]]
name = "mock"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"eth-types",
"ethers-core",
@@ -2278,7 +2276,7 @@ dependencies = [
[[package]]
name = "mpt-zktrie"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"bus-mapping",
"eth-types",
@@ -2754,7 +2752,7 @@ dependencies = [
[[package]]
name = "prover"
version = "0.4.0"
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.5.10#cb8f71475e6aa9fc78a24a832369fecb1c7d2201"
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.5.1#15aac6e1484a42f723098fbc9d8783f374e7e90a"
dependencies = [
"aggregator",
"anyhow",
@@ -3623,7 +3621,7 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "snark-verifier"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#12c306ec57849921e690221b10b8a08189868d4a"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#f8bdcbee60348e5c996c04f19ff30522e6b276b0"
dependencies = [
"bytes",
"ethereum-types 0.14.1",
@@ -3647,7 +3645,7 @@ dependencies = [
[[package]]
name = "snark-verifier-sdk"
version = "0.0.1"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#12c306ec57849921e690221b10b8a08189868d4a"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#f8bdcbee60348e5c996c04f19ff30522e6b276b0"
dependencies = [
"bincode",
"env_logger 0.10.0",
@@ -4039,7 +4037,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "types"
version = "0.4.0"
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.5.10#cb8f71475e6aa9fc78a24a832369fecb1c7d2201"
source = "git+https://github.com/scroll-tech/scroll-prover?tag=v0.5.1#15aac6e1484a42f723098fbc9d8783f374e7e90a"
dependencies = [
"base64 0.13.1",
"blake2",
@@ -4084,12 +4082,6 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-xid"
version = "0.2.4"
@@ -4490,7 +4482,7 @@ checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
[[package]]
name = "zkevm-circuits"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.5.10#87cae118ffdcf3a085a7c3c24268f7a0df21fcd4"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=develop#2855c13b5d3e6ec4056f823f56a33bf25d0080bb"
dependencies = [
"array-init",
"bus-mapping",

View File

@@ -7,8 +7,6 @@ edition = "2021"
[lib]
crate-type = ["cdylib"]
[patch.crates-io]
ethers-core = { git = "https://github.com/scroll-tech/ethers-rs.git", branch = "v0.17.0" }
[patch."https://github.com/privacy-scaling-explorations/halo2.git"]
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "develop" }
[patch."https://github.com/privacy-scaling-explorations/poseidon.git"]
@@ -20,8 +18,8 @@ maingate = { git = "https://github.com/scroll-tech/halo2wrong", branch = "halo2-
halo2curves = { git = "https://github.com/scroll-tech/halo2curves.git", branch = "0.3.1-derive-serde" }
[dependencies]
prover = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.5.10" }
types = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.5.10" }
prover = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.5.1" }
types = { git = "https://github.com/scroll-tech/scroll-prover", tag = "v0.5.1" }
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "develop" }
log = "0.4"
@@ -35,6 +33,8 @@ once_cell = "1.8.0"
[profile.test]
opt-level = 3
# debug-assertions = true
[profile.release]
opt-level = 3
# debug-assertions = true

View File

@@ -169,7 +169,7 @@ func TestBatchHeaderEncode(t *testing.T) {
assert.NotNil(t, batchHeader)
bytes = batchHeader.Encode()
assert.Equal(t, 121, len(bytes))
assert.Equal(t, "010000000000000001000000000000000b000000000000000b34f419ce7e882295bdb5aec6cce56ffa788a5fed4744d7fbd77e4acbf409f1ca4136709aabc8a23aa17fbcc833da2f7857d3c2884feec9aae73429c135f9498500000000000000000000000000000000000000000000000000000000000003ff", common.Bytes2Hex(bytes))
assert.Equal(t, "010000000000000001000000000000000b000000000000000b457a9e90e8e51ba2de2f66c6b589540b88cf594dac7fa7d04b99cdcfecf24e384136709aabc8a23aa17fbcc833da2f7857d3c2884feec9aae73429c135f9498500000000000000000000000000000000000000000000000000000000000003ff", common.Bytes2Hex(bytes))
}
func TestBatchHeaderHash(t *testing.T) {
@@ -230,7 +230,7 @@ func TestBatchHeaderHash(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, batchHeader)
hash = batchHeader.Hash()
assert.Equal(t, "1c3007880f0eafe74572ede7d164ff1ee5376e9ac9bff6f7fb837b2630cddc9a", common.Bytes2Hex(hash.Bytes()))
assert.Equal(t, "0ec9547c6645d5f0c1254e121f49e93f54525cfda5bfb2236440fb3470f48902", common.Bytes2Hex(hash.Bytes()))
}
func TestBatchHeaderDecode(t *testing.T) {

View File

@@ -36,17 +36,6 @@ func (w *WrappedBlock) NumL1Messages(totalL1MessagePoppedBefore uint64) uint64 {
return *lastQueueIndex - totalL1MessagePoppedBefore + 1
}
// NumL2Transactions returns the number of L2 transactions in this block.
func (w *WrappedBlock) NumL2Transactions() uint64 {
var count uint64
for _, txData := range w.Transactions {
if txData.Type != types.L1MessageTxType {
count++
}
}
return count
}
// Encode encodes the WrappedBlock into RollupV2 BlockContext Encoding.
func (w *WrappedBlock) Encode(totalL1MessagePoppedBefore uint64) ([]byte, error) {
bytes := make([]byte, 60)
@@ -54,25 +43,20 @@ func (w *WrappedBlock) Encode(totalL1MessagePoppedBefore uint64) ([]byte, error)
if !w.Header.Number.IsUint64() {
return nil, errors.New("block number is not uint64")
}
if len(w.Transactions) > math.MaxUint16 {
return nil, errors.New("number of transactions exceeds max uint16")
}
// note: numL1Messages includes skipped messages
numL1Messages := w.NumL1Messages(totalL1MessagePoppedBefore)
if numL1Messages > math.MaxUint16 {
return nil, errors.New("number of L1 messages exceeds max uint16")
}
// note: numTransactions includes skipped messages
numL2Transactions := w.NumL2Transactions()
numTransactions := numL1Messages + numL2Transactions
if numTransactions > math.MaxUint16 {
return nil, errors.New("number of transactions exceeds max uint16")
}
binary.BigEndian.PutUint64(bytes[0:], w.Header.Number.Uint64())
binary.BigEndian.PutUint64(bytes[8:], w.Header.Time)
// TODO: [16:47] Currently, baseFee is 0, because we disable EIP-1559.
binary.BigEndian.PutUint64(bytes[48:], w.Header.GasLimit)
binary.BigEndian.PutUint16(bytes[56:], uint16(numTransactions))
binary.BigEndian.PutUint16(bytes[56:], uint16(len(w.Transactions)))
binary.BigEndian.PutUint16(bytes[58:], uint16(numL1Messages))
return bytes, nil

View File

@@ -65,10 +65,9 @@ func TestChunkEncode(t *testing.T) {
hexString = hex.EncodeToString(bytes)
assert.NoError(t, err)
assert.Equal(t, 97, len(bytes))
assert.Equal(t, "01000000000000000d00000000646b6e13000000000000000000000000000000000000000000000000000000000000000000000000007a1200000c000b00000020df0b80825dc0941a258d17bf244c4df02d40343a7626a9d321e1058080808080", hexString)
assert.Equal(t, "01000000000000000d00000000646b6e13000000000000000000000000000000000000000000000000000000000000000000000000007a12000002000b00000020df0b80825dc0941a258d17bf244c4df02d40343a7626a9d321e1058080808080", hexString)
// Test case 5: when the chunk contains two blocks each with 1 L1MsgTx
// TODO: revise this test, we cannot reuse the same L1MsgTx twice
chunk = &Chunk{
Blocks: []*WrappedBlock{
wrappedBlock2,
@@ -79,7 +78,7 @@ func TestChunkEncode(t *testing.T) {
hexString = hex.EncodeToString(bytes)
assert.NoError(t, err)
assert.Equal(t, 193, len(bytes))
assert.Equal(t, "02000000000000000d00000000646b6e13000000000000000000000000000000000000000000000000000000000000000000000000007a1200000c000b000000000000000d00000000646b6e13000000000000000000000000000000000000000000000000000000000000000000000000007a12000001000000000020df0b80825dc0941a258d17bf244c4df02d40343a7626a9d321e105808080808000000020df0b80825dc0941a258d17bf244c4df02d40343a7626a9d321e1058080808080", hexString)
assert.Equal(t, "02000000000000000d00000000646b6e13000000000000000000000000000000000000000000000000000000000000000000000000007a12000002000b000000000000000d00000000646b6e13000000000000000000000000000000000000000000000000000000000000000000000000007a12000002000000000020df0b80825dc0941a258d17bf244c4df02d40343a7626a9d321e105808080808000000020df0b80825dc0941a258d17bf244c4df02d40343a7626a9d321e1058080808080", hexString)
}
func TestChunkHash(t *testing.T) {
@@ -134,5 +133,5 @@ func TestChunkHash(t *testing.T) {
}
hash, err = chunk.Hash(0)
assert.NoError(t, err)
assert.Equal(t, "0x2eb7dd63bf8fc29a0f8c10d16c2ae6f9da446907c79d50f5c164d30dc8526b60", hash.Hex())
assert.Equal(t, "0x42967825696a129e7a83f082097aca982747480956dcaa448c9296e795c9a91a", hash.Hex())
}

View File

@@ -33,7 +33,7 @@ func (r ProofType) String() string {
case ProofTypeBatch:
return "proof type batch"
default:
return fmt.Sprintf("illegal proof type: %d", r)
return "illegal proof type"
}
}
@@ -60,8 +60,6 @@ type AuthMsg struct {
type Identity struct {
// ProverName the prover name
ProverName string `json:"prover_name"`
// ProverVersion the prover version
ProverVersion string `json:"prover_version"`
// Challenge unique challenge generated by manager
Challenge string `json:"challenge"`
}

View File

@@ -15,9 +15,8 @@ func TestAuthMessageSignAndVerify(t *testing.T) {
authMsg := &AuthMsg{
Identity: &Identity{
Challenge: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTEwMzgxNzUsIm9yaWdfaWF0IjoxNjkxMDM0NTc1fQ.HybBMsEJFhyZqtIa2iVcHUP7CEFttf708jmTMAImAWA",
ProverName: "test",
ProverVersion: "v1.0.0",
Challenge: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTEwMzgxNzUsIm9yaWdfaWF0IjoxNjkxMDM0NTc1fQ.HybBMsEJFhyZqtIa2iVcHUP7CEFttf708jmTMAImAWA",
ProverName: "test",
},
}
assert.NoError(t, authMsg.SignWithKey(privkey))
@@ -46,15 +45,14 @@ func TestGenerateToken(t *testing.T) {
func TestIdentityHash(t *testing.T) {
identity := &Identity{
Challenge: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTEwMzM0MTksIm9yaWdfaWF0IjoxNjkxMDI5ODE5fQ.EhkLZsj__rNPVC3ZDYBtvdh0nB8mmM_Hl82hObaIWOs",
ProverName: "test",
ProverVersion: "v1.0.0",
Challenge: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTEwMzM0MTksIm9yaWdfaWF0IjoxNjkxMDI5ODE5fQ.EhkLZsj__rNPVC3ZDYBtvdh0nB8mmM_Hl82hObaIWOs",
ProverName: "test",
}
hash, err := identity.Hash()
assert.NoError(t, err)
expectedHash := "83f5e0ad023e9c1de639ab07b9b4cb972ec9dbbd2524794c533a420a5b137721"
expectedHash := "7373bb57ab7c01307d86fec55e088e00c526d82d9d1303fa4a189ff6ea95fbe2"
assert.Equal(t, expectedHash, hex.EncodeToString(hash))
}
@@ -118,7 +116,7 @@ func TestProveTypeString(t *testing.T) {
assert.Equal(t, "proof type batch", proofTypeBatch.String())
illegalProof := ProofType(3)
assert.Equal(t, "illegal proof type: 3", illegalProof.String())
assert.Equal(t, "illegal proof type", illegalProof.String())
}
func TestProofMsgPublicKey(t *testing.T) {

View File

@@ -5,7 +5,7 @@ import (
"runtime/debug"
)
var tag = "v4.1.26"
var tag = "v4.1.1"
var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {

View File

@@ -533,7 +533,7 @@ Emitted when some ERC1155 token is refunded.
### UpdateTokenMapping
```solidity
event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token)
event UpdateTokenMapping(address _l1Token, address _l2Token)
```
Emitted when token mapping for ERC1155 token is updated.
@@ -544,9 +544,8 @@ Emitted when token mapping for ERC1155 token is updated.
| Name | Type | Description |
|---|---|---|
| l1Token `indexed` | address | The address of ERC1155 token in layer 1. |
| oldL2Token `indexed` | address | The address of the old corresponding ERC1155 token in layer 2. |
| newL2Token `indexed` | address | The address of the new corresponding ERC1155 token in layer 2. |
| _l1Token | address | The address of ERC1155 token on layer 1. |
| _l2Token | address | The address of corresponding ERC1155 token on layer 2. |

View File

@@ -472,7 +472,7 @@ Emitted when some ERC721 token is refunded.
### UpdateTokenMapping
```solidity
event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token)
event UpdateTokenMapping(address _l1Token, address _l2Token)
```
Emitted when token mapping for ERC721 token is updated.
@@ -483,9 +483,8 @@ Emitted when token mapping for ERC721 token is updated.
| Name | Type | Description |
|---|---|---|
| l1Token `indexed` | address | The address of ERC721 token in layer 1. |
| oldL2Token `indexed` | address | The address of the old corresponding ERC721 token in layer 2. |
| newL2Token `indexed` | address | The address of the new corresponding ERC721 token in layer 2. |
| _l1Token | address | The address of ERC721 token on layer 1. |
| _l2Token | address | The address of corresponding ERC721 token on layer 2. |

View File

@@ -350,7 +350,7 @@ Request ERC20 token transfer from users to gateways.
### setDefaultERC20Gateway
```solidity
function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external nonpayable
function setDefaultERC20Gateway(address _defaultERC20Gateway) external nonpayable
```
Update the address of default ERC20 gateway contract.
@@ -361,7 +361,7 @@ Update the address of default ERC20 gateway contract.
| Name | Type | Description |
|---|---|---|
| _newDefaultERC20Gateway | address | undefined |
| _defaultERC20Gateway | address | The address to update. |
### setERC20Gateway
@@ -383,7 +383,7 @@ Update the mapping from token address to gateway address.
### setETHGateway
```solidity
function setETHGateway(address _newEthGateway) external nonpayable
function setETHGateway(address _ethGateway) external nonpayable
```
Update the address of ETH gateway contract.
@@ -394,7 +394,7 @@ Update the address of ETH gateway contract.
| Name | Type | Description |
|---|---|---|
| _newEthGateway | address | undefined |
| _ethGateway | address | The address to update. |
### transferOwnership
@@ -567,7 +567,7 @@ Emitted when some ETH is refunded.
### SetDefaultERC20Gateway
```solidity
event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway)
event SetDefaultERC20Gateway(address indexed defaultERC20Gateway)
```
Emitted when the address of default ERC20 Gateway is updated.
@@ -578,13 +578,12 @@ Emitted when the address of default ERC20 Gateway is updated.
| Name | Type | Description |
|---|---|---|
| oldDefaultERC20Gateway `indexed` | address | undefined |
| newDefaultERC20Gateway `indexed` | address | undefined |
| defaultERC20Gateway `indexed` | address | undefined |
### SetERC20Gateway
```solidity
event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway)
event SetERC20Gateway(address indexed token, address indexed gateway)
```
Emitted when the `gateway` for `token` is updated.
@@ -596,13 +595,12 @@ Emitted when the `gateway` for `token` is updated.
| Name | Type | Description |
|---|---|---|
| token `indexed` | address | undefined |
| oldGateway `indexed` | address | undefined |
| newGateway `indexed` | address | undefined |
| gateway `indexed` | address | undefined |
### SetETHGateway
```solidity
event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway)
event SetETHGateway(address indexed ethGateway)
```
Emitted when the address of ETH Gateway is updated.
@@ -613,8 +611,7 @@ Emitted when the address of ETH Gateway is updated.
| Name | Type | Description |
|---|---|---|
| oldETHGateway `indexed` | address | undefined |
| newEthGateway `indexed` | address | undefined |
| ethGateway `indexed` | address | undefined |

View File

@@ -423,7 +423,7 @@ Update fee vault contract.
### updateMaxReplayTimes
```solidity
function updateMaxReplayTimes(uint256 _newMaxReplayTimes) external nonpayable
function updateMaxReplayTimes(uint256 _maxReplayTimes) external nonpayable
```
Update max replay times.
@@ -434,7 +434,7 @@ Update max replay times.
| Name | Type | Description |
|---|---|---|
| _newMaxReplayTimes | uint256 | The new max replay times. |
| _maxReplayTimes | uint256 | The new max replay times. |
### xDomainMessageSender
@@ -595,7 +595,7 @@ Emitted when owner updates fee vault contract.
### UpdateMaxReplayTimes
```solidity
event UpdateMaxReplayTimes(uint256 oldMaxReplayTimes, uint256 newMaxReplayTimes)
event UpdateMaxReplayTimes(uint256 maxReplayTimes)
```
Emitted when the maximum number of times each message can be replayed is updated.
@@ -606,8 +606,7 @@ Emitted when the maximum number of times each message can be replayed is updated
| Name | Type | Description |
|---|---|---|
| oldMaxReplayTimes | uint256 | undefined |
| newMaxReplayTimes | uint256 | undefined |
| maxReplayTimes | uint256 | undefined |

View File

@@ -214,34 +214,6 @@ function onDropMessage(bytes _message) external payable
|---|---|---|
| _message | bytes | undefined |
### owner
```solidity
function owner() external view returns (address)
```
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### renounceOwnership
```solidity
function renounceOwnership() external nonpayable
```
*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.*
### router
```solidity
@@ -259,22 +231,6 @@ The address of L1GatewayRouter/L2GatewayRouter contract.
|---|---|---|
| _0 | address | undefined |
### transferOwnership
```solidity
function transferOwnership(address newOwner) external nonpayable
```
*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| newOwner | address | undefined |
## Events
@@ -337,23 +293,6 @@ event Initialized(uint8 version)
|---|---|---|
| version | uint8 | undefined |
### OwnershipTransferred
```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### RefundERC20
```solidity

View File

@@ -212,34 +212,6 @@ function onDropMessage(bytes _message) external payable
|---|---|---|
| _message | bytes | undefined |
### owner
```solidity
function owner() external view returns (address)
```
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### renounceOwnership
```solidity
function renounceOwnership() external nonpayable
```
*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.*
### router
```solidity
@@ -257,22 +229,6 @@ The address of L1GatewayRouter/L2GatewayRouter contract.
|---|---|---|
| _0 | address | undefined |
### transferOwnership
```solidity
function transferOwnership(address newOwner) external nonpayable
```
*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| newOwner | address | undefined |
## Events
@@ -335,23 +291,6 @@ event Initialized(uint8 version)
|---|---|---|
| version | uint8 | undefined |
### OwnershipTransferred
```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### RefundERC20
```solidity

View File

@@ -458,7 +458,7 @@ event OwnershipTransferred(address indexed previousOwner, address indexed newOwn
### UpdateTokenMapping
```solidity
event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token)
event UpdateTokenMapping(address _l2Token, address _l1Token)
```
Emitted when token mapping for ERC1155 token is updated.
@@ -469,9 +469,8 @@ Emitted when token mapping for ERC1155 token is updated.
| Name | Type | Description |
|---|---|---|
| l2Token `indexed` | address | The address of corresponding ERC1155 token in layer 2. |
| oldL1Token `indexed` | address | The address of the old corresponding ERC1155 token in layer 1. |
| newL1Token `indexed` | address | The address of the new corresponding ERC1155 token in layer 1. |
| _l2Token | address | The address of corresponding ERC1155 token on layer 2. |
| _l1Token | address | The address of ERC1155 token on layer 1. |
### WithdrawERC1155

View File

@@ -400,7 +400,7 @@ event OwnershipTransferred(address indexed previousOwner, address indexed newOwn
### UpdateTokenMapping
```solidity
event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token)
event UpdateTokenMapping(address _l2Token, address _l1Token)
```
Emitted when token mapping for ERC721 token is updated.
@@ -411,9 +411,8 @@ Emitted when token mapping for ERC721 token is updated.
| Name | Type | Description |
|---|---|---|
| l2Token `indexed` | address | The address of corresponding ERC721 token in layer 2. |
| oldL1Token `indexed` | address | The address of the old corresponding ERC721 token in layer 1. |
| newL1Token `indexed` | address | The address of the new corresponding ERC721 token in layer 1. |
| _l2Token | address | The address of corresponding ERC721 token on layer 2. |
| _l1Token | address | The address of ERC721 token on layer 1. |
### WithdrawERC721

View File

@@ -220,7 +220,7 @@ function renounceOwnership() external nonpayable
### setDefaultERC20Gateway
```solidity
function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external nonpayable
function setDefaultERC20Gateway(address _defaultERC20Gateway) external nonpayable
```
Update the address of default ERC20 gateway contract.
@@ -231,7 +231,7 @@ Update the address of default ERC20 gateway contract.
| Name | Type | Description |
|---|---|---|
| _newDefaultERC20Gateway | address | The address to update. |
| _defaultERC20Gateway | address | The address to update. |
### setERC20Gateway
@@ -253,7 +253,7 @@ Update the mapping from token address to gateway address.
### setETHGateway
```solidity
function setETHGateway(address _newEthGateway) external nonpayable
function setETHGateway(address _ethGateway) external nonpayable
```
Update the address of ETH gateway contract.
@@ -264,7 +264,7 @@ Update the address of ETH gateway contract.
| Name | Type | Description |
|---|---|---|
| _newEthGateway | address | The address to update. |
| _ethGateway | address | The address to update. |
### transferOwnership
@@ -473,7 +473,7 @@ event OwnershipTransferred(address indexed previousOwner, address indexed newOwn
### SetDefaultERC20Gateway
```solidity
event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway)
event SetDefaultERC20Gateway(address indexed defaultERC20Gateway)
```
Emitted when the address of default ERC20 Gateway is updated.
@@ -484,13 +484,12 @@ Emitted when the address of default ERC20 Gateway is updated.
| Name | Type | Description |
|---|---|---|
| oldDefaultERC20Gateway `indexed` | address | undefined |
| newDefaultERC20Gateway `indexed` | address | undefined |
| defaultERC20Gateway `indexed` | address | undefined |
### SetERC20Gateway
```solidity
event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway)
event SetERC20Gateway(address indexed token, address indexed gateway)
```
Emitted when the `gateway` for `token` is updated.
@@ -502,13 +501,12 @@ Emitted when the `gateway` for `token` is updated.
| Name | Type | Description |
|---|---|---|
| token `indexed` | address | undefined |
| oldGateway `indexed` | address | undefined |
| newGateway `indexed` | address | undefined |
| gateway `indexed` | address | undefined |
### SetETHGateway
```solidity
event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway)
event SetETHGateway(address indexed ethGateway)
```
Emitted when the address of ETH Gateway is updated.
@@ -519,8 +517,7 @@ Emitted when the address of ETH Gateway is updated.
| Name | Type | Description |
|---|---|---|
| oldETHGateway `indexed` | address | undefined |
| newEthGateway `indexed` | address | undefined |
| ethGateway `indexed` | address | undefined |
### WithdrawERC20

View File

@@ -47,7 +47,7 @@ The address of fee vault, collecting cross domain messaging fee.
### initialize
```solidity
function initialize(address _counterpart) external nonpayable
function initialize(address _counterpart, address _feeVault) external nonpayable
```
@@ -59,6 +59,7 @@ function initialize(address _counterpart) external nonpayable
| Name | Type | Description |
|---|---|---|
| _counterpart | address | undefined |
| _feeVault | address | undefined |
### isL1MessageExecuted
@@ -315,7 +316,7 @@ Update fee vault contract.
### updateMaxFailedExecutionTimes
```solidity
function updateMaxFailedExecutionTimes(uint256 _newMaxFailedExecutionTimes) external nonpayable
function updateMaxFailedExecutionTimes(uint256 _maxFailedExecutionTimes) external nonpayable
```
Update max failed execution times.
@@ -326,7 +327,7 @@ Update max failed execution times.
| Name | Type | Description |
|---|---|---|
| _newMaxFailedExecutionTimes | uint256 | The new max failed execution times. |
| _maxFailedExecutionTimes | uint256 | The new max failed execution times. |
### xDomainMessageSender
@@ -487,7 +488,7 @@ Emitted when owner updates fee vault contract.
### UpdateMaxFailedExecutionTimes
```solidity
event UpdateMaxFailedExecutionTimes(uint256 oldMaxFailedExecutionTimes, uint256 newMaxFailedExecutionTimes)
event UpdateMaxFailedExecutionTimes(uint256 maxFailedExecutionTimes)
```
Emitted when the maximum number of times each message can fail in L2 is updated.
@@ -498,8 +499,7 @@ Emitted when the maximum number of times each message can fail in L2 is updated.
| Name | Type | Description |
|---|---|---|
| oldMaxFailedExecutionTimes | uint256 | undefined |
| newMaxFailedExecutionTimes | uint256 | undefined |
| maxFailedExecutionTimes | uint256 | The new maximum number of times each message can fail in L2. |

View File

@@ -128,34 +128,6 @@ The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract.
|---|---|---|
| _0 | address | undefined |
### owner
```solidity
function owner() external view returns (address)
```
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### renounceOwnership
```solidity
function renounceOwnership() external nonpayable
```
*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.*
### router
```solidity
@@ -190,22 +162,6 @@ The address of ScrollStandardERC20Factory.
|---|---|---|
| _0 | address | undefined |
### transferOwnership
```solidity
function transferOwnership(address newOwner) external nonpayable
```
*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| newOwner | address | undefined |
### withdrawERC20
```solidity
@@ -304,23 +260,6 @@ event Initialized(uint8 version)
|---|---|---|
| version | uint8 | undefined |
### OwnershipTransferred
```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### WithdrawERC20
```solidity

View File

@@ -161,34 +161,6 @@ The address of corresponding L1ScrollMessenger/L2ScrollMessenger contract.
|---|---|---|
| _0 | address | undefined |
### owner
```solidity
function owner() external view returns (address)
```
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### renounceOwnership
```solidity
function renounceOwnership() external nonpayable
```
*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.*
### router
```solidity
@@ -206,22 +178,6 @@ The address of L1GatewayRouter/L2GatewayRouter contract.
|---|---|---|
| _0 | address | undefined |
### transferOwnership
```solidity
function transferOwnership(address newOwner) external nonpayable
```
*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| newOwner | address | undefined |
### withdrawERC20
```solidity
@@ -320,23 +276,6 @@ event Initialized(uint8 version)
|---|---|---|
| version | uint8 | undefined |
### OwnershipTransferred
```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### WithdrawERC20
```solidity

View File

@@ -1,6 +1,7 @@
/* eslint-disable node/no-unpublished-import */
/* eslint-disable node/no-missing-import */
import { constants } from "ethers";
import { concat } from "ethers/lib/utils";
import { ethers } from "hardhat";
import { ScrollChain, L1MessageQueue } from "../typechain";
@@ -27,7 +28,7 @@ describe("ScrollChain", async () => {
await chain.deployed();
await chain.initialize(queue.address, constants.AddressZero, 44);
await chain.addSequencer(deployer.address);
await chain.updateSequencer(deployer.address, true);
await queue.initialize(
constants.AddressZero,
chain.address,

View File

@@ -22,7 +22,6 @@ contract InitializeL1BridgeContracts is Script {
uint256 CHAIN_ID_L2 = vm.envUint("CHAIN_ID_L2");
uint256 MAX_L2_TX_IN_CHUNK = vm.envUint("MAX_L2_TX_IN_CHUNK");
uint256 MAX_L1_MESSAGE_GAS_LIMIT = vm.envUint("MAX_L1_MESSAGE_GAS_LIMIT");
address L1_ROLLUP_OPERATOR_ADDR = vm.envAddress("L1_ROLLUP_OPERATOR_ADDR");
address L1_FEE_VAULT_ADDR = vm.envAddress("L1_FEE_VAULT_ADDR");
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
@@ -67,8 +66,8 @@ contract InitializeL1BridgeContracts is Script {
L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR,
MAX_L2_TX_IN_CHUNK
);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_ROLLUP_OPERATOR_ADDR);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_ROLLUP_OPERATOR_ADDR);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).updateSequencer(L1_ROLLUP_OPERATOR_ADDR, true);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).updateProver(L1_ROLLUP_OPERATOR_ADDR, true);
// initialize L2GasPriceOracle
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize(
@@ -85,7 +84,7 @@ contract InitializeL1BridgeContracts is Script {
L1_SCROLL_CHAIN_PROXY_ADDR,
L1_ENFORCED_TX_GATEWAY_PROXY_ADDR,
L2_GAS_PRICE_ORACLE_PROXY_ADDR,
MAX_L1_MESSAGE_GAS_LIMIT
10000000
);
// initialize L1ScrollMessenger

View File

@@ -65,7 +65,10 @@ contract InitializeL2BridgeContracts is Script {
L1GasPriceOracle(L1_GAS_PRICE_ORACLE_ADDR).updateWhitelist(L2_WHITELIST_ADDR);
// initialize L2ScrollMessenger
L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).initialize(L1_SCROLL_MESSENGER_PROXY_ADDR);
L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_TX_FEE_VAULT_ADDR
);
// initialize L2GatewayRouter
L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).initialize(

View File

@@ -10,9 +10,8 @@ interface IL1ScrollMessenger is IScrollMessenger {
**********/
/// @notice Emitted when the maximum number of times each message can be replayed is updated.
/// @param oldMaxReplayTimes The old maximum number of times each message can be replayed.
/// @param newMaxReplayTimes The new maximum number of times each message can be replayed.
event UpdateMaxReplayTimes(uint256 oldMaxReplayTimes, uint256 newMaxReplayTimes);
/// @param maxReplayTimes The new maximum number of times each message can be replayed.
event UpdateMaxReplayTimes(uint256 maxReplayTimes);
/***********
* Structs *

View File

@@ -2,12 +2,15 @@
pragma solidity =0.8.16;
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {IScrollChain} from "./rollup/IScrollChain.sol";
import {IL1MessageQueue} from "./rollup/IL1MessageQueue.sol";
import {IL1ScrollMessenger} from "./IL1ScrollMessenger.sol";
import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol";
import {IScrollMessenger} from "../libraries/IScrollMessenger.sol";
import {ScrollMessengerBase} from "../libraries/ScrollMessengerBase.sol";
import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol";
import {WithdrawTrieVerifier} from "../libraries/verifier/WithdrawTrieVerifier.sol";
import {IMessageDropCallback} from "../libraries/callbacks/IMessageDropCallback.sol";
@@ -25,7 +28,7 @@ import {IMessageDropCallback} from "../libraries/callbacks/IMessageDropCallback.
///
/// @dev All deposited Ether (including `WETH` deposited throng `L1WETHGateway`) will locked in
/// this contract.
contract L1ScrollMessenger is ScrollMessengerBase, IL1ScrollMessenger {
contract L1ScrollMessenger is PausableUpgradeable, ScrollMessengerBase, IL1ScrollMessenger {
/***********
* Structs *
***********/
@@ -94,7 +97,8 @@ contract L1ScrollMessenger is ScrollMessengerBase, IL1ScrollMessenger {
address _rollup,
address _messageQueue
) public initializer {
ScrollMessengerBase.__ScrollMessengerBase_init(_counterpart, _feeVault);
PausableUpgradeable.__Pausable_init();
ScrollMessengerBase._initialize(_counterpart, _feeVault);
rollup = _rollup;
messageQueue = _messageQueue;
@@ -291,14 +295,24 @@ contract L1ScrollMessenger is ScrollMessengerBase, IL1ScrollMessenger {
* Restricted Functions *
************************/
/// @notice Pause the contract
/// @dev This function can only called by contract owner.
/// @param _status The pause status to update.
function setPause(bool _status) external onlyOwner {
if (_status) {
_pause();
} else {
_unpause();
}
}
/// @notice Update max replay times.
/// @dev This function can only called by contract owner.
/// @param _newMaxReplayTimes The new max replay times.
function updateMaxReplayTimes(uint256 _newMaxReplayTimes) external onlyOwner {
uint256 _oldMaxReplayTimes = maxReplayTimes;
maxReplayTimes = _newMaxReplayTimes;
/// @param _maxReplayTimes The new max replay times.
function updateMaxReplayTimes(uint256 _maxReplayTimes) external onlyOwner {
maxReplayTimes = _maxReplayTimes;
emit UpdateMaxReplayTimes(_oldMaxReplayTimes, _newMaxReplayTimes);
emit UpdateMaxReplayTimes(_maxReplayTimes);
}
/**********************

View File

@@ -11,20 +11,17 @@ interface IL1GatewayRouter is IL1ETHGateway, IL1ERC20Gateway {
**********/
/// @notice Emitted when the address of ETH Gateway is updated.
/// @param oldETHGateway The address of the old ETH Gateway.
/// @param newEthGateway The address of the new ETH Gateway.
event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway);
/// @param ethGateway The address of new ETH Gateway.
event SetETHGateway(address indexed ethGateway);
/// @notice Emitted when the address of default ERC20 Gateway is updated.
/// @param oldDefaultERC20Gateway The address of the old default ERC20 Gateway.
/// @param newDefaultERC20Gateway The address of the new default ERC20 Gateway.
event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway);
/// @param defaultERC20Gateway The address of new default ERC20 Gateway.
event SetDefaultERC20Gateway(address indexed defaultERC20Gateway);
/// @notice Emitted when the `gateway` for `token` is updated.
/// @param token The address of token updated.
/// @param oldGateway The corresponding address of the old gateway.
/// @param newGateway The corresponding address of the new gateway.
event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway);
/// @param gateway The corresponding address of gateway updated.
event SetERC20Gateway(address indexed token, address indexed gateway);
/*************************
* Public View Functions *

View File

@@ -2,6 +2,7 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
@@ -17,7 +18,7 @@ import {L1ERC20Gateway} from "./L1ERC20Gateway.sol";
/// finalize withdraw the tokens from layer 2.
/// @dev The deposited tokens are held in this gateway. On finalizing withdraw, the corresponding
/// tokens will be transfer to the recipient directly.
contract L1CustomERC20Gateway is L1ERC20Gateway {
contract L1CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L1ERC20Gateway {
using SafeERC20Upgradeable for IERC20Upgradeable;
/**********
@@ -25,10 +26,9 @@ contract L1CustomERC20Gateway is L1ERC20Gateway {
**********/
/// @notice Emitted when token mapping for ERC20 token is updated.
/// @param l1Token The address of ERC20 token in layer 1.
/// @param oldL2Token The address of the old corresponding ERC20 token in layer 2.
/// @param newL2Token The address of the new corresponding ERC20 token in layer 2.
event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token);
/// @param _l1Token The address of ERC20 token on layer 1.
/// @param _l2Token The address of corresponding ERC20 token on layer 2.
event UpdateTokenMapping(address _l1Token, address _l2Token);
/*************
* Variables *
@@ -56,6 +56,7 @@ contract L1CustomERC20Gateway is L1ERC20Gateway {
) external initializer {
require(_router != address(0), "zero router address");
OwnableUpgradeable.__Ownable_init();
ScrollGatewayBase._initialize(_counterpart, _router, _messenger);
}
@@ -78,10 +79,9 @@ contract L1CustomERC20Gateway is L1ERC20Gateway {
function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner {
require(_l2Token != address(0), "token address cannot be 0");
address _oldL2Token = tokenMapping[_l1Token];
tokenMapping[_l1Token] = _l2Token;
emit UpdateTokenMapping(_l1Token, _oldL2Token, _l2Token);
emit UpdateTokenMapping(_l1Token, _l2Token);
}
/**********************

View File

@@ -2,6 +2,7 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import {ERC1155HolderUpgradeable, ERC1155ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
@@ -19,16 +20,21 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// NFT will be transfer to the recipient directly.
///
/// This will be changed if we have more specific scenarios.
contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC1155Gateway, IMessageDropCallback {
contract L1ERC1155Gateway is
OwnableUpgradeable,
ERC1155HolderUpgradeable,
ScrollGatewayBase,
IL1ERC1155Gateway,
IMessageDropCallback
{
/**********
* Events *
**********/
/// @notice Emitted when token mapping for ERC1155 token is updated.
/// @param l1Token The address of ERC1155 token in layer 1.
/// @param oldL2Token The address of the old corresponding ERC1155 token in layer 2.
/// @param newL2Token The address of the new corresponding ERC1155 token in layer 2.
event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token);
/// @param _l1Token The address of ERC1155 token on layer 1.
/// @param _l2Token The address of corresponding ERC1155 token on layer 2.
event UpdateTokenMapping(address _l1Token, address _l2Token);
/*************
* Variables *
@@ -49,6 +55,7 @@ contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC
/// @param _counterpart The address of L2ERC1155Gateway in L2.
/// @param _messenger The address of L1ScrollMessenger.
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC1155HolderUpgradeable.__ERC1155Holder_init();
ERC1155ReceiverUpgradeable.__ERC1155Receiver_init();
@@ -170,10 +177,9 @@ contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC
function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner {
require(_l2Token != address(0), "token address cannot be 0");
address _oldL2Token = tokenMapping[_l1Token];
tokenMapping[_l1Token] = _l2Token;
emit UpdateTokenMapping(_l1Token, _oldL2Token, _l2Token);
emit UpdateTokenMapping(_l1Token, _l2Token);
}
/**********************

View File

@@ -2,12 +2,14 @@
pragma solidity ^0.8.16;
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol";
import {IL1GatewayRouter} from "./IL1GatewayRouter.sol";
import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol";
import {IScrollMessenger} from "../../libraries/IScrollMessenger.sol";
import {ScrollConstants} from "../../libraries/constants/ScrollConstants.sol";
@@ -17,7 +19,7 @@ import {IMessageDropCallback} from "../../libraries/callbacks/IMessageDropCallba
// solhint-disable no-empty-blocks
abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, ScrollGatewayBase {
using SafeERC20Upgradeable for IERC20Upgradeable;
using SafeERC20 for IERC20;
/*************
* Variables *
@@ -73,7 +75,7 @@ abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, Scrol
// @note can possible trigger reentrant call to this contract or messenger,
// but it seems not a big problem.
IERC20Upgradeable(_l1Token).safeTransfer(_to, _amount);
IERC20(_l1Token).safeTransfer(_to, _amount);
_doCallback(_to, _data);
@@ -94,7 +96,7 @@ abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, Scrol
// do dome check for each custom gateway
_beforeDropMessage(_token, _receiver, _amount);
IERC20Upgradeable(_token).safeTransfer(_receiver, _amount);
IERC20(_token).safeTransfer(_receiver, _amount);
emit RefundERC20(_token, _receiver, _amount);
}
@@ -152,9 +154,9 @@ abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, Scrol
_amount = IL1GatewayRouter(msg.sender).requestERC20(_from, _token, _amount);
} else {
// common practice to handle fee on transfer token.
uint256 _before = IERC20Upgradeable(_token).balanceOf(address(this));
IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount);
uint256 _after = IERC20Upgradeable(_token).balanceOf(address(this));
uint256 _before = IERC20(_token).balanceOf(address(this));
IERC20(_token).safeTransferFrom(_from, address(this), _amount);
uint256 _after = IERC20(_token).balanceOf(address(this));
// no unchecked here, since some weird token may return arbitrary balance.
_amount = _after - _before;
}

View File

@@ -2,6 +2,7 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import {ERC721HolderUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol";
@@ -19,16 +20,21 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// NFT will be transfer to the recipient directly.
///
/// This will be changed if we have more specific scenarios.
contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC721Gateway, IMessageDropCallback {
contract L1ERC721Gateway is
OwnableUpgradeable,
ERC721HolderUpgradeable,
ScrollGatewayBase,
IL1ERC721Gateway,
IMessageDropCallback
{
/**********
* Events *
**********/
/// @notice Emitted when token mapping for ERC721 token is updated.
/// @param l1Token The address of ERC721 token in layer 1.
/// @param oldL2Token The address of the old corresponding ERC721 token in layer 2.
/// @param newL2Token The address of the new corresponding ERC721 token in layer 2.
event UpdateTokenMapping(address indexed l1Token, address indexed oldL2Token, address indexed newL2Token);
/// @param _l1Token The address of ERC721 token on layer 1.
/// @param _l2Token The address of corresponding ERC721 token on layer 2.
event UpdateTokenMapping(address _l1Token, address _l2Token);
/*************
* Variables *
@@ -49,6 +55,7 @@ contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC72
/// @param _counterpart The address of L2ERC721Gateway in L2.
/// @param _messenger The address of L1ScrollMessenger.
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC721HolderUpgradeable.__ERC721Holder_init();
ScrollGatewayBase._initialize(_counterpart, address(0), _messenger);
@@ -166,10 +173,9 @@ contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC72
function updateTokenMapping(address _l1Token, address _l2Token) external onlyOwner {
require(_l2Token != address(0), "token address cannot be 0");
address _oldL2Token = tokenMapping[_l1Token];
tokenMapping[_l1Token] = _l2Token;
emit UpdateTokenMapping(_l1Token, _oldL2Token, _l2Token);
emit UpdateTokenMapping(_l1Token, _l2Token);
}
/**********************

View File

@@ -2,6 +2,8 @@
pragma solidity =0.8.16;
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {IL2ETHGateway} from "../../L2/gateways/IL2ETHGateway.sol";
import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol";
import {IL1ETHGateway} from "./IL1ETHGateway.sol";
@@ -16,7 +18,7 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// finalize withdraw ETH from layer 2.
/// @dev The deposited ETH tokens are held in this gateway. On finalizing withdraw, the corresponding
/// ETH will be transfer to the recipient directly.
contract L1ETHGateway is ScrollGatewayBase, IL1ETHGateway, IMessageDropCallback {
contract L1ETHGateway is Initializable, ScrollGatewayBase, IL1ETHGateway, IMessageDropCallback {
/***************
* Constructor *
***************/

View File

@@ -6,6 +6,8 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
import {IScrollGateway} from "../../libraries/gateway/IScrollGateway.sol";
import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol";
import {IL1ETHGateway} from "./IL1ETHGateway.sol";
import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol";
import {IL1GatewayRouter} from "./IL1GatewayRouter.sol";
@@ -66,13 +68,13 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
// it can be zero during initialization
if (_defaultERC20Gateway != address(0)) {
defaultERC20Gateway = _defaultERC20Gateway;
emit SetDefaultERC20Gateway(address(0), _defaultERC20Gateway);
emit SetDefaultERC20Gateway(_defaultERC20Gateway);
}
// it can be zero during initialization
if (_ethGateway != address(0)) {
ethGateway = _ethGateway;
emit SetETHGateway(address(0), _ethGateway);
emit SetETHGateway(_ethGateway);
}
}
@@ -223,19 +225,17 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
************************/
/// @inheritdoc IL1GatewayRouter
function setETHGateway(address _newEthGateway) external onlyOwner {
address _oldETHGateway = ethGateway;
ethGateway = _newEthGateway;
function setETHGateway(address _ethGateway) external onlyOwner {
ethGateway = _ethGateway;
emit SetETHGateway(_oldETHGateway, _newEthGateway);
emit SetETHGateway(_ethGateway);
}
/// @inheritdoc IL1GatewayRouter
function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external onlyOwner {
address _oldDefaultERC20Gateway = defaultERC20Gateway;
defaultERC20Gateway = _newDefaultERC20Gateway;
function setDefaultERC20Gateway(address _defaultERC20Gateway) external onlyOwner {
defaultERC20Gateway = _defaultERC20Gateway;
emit SetDefaultERC20Gateway(_oldDefaultERC20Gateway, _newDefaultERC20Gateway);
emit SetDefaultERC20Gateway(_defaultERC20Gateway);
}
/// @inheritdoc IL1GatewayRouter
@@ -243,10 +243,9 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
require(_tokens.length == _gateways.length, "length mismatch");
for (uint256 i = 0; i < _tokens.length; i++) {
address _oldGateway = ERC20Gateway[_tokens[i]];
ERC20Gateway[_tokens[i]] = _gateways[i];
emit SetERC20Gateway(_tokens[i], _oldGateway, _gateways[i]);
emit SetERC20Gateway(_tokens[i], _gateways[i]);
}
}
}

View File

@@ -2,9 +2,12 @@
pragma solidity =0.8.16;
import {ClonesUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/ClonesUpgradeable.sol";
import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {IERC20Metadata} from "../../interfaces/IERC20Metadata.sol";
import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol";
import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol";
import {IL1ERC20Gateway} from "./IL1ERC20Gateway.sol";
@@ -18,7 +21,9 @@ import {L1ERC20Gateway} from "./L1ERC20Gateway.sol";
/// @dev The deposited ERC20 tokens are held in this gateway. On finalizing withdraw, the corresponding
/// token will be transfer to the recipient directly. Any ERC20 that requires non-standard functionality
/// should use a separate gateway.
contract L1StandardERC20Gateway is L1ERC20Gateway {
contract L1StandardERC20Gateway is Initializable, ScrollGatewayBase, L1ERC20Gateway {
using SafeERC20 for IERC20;
/*************
* Variables *
*************/
@@ -76,7 +81,7 @@ contract L1StandardERC20Gateway is L1ERC20Gateway {
// we can calculate the l2 address directly.
bytes32 _salt = keccak256(abi.encodePacked(counterpart, keccak256(abi.encodePacked(_l1Token))));
return ClonesUpgradeable.predictDeterministicAddress(l2TokenImplementation, _salt, l2TokenFactory);
return Clones.predictDeterministicAddress(l2TokenImplementation, _salt, l2TokenFactory);
}
/**********************
@@ -138,9 +143,9 @@ contract L1StandardERC20Gateway is L1ERC20Gateway {
_l2Token = getL2ERC20Address(_token);
// passing symbol/name/decimal in order to deploy in L2.
string memory _symbol = IERC20MetadataUpgradeable(_token).symbol();
string memory _name = IERC20MetadataUpgradeable(_token).name();
uint8 _decimals = IERC20MetadataUpgradeable(_token).decimals();
string memory _symbol = IERC20Metadata(_token).symbol();
string memory _name = IERC20Metadata(_token).name();
uint8 _decimals = IERC20Metadata(_token).decimals();
_l2Data = abi.encode(true, abi.encode(_data, abi.encode(_symbol, _name, _decimals)));
} else {
_l2Data = abi.encode(false, _data);

View File

@@ -2,6 +2,10 @@
pragma solidity =0.8.16;
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IWETH} from "../../interfaces/IWETH.sol";
import {IL2ERC20Gateway} from "../../L2/gateways/IL2ERC20Gateway.sol";
import {IL1ScrollMessenger} from "../IL1ScrollMessenger.sol";
@@ -17,7 +21,9 @@ import {L1ERC20Gateway} from "./L1ERC20Gateway.sol";
/// as Ether and then the Ether will be sent to the `L1ScrollMessenger` contract.
/// On finalizing withdraw, the Ether will be transfered from `L1ScrollMessenger`, then
/// wrapped as WETH and finally transfer to recipient.
contract L1WETHGateway is L1ERC20Gateway {
contract L1WETHGateway is Initializable, ScrollGatewayBase, L1ERC20Gateway {
using SafeERC20 for IERC20;
/*************
* Constants *
*************/

View File

@@ -24,12 +24,12 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
/// @notice Emitted when owner updates gas oracle contract.
/// @param _oldGasOracle The address of old gas oracle contract.
/// @param _newGasOracle The address of new gas oracle contract.
event UpdateGasOracle(address indexed _oldGasOracle, address indexed _newGasOracle);
event UpdateGasOracle(address _oldGasOracle, address _newGasOracle);
/// @notice Emitted when owner updates EnforcedTxGateway contract.
/// @param _oldGateway The address of old EnforcedTxGateway contract.
/// @param _newGateway The address of new EnforcedTxGateway contract.
event UpdateEnforcedTxGateway(address indexed _oldGateway, address indexed _newGateway);
event UpdateEnforcedTxGateway(address _oldGateway, address _newGateway);
/// @notice Emitted when owner updates max gas limit.
/// @param _oldMaxGasLimit The old max gas limit.

View File

@@ -19,9 +19,8 @@ contract L2GasPriceOracle is OwnableUpgradeable, IL2GasPriceOracle {
event UpdateWhitelist(address _oldWhitelist, address _newWhitelist);
/// @notice Emitted when current l2 base fee is updated.
/// @param oldL2BaseFee The original l2 base fee before update.
/// @param newL2BaseFee The current l2 base fee updated.
event L2BaseFeeUpdated(uint256 oldL2BaseFee, uint256 newL2BaseFee);
/// @param l2BaseFee The current l2 base fee updated.
event L2BaseFeeUpdated(uint256 l2BaseFee);
/// @notice Emitted when intrinsic params are updated.
/// @param txGas The intrinsic gas for transaction.
@@ -131,14 +130,13 @@ contract L2GasPriceOracle is OwnableUpgradeable, IL2GasPriceOracle {
}
/// @notice Allows the owner to modify the l2 base fee.
/// @param _newL2BaseFee The new l2 base fee.
function setL2BaseFee(uint256 _newL2BaseFee) external {
/// @param _l2BaseFee The new l2 base fee.
function setL2BaseFee(uint256 _l2BaseFee) external {
require(whitelist.isSenderAllowed(msg.sender), "Not whitelisted sender");
uint256 _oldL2BaseFee = l2BaseFee;
l2BaseFee = _newL2BaseFee;
l2BaseFee = _l2BaseFee;
emit L2BaseFeeUpdated(_oldL2BaseFee, _newL2BaseFee);
emit L2BaseFeeUpdated(_l2BaseFee);
}
/************************

View File

@@ -3,7 +3,6 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {IL1MessageQueue} from "./IL1MessageQueue.sol";
import {IScrollChain} from "./IScrollChain.sol";
@@ -16,7 +15,7 @@ import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol";
/// @title ScrollChain
/// @notice This contract maintains data for the Scroll rollup.
contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
contract ScrollChain is OwnableUpgradeable, IScrollChain {
/**********
* Events *
**********/
@@ -34,7 +33,7 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
/// @notice Emitted when the address of rollup verifier is updated.
/// @param oldVerifier The address of old rollup verifier.
/// @param newVerifier The address of new rollup verifier.
event UpdateVerifier(address indexed oldVerifier, address indexed newVerifier);
event UpdateVerifier(address oldVerifier, address newVerifier);
/// @notice Emitted when the value of `maxNumL2TxInChunk` is updated.
/// @param oldMaxNumL2TxInChunk The old value of `maxNumL2TxInChunk`.
@@ -166,7 +165,7 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
bytes calldata _parentBatchHeader,
bytes[] memory _chunks,
bytes calldata _skippedL1MessageBitmap
) external override OnlySequencer whenNotPaused {
) external override OnlySequencer {
require(_version == 0, "invalid version");
// check whether the batch is empty
@@ -292,7 +291,7 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
bytes32 _postStateRoot,
bytes32 _withdrawRoot,
bytes calldata _aggrProof
) external override OnlyProver whenNotPaused {
) external override OnlyProver {
require(_prevStateRoot != bytes32(0), "previous state root is zero");
require(_postStateRoot != bytes32(0), "new state root is zero");
@@ -356,36 +355,24 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
* Restricted Functions *
************************/
/// @notice Add an account to the sequencer list.
/// @param _account The address of account to add.
function addSequencer(address _account) external onlyOwner {
isSequencer[_account] = true;
/// @notice Update the status of sequencer.
/// @dev This function can only called by contract owner.
/// @param _account The address of account to update.
/// @param _status The status of the account to update.
function updateSequencer(address _account, bool _status) external onlyOwner {
isSequencer[_account] = _status;
emit UpdateSequencer(_account, true);
emit UpdateSequencer(_account, _status);
}
/// @notice Remove an account from the sequencer list.
/// @param _account The address of account to remove.
function removeSequencer(address _account) external onlyOwner {
isSequencer[_account] = false;
/// @notice Update the status of prover.
/// @dev This function can only called by contract owner.
/// @param _account The address of account to update.
/// @param _status The status of the account to update.
function updateProver(address _account, bool _status) external onlyOwner {
isProver[_account] = _status;
emit UpdateSequencer(_account, false);
}
/// @notice Add an account to the prover list.
/// @param _account The address of account to add.
function addProver(address _account) external onlyOwner {
isProver[_account] = true;
emit UpdateProver(_account, true);
}
/// @notice Add an account from the prover list.
/// @param _account The address of account to remove.
function removeProver(address _account) external onlyOwner {
isProver[_account] = false;
emit UpdateProver(_account, false);
emit UpdateProver(_account, _status);
}
/// @notice Update the address verifier contract.
@@ -406,16 +393,6 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
emit UpdateMaxNumL2TxInChunk(_oldMaxNumL2TxInChunk, _maxNumL2TxInChunk);
}
/// @notice Pause the contract
/// @param _status The pause status to update.
function setPause(bool _status) external onlyOwner {
if (_status) {
_pause();
} else {
_unpause();
}
}
/**********************
* Internal Functions *
**********************/
@@ -492,7 +469,6 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
// concatenate l2 transaction hashes
uint256 _numTransactionsInBlock = ChunkCodec.numTransactions(blockPtr);
require(_numTransactionsInBlock >= _numL1MessagesInBlock, "num txs less than num L1 msgs");
for (uint256 j = _numL1MessagesInBlock; j < _numTransactionsInBlock; j++) {
bytes32 txHash;
(txHash, l2TxPtr) = ChunkCodec.loadL2TxHash(l2TxPtr);

View File

@@ -5,15 +5,6 @@ pragma solidity ^0.8.16;
import {IScrollMessenger} from "../libraries/IScrollMessenger.sol";
interface IL2ScrollMessenger is IScrollMessenger {
/**********
* Events *
**********/
/// @notice Emitted when the maximum number of times each message can fail in L2 is updated.
/// @param oldMaxFailedExecutionTimes The old maximum number of times each message can fail in L2.
/// @param newMaxFailedExecutionTimes The new maximum number of times each message can fail in L2.
event UpdateMaxFailedExecutionTimes(uint256 oldMaxFailedExecutionTimes, uint256 newMaxFailedExecutionTimes);
/*****************************
* Public Mutating Functions *
*****************************/

View File

@@ -2,8 +2,12 @@
pragma solidity =0.8.16;
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {IL2ScrollMessenger} from "./IL2ScrollMessenger.sol";
import {L2MessageQueue} from "./predeploys/L2MessageQueue.sol";
import {IL1BlockContainer} from "./predeploys/IL1BlockContainer.sol";
import {IL1GasPriceOracle} from "./predeploys/IL1GasPriceOracle.sol";
import {PatriciaMerkleTrieVerifier} from "../libraries/verifier/PatriciaMerkleTrieVerifier.sol";
import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol";
@@ -22,7 +26,15 @@ import {ScrollMessengerBase} from "../libraries/ScrollMessengerBase.sol";
///
/// @dev It should be a predeployed contract on layer 2 and should hold infinite amount
/// of Ether (Specifically, `uint256(-1)`), which can be initialized in Genesis Block.
contract L2ScrollMessenger is ScrollMessengerBase, IL2ScrollMessenger {
contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2ScrollMessenger {
/**********
* Events *
**********/
/// @notice Emitted when the maximum number of times each message can fail in L2 is updated.
/// @param maxFailedExecutionTimes The new maximum number of times each message can fail in L2.
event UpdateMaxFailedExecutionTimes(uint256 maxFailedExecutionTimes);
/*************
* Constants *
*************/
@@ -56,8 +68,9 @@ contract L2ScrollMessenger is ScrollMessengerBase, IL2ScrollMessenger {
messageQueue = _messageQueue;
}
function initialize(address _counterpart) external initializer {
ScrollMessengerBase.__ScrollMessengerBase_init(_counterpart, address(0));
function initialize(address _counterpart, address _feeVault) external initializer {
PausableUpgradeable.__Pausable_init();
ScrollMessengerBase._initialize(_counterpart, _feeVault);
maxFailedExecutionTimes = 3;
}
@@ -109,16 +122,26 @@ contract L2ScrollMessenger is ScrollMessengerBase, IL2ScrollMessenger {
* Restricted Functions *
************************/
/// @notice Pause the contract
/// @dev This function can only called by contract owner.
/// @param _status The pause status to update.
function setPause(bool _status) external onlyOwner {
if (_status) {
_pause();
} else {
_unpause();
}
}
/// @notice Update max failed execution times.
/// @dev This function can only called by contract owner.
/// @param _newMaxFailedExecutionTimes The new max failed execution times.
function updateMaxFailedExecutionTimes(uint256 _newMaxFailedExecutionTimes) external onlyOwner {
require(_newMaxFailedExecutionTimes > 0, "maxFailedExecutionTimes cannot be zero");
/// @param _maxFailedExecutionTimes The new max failed execution times.
function updateMaxFailedExecutionTimes(uint256 _maxFailedExecutionTimes) external onlyOwner {
require(_maxFailedExecutionTimes > 0, "maxFailedExecutionTimes cannot be zero");
uint256 _oldMaxFailedExecutionTimes = maxFailedExecutionTimes;
maxFailedExecutionTimes = _newMaxFailedExecutionTimes;
maxFailedExecutionTimes = _maxFailedExecutionTimes;
emit UpdateMaxFailedExecutionTimes(_oldMaxFailedExecutionTimes, _newMaxFailedExecutionTimes);
emit UpdateMaxFailedExecutionTimes(_maxFailedExecutionTimes);
}
/**********************

View File

@@ -11,18 +11,15 @@ interface IL2GatewayRouter is IL2ETHGateway, IL2ERC20Gateway {
**********/
/// @notice Emitted when the address of ETH Gateway is updated.
/// @param oldETHGateway The address of the old ETH Gateway.
/// @param newEthGateway The address of the new ETH Gateway.
event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway);
/// @param ethGateway The address of new ETH Gateway.
event SetETHGateway(address indexed ethGateway);
/// @notice Emitted when the address of default ERC20 Gateway is updated.
/// @param oldDefaultERC20Gateway The address of the old default ERC20 Gateway.
/// @param newDefaultERC20Gateway The address of the new default ERC20 Gateway.
event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway);
/// @param defaultERC20Gateway The address of new default ERC20 Gateway.
event SetDefaultERC20Gateway(address indexed defaultERC20Gateway);
/// @notice Emitted when the `gateway` for `token` is updated.
/// @param token The address of token updated.
/// @param oldGateway The corresponding address of the old gateway.
/// @param newGateway The corresponding address of the new gateway.
event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway);
/// @param gateway The corresponding address of gateway updated.
event SetERC20Gateway(address indexed token, address indexed gateway);
}

View File

@@ -2,27 +2,29 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol";
import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {IScrollERC20Upgradeable} from "../../libraries/token/IScrollERC20Upgradeable.sol";
import {ScrollGatewayBase, IScrollGateway} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {IScrollERC20} from "../../libraries/token/IScrollERC20.sol";
/// @title L2ERC20Gateway
/// @notice The `L2ERC20Gateway` is used to withdraw custom ERC20 compatible tokens on layer 2 and
/// finalize deposit the tokens from layer 1.
/// @dev The withdrawn tokens tokens will be burned directly. On finalizing deposit, the corresponding
/// tokens will be minted and transfered to the recipient.
contract L2CustomERC20Gateway is L2ERC20Gateway {
contract L2CustomERC20Gateway is OwnableUpgradeable, ScrollGatewayBase, L2ERC20Gateway {
/**********
* Events *
**********/
/// @notice Emitted when token mapping for ERC20 token is updated.
/// @param l2Token The address of corresponding ERC20 token in layer 2.
/// @param oldL1Token The address of the old corresponding ERC20 token in layer 1.
/// @param newL1Token The address of the new corresponding ERC20 token in layer 1.
event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token);
/// @param _l2Token The address of corresponding ERC20 token on layer 2.
/// @param _l1Token The address of ERC20 token on layer 1.
event UpdateTokenMapping(address _l2Token, address _l1Token);
/*************
* Variables *
@@ -45,6 +47,7 @@ contract L2CustomERC20Gateway is L2ERC20Gateway {
address _messenger
) external initializer {
require(_router != address(0), "zero router address");
OwnableUpgradeable.__Ownable_init();
ScrollGatewayBase._initialize(_counterpart, _router, _messenger);
}
@@ -80,7 +83,7 @@ contract L2CustomERC20Gateway is L2ERC20Gateway {
require(_l1Token != address(0), "token address cannot be 0");
require(_l1Token == tokenMapping[_l2Token], "l1 token mismatch");
IScrollERC20Upgradeable(_l2Token).mint(_to, _amount);
IScrollERC20(_l2Token).mint(_to, _amount);
_doCallback(_to, _data);
@@ -97,10 +100,9 @@ contract L2CustomERC20Gateway is L2ERC20Gateway {
function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner {
require(_l1Token != address(0), "token address cannot be 0");
address _oldL1Token = tokenMapping[_l2Token];
tokenMapping[_l2Token] = _l1Token;
emit UpdateTokenMapping(_l2Token, _oldL1Token, _l1Token);
emit UpdateTokenMapping(_l2Token, _l1Token);
}
/**********************
@@ -127,7 +129,7 @@ contract L2CustomERC20Gateway is L2ERC20Gateway {
}
// 2. Burn token.
IScrollERC20Upgradeable(_token).burn(_from, _amount);
IScrollERC20(_token).burn(_from, _amount);
// 3. Generate message passed to L1StandardERC20Gateway.
bytes memory _message = abi.encodeCall(

View File

@@ -2,12 +2,14 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import {ERC1155HolderUpgradeable, ERC1155ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
import {IL2ERC1155Gateway} from "./IL2ERC1155Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ERC1155Gateway} from "../../L1/gateways/IL1ERC1155Gateway.sol";
import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {ScrollGatewayBase, IScrollGateway} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {IScrollERC1155} from "../../libraries/token/IScrollERC1155.sol";
/// @title L2ERC1155Gateway
@@ -17,16 +19,15 @@ import {IScrollERC1155} from "../../libraries/token/IScrollERC1155.sol";
/// NFT will be minted and transfered to the recipient.
///
/// This will be changed if we have more specific scenarios.
contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC1155Gateway {
contract L2ERC1155Gateway is OwnableUpgradeable, ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC1155Gateway {
/**********
* Events *
**********/
/// @notice Emitted when token mapping for ERC1155 token is updated.
/// @param l2Token The address of corresponding ERC1155 token in layer 2.
/// @param oldL1Token The address of the old corresponding ERC1155 token in layer 1.
/// @param newL1Token The address of the new corresponding ERC1155 token in layer 1.
event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token);
/// @param _l2Token The address of corresponding ERC1155 token on layer 2.
/// @param _l1Token The address of ERC1155 token on layer 1.
event UpdateTokenMapping(address _l2Token, address _l1Token);
/*************
* Variables *
@@ -44,6 +45,7 @@ contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC
}
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC1155HolderUpgradeable.__ERC1155Holder_init();
ERC1155ReceiverUpgradeable.__ERC1155Receiver_init();
@@ -140,10 +142,9 @@ contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC
function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner {
require(_l1Token != address(0), "token address cannot be 0");
address _oldL1Token = tokenMapping[_l2Token];
tokenMapping[_l2Token] = _l1Token;
emit UpdateTokenMapping(_l2Token, _oldL1Token, _l1Token);
emit UpdateTokenMapping(_l2Token, _l1Token);
}
/**********************

View File

@@ -4,11 +4,9 @@ pragma solidity ^0.8.16;
import {IL2ERC20Gateway} from "./IL2ERC20Gateway.sol";
import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
// solhint-disable no-empty-blocks
abstract contract L2ERC20Gateway is ScrollGatewayBase, IL2ERC20Gateway {
abstract contract L2ERC20Gateway is IL2ERC20Gateway {
/*************
* Variables *
*************/

View File

@@ -2,12 +2,14 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import {ERC721HolderUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol";
import {IL2ERC721Gateway} from "./IL2ERC721Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ERC721Gateway} from "../../L1/gateways/IL1ERC721Gateway.sol";
import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {ScrollGatewayBase, IScrollGateway} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {IScrollERC721} from "../../libraries/token/IScrollERC721.sol";
/// @title L2ERC721Gateway
@@ -17,16 +19,15 @@ import {IScrollERC721} from "../../libraries/token/IScrollERC721.sol";
/// NFT will be minted and transfered to the recipient.
///
/// This will be changed if we have more specific scenarios.
contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC721Gateway {
contract L2ERC721Gateway is OwnableUpgradeable, ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC721Gateway {
/**********
* Events *
**********/
/// @notice Emitted when token mapping for ERC721 token is updated.
/// @param l2Token The address of corresponding ERC721 token in layer 2.
/// @param oldL1Token The address of the old corresponding ERC721 token in layer 1.
/// @param newL1Token The address of the new corresponding ERC721 token in layer 1.
event UpdateTokenMapping(address indexed l2Token, address indexed oldL1Token, address indexed newL1Token);
/// @param _l2Token The address of corresponding ERC721 token on layer 2.
/// @param _l1Token The address of ERC721 token on layer 1.
event UpdateTokenMapping(address _l2Token, address _l1Token);
/*************
* Variables *
@@ -44,6 +45,7 @@ contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC72
}
function initialize(address _counterpart, address _messenger) external initializer {
OwnableUpgradeable.__Ownable_init();
ERC721HolderUpgradeable.__ERC721Holder_init();
ScrollGatewayBase._initialize(_counterpart, address(0), _messenger);
@@ -135,10 +137,9 @@ contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC72
function updateTokenMapping(address _l2Token, address _l1Token) external onlyOwner {
require(_l1Token != address(0), "token address cannot be 0");
address _oldL1Token = tokenMapping[_l2Token];
tokenMapping[_l2Token] = _l1Token;
emit UpdateTokenMapping(_l2Token, _oldL1Token, _l1Token);
emit UpdateTokenMapping(_l2Token, _l1Token);
}
/**********************

View File

@@ -2,6 +2,8 @@
pragma solidity =0.8.16;
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {IL1ETHGateway} from "../../L1/gateways/IL1ETHGateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL2ETHGateway} from "./IL2ETHGateway.sol";
@@ -13,7 +15,7 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// finalize deposit ETH from layer 1.
/// @dev The ETH are not held in the gateway. The ETH will be sent to the `L2ScrollMessenger` contract.
/// On finalizing deposit, the Ether will be transfered from `L2ScrollMessenger`, then transfer to recipient.
contract L2ETHGateway is ScrollGatewayBase, IL2ETHGateway {
contract L2ETHGateway is Initializable, ScrollGatewayBase, IL2ETHGateway {
/***************
* Constructor *
***************/

View File

@@ -7,6 +7,9 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
import {IL2GatewayRouter} from "./IL2GatewayRouter.sol";
import {IL2ETHGateway} from "./IL2ETHGateway.sol";
import {IL2ERC20Gateway} from "./IL2ERC20Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ETHGateway} from "../../L1/gateways/IL1ETHGateway.sol";
import {IScrollGateway} from "../../libraries/gateway/IScrollGateway.sol";
/// @title L2GatewayRouter
/// @notice The `L2GatewayRouter` is the main entry for withdrawing Ether and ERC20 tokens.
@@ -42,13 +45,13 @@ contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
// it can be zero during initialization
if (_defaultERC20Gateway != address(0)) {
defaultERC20Gateway = _defaultERC20Gateway;
emit SetDefaultERC20Gateway(address(0), _defaultERC20Gateway);
emit SetDefaultERC20Gateway(_defaultERC20Gateway);
}
// it can be zero during initialization
if (_ethGateway != address(0)) {
ethGateway = _ethGateway;
emit SetETHGateway(address(0), _ethGateway);
emit SetETHGateway(_ethGateway);
}
}
@@ -179,22 +182,20 @@ contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
/// @notice Update the address of ETH gateway contract.
/// @dev This function should only be called by contract owner.
/// @param _newEthGateway The address to update.
function setETHGateway(address _newEthGateway) external onlyOwner {
address _oldEthGateway = ethGateway;
ethGateway = _newEthGateway;
/// @param _ethGateway The address to update.
function setETHGateway(address _ethGateway) external onlyOwner {
ethGateway = _ethGateway;
emit SetETHGateway(_oldEthGateway, _newEthGateway);
emit SetETHGateway(_ethGateway);
}
/// @notice Update the address of default ERC20 gateway contract.
/// @dev This function should only be called by contract owner.
/// @param _newDefaultERC20Gateway The address to update.
function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external onlyOwner {
address _oldDefaultERC20Gateway = defaultERC20Gateway;
defaultERC20Gateway = _newDefaultERC20Gateway;
/// @param _defaultERC20Gateway The address to update.
function setDefaultERC20Gateway(address _defaultERC20Gateway) external onlyOwner {
defaultERC20Gateway = _defaultERC20Gateway;
emit SetDefaultERC20Gateway(_oldDefaultERC20Gateway, _newDefaultERC20Gateway);
emit SetDefaultERC20Gateway(_defaultERC20Gateway);
}
/// @notice Update the mapping from token address to gateway address.
@@ -205,10 +206,9 @@ contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
require(_tokens.length == _gateways.length, "length mismatch");
for (uint256 i = 0; i < _tokens.length; i++) {
address _oldGateway = ERC20Gateway[_tokens[i]];
ERC20Gateway[_tokens[i]] = _gateways[i];
emit SetERC20Gateway(_tokens[i], _oldGateway, _gateways[i]);
emit SetERC20Gateway(_tokens[i], _gateways[i]);
}
}
}

View File

@@ -2,15 +2,18 @@
pragma solidity =0.8.16;
import {AddressUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol";
import {IScrollERC20Upgradeable} from "../../libraries/token/IScrollERC20Upgradeable.sol";
import {IScrollERC20} from "../../libraries/token/IScrollERC20.sol";
import {ScrollStandardERC20} from "../../libraries/token/ScrollStandardERC20.sol";
import {IScrollStandardERC20Factory} from "../../libraries/token/IScrollStandardERC20Factory.sol";
import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {ScrollGatewayBase, IScrollGateway} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// @title L2StandardERC20Gateway
/// @notice The `L2StandardERC20Gateway` is used to withdraw standard ERC20 tokens on layer 2 and
@@ -18,8 +21,9 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// @dev The withdrawn ERC20 tokens will be burned directly. On finalizing deposit, the corresponding
/// token will be minted and transfered to the recipient. Any ERC20 that requires non-standard functionality
/// should use a separate gateway.
contract L2StandardERC20Gateway is L2ERC20Gateway {
using AddressUpgradeable for address;
contract L2StandardERC20Gateway is Initializable, ScrollGatewayBase, L2ERC20Gateway {
using SafeERC20 for IERC20;
using Address for address;
/*************
* Variables *
@@ -110,7 +114,7 @@ contract L2StandardERC20Gateway is L2ERC20Gateway {
_deployL2Token(_deployData, _l1Token);
}
IScrollERC20Upgradeable(_l2Token).mint(_to, _amount);
IScrollERC20(_l2Token).mint(_to, _amount);
_doCallback(_to, _callData);
@@ -141,7 +145,7 @@ contract L2StandardERC20Gateway is L2ERC20Gateway {
require(_l1Token != address(0), "no corresponding l1 token");
// 2. Burn token.
IScrollERC20Upgradeable(_token).burn(_from, _amount);
IScrollERC20(_token).burn(_from, _amount);
// 3. Generate message passed to L1StandardERC20Gateway.
bytes memory _message = abi.encodeCall(

View File

@@ -2,14 +2,15 @@
pragma solidity =0.8.16;
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IL2ERC20Gateway, L2ERC20Gateway} from "./L2ERC20Gateway.sol";
import {IL2ScrollMessenger} from "../IL2ScrollMessenger.sol";
import {IWETH} from "../../interfaces/IWETH.sol";
import {IL1ERC20Gateway} from "../../L1/gateways/IL1ERC20Gateway.sol";
import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
import {ScrollGatewayBase, IScrollGateway} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// @title L2WETHGateway
/// @notice The `L2WETHGateway` contract is used to withdraw `WETH` token on layer 2 and
@@ -18,8 +19,8 @@ import {ScrollGatewayBase} from "../../libraries/gateway/ScrollGatewayBase.sol";
/// then the Ether will be sent to the `L2ScrollMessenger` contract.
/// On finalizing deposit, the Ether will be transfered from `L2ScrollMessenger`, then
/// wrapped as WETH and finally transfer to recipient.
contract L2WETHGateway is L2ERC20Gateway {
using SafeERC20Upgradeable for IERC20Upgradeable;
contract L2WETHGateway is Initializable, ScrollGatewayBase, L2ERC20Gateway {
using SafeERC20 for IERC20;
/*************
* Constants *
@@ -88,7 +89,7 @@ contract L2WETHGateway is L2ERC20Gateway {
require(_amount == msg.value, "msg.value mismatch");
IWETH(_l2Token).deposit{value: _amount}();
IERC20Upgradeable(_l2Token).safeTransfer(_to, _amount);
IERC20(_l2Token).safeTransfer(_to, _amount);
_doCallback(_to, _data);
@@ -117,7 +118,7 @@ contract L2WETHGateway is L2ERC20Gateway {
}
// 2. Transfer token into this contract.
IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount);
IERC20(_token).safeTransferFrom(_from, address(this), _amount);
IWETH(_token).withdraw(_amount);
// 3. Generate message passed to L2StandardERC20Gateway.

View File

@@ -2,6 +2,7 @@
pragma solidity =0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
@@ -16,7 +17,7 @@ import {L2ERC20Gateway} from "../L2ERC20Gateway.sol";
/// @title L2USDCGateway
/// @notice The `L2USDCGateway` contract is used to withdraw `USDC` token on layer 2 and
/// finalize deposit `USDC` from layer 1.
contract L2USDCGateway is L2ERC20Gateway {
contract L2USDCGateway is OwnableUpgradeable, ScrollGatewayBase, L2ERC20Gateway {
using SafeERC20Upgradeable for IERC20Upgradeable;
/*************
@@ -55,6 +56,8 @@ contract L2USDCGateway is L2ERC20Gateway {
) external initializer {
require(_router != address(0), "zero router address");
ScrollGatewayBase._initialize(_counterpart, _router, _messenger);
OwnableUpgradeable.__Ownable_init();
}
/*************************

View File

@@ -5,6 +5,7 @@ pragma solidity =0.8.16;
import {OwnableBase} from "../../libraries/common/OwnableBase.sol";
import {IWhitelist} from "../../libraries/common/IWhitelist.sol";
import {IL1BlockContainer} from "./IL1BlockContainer.sol";
import {IL1GasPriceOracle} from "./IL1GasPriceOracle.sol";
contract L1GasPriceOracle is OwnableBase, IL1GasPriceOracle {

View File

@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
interface IERC20Metadata {
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function decimals() external view returns (uint8);
}

View File

@@ -3,20 +3,13 @@
pragma solidity ^0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {ScrollConstants} from "./constants/ScrollConstants.sol";
import {IScrollMessenger} from "./IScrollMessenger.sol";
// solhint-disable var-name-mixedcase
abstract contract ScrollMessengerBase is
OwnableUpgradeable,
PausableUpgradeable,
ReentrancyGuardUpgradeable,
IScrollMessenger
{
abstract contract ScrollMessengerBase is OwnableUpgradeable, IScrollMessenger {
/**********
* Events *
**********/
@@ -26,6 +19,14 @@ abstract contract ScrollMessengerBase is
/// @param _newFeeVault The address of new fee vault contract.
event UpdateFeeVault(address _oldFeeVault, address _newFeeVault);
/*************
* Constants *
*************/
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/security/ReentrancyGuard.sol
uint256 internal constant _NOT_ENTERED = 1;
uint256 internal constant _ENTERED = 2;
/*************
* Variables *
*************/
@@ -39,13 +40,31 @@ abstract contract ScrollMessengerBase is
/// @notice The address of fee vault, collecting cross domain messaging fee.
address public feeVault;
// @note move to ScrollMessengerBase in next big refactor
/// @dev The status of for non-reentrant check.
uint256 private _lock_status;
/// @dev The storage slots for future usage.
uint256[47] private __gap;
uint256[46] private __gap;
/**********************
* Function Modifiers *
**********************/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_lock_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_lock_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_lock_status = _NOT_ENTERED;
}
modifier notInExecution() {
require(
xDomainMessageSender == ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER,
@@ -58,18 +77,14 @@ abstract contract ScrollMessengerBase is
* Constructor *
***************/
function __ScrollMessengerBase_init(address _counterpart, address _feeVault) internal onlyInitializing {
function _initialize(address _counterpart, address _feeVault) internal {
OwnableUpgradeable.__Ownable_init();
PausableUpgradeable.__Pausable_init();
ReentrancyGuardUpgradeable.__ReentrancyGuard_init();
// initialize to a nonzero value
xDomainMessageSender = ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER;
counterpart = _counterpart;
if (_feeVault != address(0)) {
feeVault = _feeVault;
}
feeVault = _feeVault;
}
// make sure only owner can send ether to messenger to avoid possible user fund loss.
@@ -89,17 +104,6 @@ abstract contract ScrollMessengerBase is
emit UpdateFeeVault(_oldFeeVault, _newFeeVault);
}
/// @notice Pause the contract
/// @dev This function can only called by contract owner.
/// @param _status The pause status to update.
function setPause(bool _status) external onlyOwner {
if (_status) {
_pause();
} else {
_unpause();
}
}
/**********************
* Internal Functions *
**********************/

View File

@@ -2,15 +2,20 @@
pragma solidity ^0.8.16;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {IScrollGateway} from "./IScrollGateway.sol";
import {IScrollMessenger} from "../IScrollMessenger.sol";
import {IScrollGatewayCallback} from "../callbacks/IScrollGatewayCallback.sol";
import {ScrollConstants} from "../constants/ScrollConstants.sol";
abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgradeable, IScrollGateway {
abstract contract ScrollGatewayBase is IScrollGateway {
/*************
* Constants *
*************/
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/security/ReentrancyGuard.sol
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
/*************
* Variables *
*************/
@@ -24,13 +29,35 @@ abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgrad
/// @inheritdoc IScrollGateway
address public override messenger;
/// @dev The status of for non-reentrant check.
uint256 private _status;
/// @dev The storage slots for future usage.
uint256[47] private __gap;
uint256[46] private __gap;
/**********************
* Function Modifiers *
**********************/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
modifier onlyMessenger() {
require(msg.sender == messenger, "only messenger can call");
_;
}
modifier onlyCallByCounterpart() {
address _messenger = messenger; // gas saving
require(msg.sender == _messenger, "only messenger can call");
@@ -60,9 +87,6 @@ abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgrad
require(_counterpart != address(0), "zero counterpart address");
require(_messenger != address(0), "zero messenger address");
ReentrancyGuardUpgradeable.__ReentrancyGuard_init();
OwnableUpgradeable.__Ownable_init();
counterpart = _counterpart;
messenger = _messenger;
@@ -70,6 +94,9 @@ abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgrad
if (_router != address(0)) {
router = _router;
}
// for reentrancy guard
_status = _NOT_ENTERED;
}
/**********************

View File

@@ -76,7 +76,12 @@ contract ScrollStandardERC20 is ERC20PermitUpgradeable, IScrollERC20Upgradeable
}
function isContract(address _addr) private view returns (bool hasCode) {
hasCode = _addr.code.length > 0;
uint256 length;
// solhint-disable-next-line no-inline-assembly
assembly {
length := extcodesize(_addr)
}
return length > 0;
}
/// @inheritdoc IScrollERC20Upgradeable

View File

@@ -20,9 +20,9 @@ import {TransferReentrantToken} from "./mocks/tokens/TransferReentrantToken.sol"
contract L1GatewayRouterTest is L1GatewayTestBase {
// from L1GatewayRouter
event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway);
event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway);
event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway);
event SetETHGateway(address indexed ethGateway);
event SetDefaultERC20Gateway(address indexed defaultERC20Gateway);
event SetERC20Gateway(address indexed token, address indexed gateway);
ScrollStandardERC20 private template;
ScrollStandardERC20Factory private factory;
@@ -94,8 +94,8 @@ contract L1GatewayRouterTest is L1GatewayTestBase {
hevm.stopPrank();
// set by owner, should succeed
hevm.expectEmit(true, true, false, true);
emit SetDefaultERC20Gateway(address(0), address(l1StandardERC20Gateway));
hevm.expectEmit(true, false, false, true);
emit SetDefaultERC20Gateway(address(l1StandardERC20Gateway));
assertEq(address(0), router.getERC20Gateway(address(l1Token)));
assertEq(address(0), router.defaultERC20Gateway());
@@ -121,8 +121,8 @@ contract L1GatewayRouterTest is L1GatewayTestBase {
_tokens[0] = address(l1Token);
_gateways[0] = address(l1StandardERC20Gateway);
hevm.expectEmit(true, true, true, true);
emit SetERC20Gateway(address(l1Token), address(0), address(l1StandardERC20Gateway));
hevm.expectEmit(true, true, false, true);
emit SetERC20Gateway(address(l1Token), address(l1StandardERC20Gateway));
assertEq(address(0), router.getERC20Gateway(address(l1Token)));
router.setERC20Gateway(_tokens, _gateways);

View File

@@ -101,8 +101,8 @@ abstract contract L1GatewayTestBase is DSTestPlus {
}
function prepareL2MessageRoot(bytes32 messageHash) internal {
rollup.addSequencer(address(this));
rollup.addProver(address(this));
rollup.updateSequencer(address(this), true);
rollup.updateProver(address(this), true);
// import genesis batch
bytes memory batchHeader0 = new bytes(89);

View File

@@ -16,7 +16,7 @@ import {L1GatewayTestBase} from "./L1GatewayTestBase.t.sol";
contract L1ScrollMessengerTest is L1GatewayTestBase {
event OnDropMessageCalled(bytes);
event UpdateMaxReplayTimes(uint256 oldMaxReplayTimes, uint256 newMaxReplayTimes);
event UpdateMaxReplayTimes(uint256 maxReplayTimes);
function setUp() public {
L1GatewayTestBase.setUpBase();
@@ -159,7 +159,7 @@ contract L1ScrollMessengerTest is L1GatewayTestBase {
hevm.stopPrank();
hevm.expectEmit(false, false, false, true);
emit UpdateMaxReplayTimes(0, _maxReplayTimes);
emit UpdateMaxReplayTimes(_maxReplayTimes);
assertEq(l1Messenger.maxReplayTimes(), 0);
l1Messenger.updateMaxReplayTimes(_maxReplayTimes);

View File

@@ -19,10 +19,10 @@ import {ScrollStandardERC20Factory} from "../libraries/token/ScrollStandardERC20
import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol";
contract L2GatewayRouterTest is L2GatewayTestBase {
// from L2GatewayRouter
event SetETHGateway(address indexed oldETHGateway, address indexed newEthGateway);
event SetDefaultERC20Gateway(address indexed oldDefaultERC20Gateway, address indexed newDefaultERC20Gateway);
event SetERC20Gateway(address indexed token, address indexed oldGateway, address indexed newGateway);
// from L1GatewayRouter
event SetETHGateway(address indexed ethGateway);
event SetDefaultERC20Gateway(address indexed defaultERC20Gateway);
event SetERC20Gateway(address indexed token, address indexed gateway);
ScrollStandardERC20 private template;
ScrollStandardERC20Factory private factory;
@@ -89,8 +89,8 @@ contract L2GatewayRouterTest is L2GatewayTestBase {
hevm.stopPrank();
// set by owner, should succeed
hevm.expectEmit(true, true, false, true);
emit SetDefaultERC20Gateway(address(0), address(l2StandardERC20Gateway));
hevm.expectEmit(true, false, false, true);
emit SetDefaultERC20Gateway(address(l2StandardERC20Gateway));
assertEq(address(0), router.getERC20Gateway(address(l1Token)));
assertEq(address(0), router.defaultERC20Gateway());
@@ -116,8 +116,8 @@ contract L2GatewayRouterTest is L2GatewayTestBase {
_tokens[0] = address(l1Token);
_gateways[0] = address(l2StandardERC20Gateway);
hevm.expectEmit(true, true, true, true);
emit SetERC20Gateway(address(l1Token), address(0), address(l2StandardERC20Gateway));
hevm.expectEmit(true, true, false, true);
emit SetERC20Gateway(address(l1Token), address(l2StandardERC20Gateway));
assertEq(address(0), router.getERC20Gateway(address(l1Token)));
router.setERC20Gateway(_tokens, _gateways);

View File

@@ -58,7 +58,7 @@ abstract contract L2GatewayTestBase is DSTestPlus {
);
// Initialize L2 contracts
l2Messenger.initialize(address(l1Messenger));
l2Messenger.initialize(address(l1Messenger), feeVault);
l2MessageQueue.initialize(address(l2Messenger));
l1GasOracle.updateWhitelist(address(whitelist));

View File

@@ -40,7 +40,7 @@ contract L2ScrollMessengerTest is DSTestPlus {
);
// Initialize L2 contracts
l2Messenger.initialize(address(l1Messenger));
l2Messenger.initialize(address(l1Messenger), feeVault);
l2MessageQueue.initialize(address(l2Messenger));
l1GasOracle.updateWhitelist(address(whitelist));
}

View File

@@ -18,7 +18,7 @@ contract ScrollChainTest is DSTestPlus {
// from ScrollChain
event UpdateSequencer(address indexed account, bool status);
event UpdateProver(address indexed account, bool status);
event UpdateVerifier(address indexed oldVerifier, address indexed newVerifier);
event UpdateVerifier(address oldVerifier, address newVerifier);
event UpdateMaxNumL2TxInChunk(uint256 oldMaxNumL2TxInChunk, uint256 newMaxNumL2TxInChunk);
event CommitBatch(uint256 indexed batchIndex, bytes32 indexed batchHash);
@@ -62,7 +62,7 @@ contract ScrollChainTest is DSTestPlus {
hevm.expectRevert("caller not sequencer");
rollup.commitBatch(0, batchHeader0, new bytes[](0), new bytes(0));
rollup.addSequencer(address(this));
rollup.updateSequencer(address(this), true);
// invalid version, revert
hevm.expectRevert("invalid version");
@@ -106,17 +106,6 @@ contract ScrollChainTest is DSTestPlus {
hevm.expectRevert("invalid chunk length");
rollup.commitBatch(0, batchHeader0, chunks, new bytes(0));
// num txs less than num L1 msgs, revert
chunk0 = new bytes(1 + 60);
bytes memory bitmap = new bytes(32);
chunk0[0] = bytes1(uint8(1)); // one block in this chunk
chunk0[58] = bytes1(uint8(1)); // numTransactions = 1
chunk0[60] = bytes1(uint8(3)); // numL1Messages = 3
bitmap[31] = bytes1(uint8(7));
chunks[0] = chunk0;
hevm.expectRevert("num txs less than num L1 msgs");
rollup.commitBatch(0, batchHeader0, chunks, bitmap);
// incomplete l2 transaction data, revert
chunk0 = new bytes(1 + 60 + 1);
chunk0[0] = bytes1(uint8(1)); // one block in this chunk
@@ -141,8 +130,8 @@ contract ScrollChainTest is DSTestPlus {
hevm.expectRevert("caller not prover");
rollup.finalizeBatchWithProof(new bytes(0), bytes32(0), bytes32(0), bytes32(0), new bytes(0));
rollup.addProver(address(this));
rollup.addSequencer(address(this));
rollup.updateProver(address(this), true);
rollup.updateSequencer(address(this), true);
bytes memory batchHeader0 = new bytes(89);
@@ -229,8 +218,8 @@ contract ScrollChainTest is DSTestPlus {
}
function testCommitAndFinalizeWithL1Messages() public {
rollup.addSequencer(address(this));
rollup.addProver(address(this));
rollup.updateSequencer(address(this), true);
rollup.updateProver(address(this), true);
// import 300 L1 messages
for (uint256 i = 0; i < 300; i++) {
@@ -464,7 +453,7 @@ contract ScrollChainTest is DSTestPlus {
rollup.revertBatch(new bytes(89), 1);
hevm.stopPrank();
rollup.addSequencer(address(this));
rollup.updateSequencer(address(this), true);
bytes memory batchHeader0 = new bytes(89);
@@ -529,13 +518,11 @@ contract ScrollChainTest is DSTestPlus {
assertEq(uint256(rollup.committedBatches(2)), 0);
}
function testAddAndRemoveSequencer(address _sequencer) public {
function testUpdateSequencer(address _sequencer) public {
// set by non-owner, should revert
hevm.startPrank(address(1));
hevm.expectRevert("Ownable: caller is not the owner");
rollup.addSequencer(_sequencer);
hevm.expectRevert("Ownable: caller is not the owner");
rollup.removeSequencer(_sequencer);
rollup.updateSequencer(_sequencer, true);
hevm.stopPrank();
// change to random operator
@@ -543,22 +530,20 @@ contract ScrollChainTest is DSTestPlus {
emit UpdateSequencer(_sequencer, true);
assertBoolEq(rollup.isSequencer(_sequencer), false);
rollup.addSequencer(_sequencer);
rollup.updateSequencer(_sequencer, true);
assertBoolEq(rollup.isSequencer(_sequencer), true);
hevm.expectEmit(true, false, false, true);
emit UpdateSequencer(_sequencer, false);
rollup.removeSequencer(_sequencer);
rollup.updateSequencer(_sequencer, false);
assertBoolEq(rollup.isSequencer(_sequencer), false);
}
function testAddAndRemoveProver(address _prover) public {
function testUpdateProver(address _prover) public {
// set by non-owner, should revert
hevm.startPrank(address(1));
hevm.expectRevert("Ownable: caller is not the owner");
rollup.addProver(_prover);
hevm.expectRevert("Ownable: caller is not the owner");
rollup.removeProver(_prover);
rollup.updateProver(_prover, true);
hevm.stopPrank();
// change to random operator
@@ -566,39 +551,15 @@ contract ScrollChainTest is DSTestPlus {
emit UpdateProver(_prover, true);
assertBoolEq(rollup.isProver(_prover), false);
rollup.addProver(_prover);
rollup.updateProver(_prover, true);
assertBoolEq(rollup.isProver(_prover), true);
hevm.expectEmit(true, false, false, true);
emit UpdateProver(_prover, false);
rollup.removeProver(_prover);
rollup.updateProver(_prover, false);
assertBoolEq(rollup.isProver(_prover), false);
}
function testSetPause() external {
rollup.addSequencer(address(this));
rollup.addProver(address(this));
// not owner, revert
hevm.startPrank(address(1));
hevm.expectRevert("Ownable: caller is not the owner");
rollup.setPause(false);
hevm.stopPrank();
// pause
rollup.setPause(true);
assertBoolEq(true, rollup.paused());
hevm.expectRevert("Pausable: paused");
rollup.commitBatch(0, new bytes(0), new bytes[](0), new bytes(0));
hevm.expectRevert("Pausable: paused");
rollup.finalizeBatchWithProof(new bytes(0), bytes32(0), bytes32(0), bytes32(0), new bytes(0));
// unpause
rollup.setPause(false);
assertBoolEq(false, rollup.paused());
}
function testUpdateVerifier(address _newVerifier) public {
// set by non-owner, should revert
hevm.startPrank(address(1));
@@ -607,7 +568,7 @@ contract ScrollChainTest is DSTestPlus {
hevm.stopPrank();
// change to random operator
hevm.expectEmit(true, true, false, true);
hevm.expectEmit(false, false, false, true);
emit UpdateVerifier(address(verifier), _newVerifier);
assertEq(rollup.verifier(), address(verifier));

View File

@@ -81,16 +81,12 @@ func (c *CoordinatorApp) MockConfig(store bool) error {
}
// Reset prover manager config for manager test cases.
cfg.ProverManager = &coordinatorConfig.ProverManager{
ProversPerSession: 1,
Verifier: &coordinatorConfig.VerifierConfig{MockMode: true},
CollectionTimeSec: 60,
SessionAttempts: 10,
MaxVerifierWorkers: 4,
ProversPerSession: 1,
Verifier: &coordinatorConfig.VerifierConfig{MockMode: true},
CollectionTimeSec: 60,
}
cfg.DB.DSN = base.DBImg.Endpoint()
cfg.L2.ChainID = 111
cfg.Auth.ChallengeExpireDurationSec = 1
cfg.Auth.LoginExpireDurationSec = 1
c.Config = cfg
if !store {

View File

@@ -1,14 +1,14 @@
{
"prover_manager": {
"provers_per_session": 1,
"session_attempts": 5,
"session_attempts": 2,
"collection_time_sec": 180,
"verifier": {
"mock_mode": true,
"params_path": "",
"assets_path": ""
},
"max_verifier_workers": 4
"max_verifier_workers": 10
},
"db": {
"driver_name": "postgres",
@@ -21,7 +21,7 @@
},
"auth": {
"secret": "prover secret key",
"challenge_expire_duration_sec": 10,
"challenge_expire_duration_sec": 3600,
"login_expire_duration_sec": 3600
}
}

View File

@@ -16,7 +16,7 @@ type ProverManager struct {
// Currently we only consider proving timeout as failure here.
SessionAttempts uint8 `json:"session_attempts"`
// Zk verifier config.
Verifier *VerifierConfig `json:"verifier"`
Verifier *VerifierConfig `json:"verifier,omitempty"`
// Proof collection time (in seconds).
CollectionTimeSec int `json:"collection_time_sec"`
// Max number of workers in verifier worker pool
@@ -33,7 +33,7 @@ type L2 struct {
type Auth struct {
Secret string `json:"secret"`
ChallengeExpireDurationSec int `json:"challenge_expire_duration_sec"`
LoginExpireDurationSec int `json:"login_expire_duration_sec"`
LoginExpireDurationSec int `json:"token_expire_duration_sec"`
}
// Config load configuration items.

View File

@@ -14,14 +14,14 @@ func TestConfig(t *testing.T) {
configTemplate := `{
"prover_manager": {
"provers_per_session": 1,
"session_attempts": 5,
"session_attempts": %d,
"collection_time_sec": 180,
"verifier": {
"mock_mode": true,
"params_path": "",
"agg_vk_path": ""
},
"max_verifier_workers": 4
"max_verifier_workers": %d
},
"db": {
"driver_name": "postgres",
@@ -46,7 +46,8 @@ func TestConfig(t *testing.T) {
assert.NoError(t, tmpFile.Close())
assert.NoError(t, os.Remove(tmpFile.Name()))
}()
_, err = tmpFile.WriteString(configTemplate)
config := fmt.Sprintf(configTemplate, defaultNumberOfSessionRetryAttempts, defaultNumberOfVerifierWorkers)
_, err = tmpFile.WriteString(config)
assert.NoError(t, err)
cfg, err := NewConfig(tmpFile.Name())
@@ -87,4 +88,36 @@ func TestConfig(t *testing.T) {
_, err = NewConfig(tmpFile.Name())
assert.Error(t, err)
})
t.Run("Default MaxVerifierWorkers", func(t *testing.T) {
tmpFile, err := os.CreateTemp("", "example")
assert.NoError(t, err)
defer func() {
assert.NoError(t, tmpFile.Close())
assert.NoError(t, os.Remove(tmpFile.Name()))
}()
config := fmt.Sprintf(configTemplate, defaultNumberOfSessionRetryAttempts, 0)
_, err = tmpFile.WriteString(config)
assert.NoError(t, err)
cfg, err := NewConfig(tmpFile.Name())
assert.NoError(t, err)
assert.Equal(t, defaultNumberOfVerifierWorkers, cfg.ProverManager.MaxVerifierWorkers)
})
t.Run("Default SessionAttempts", func(t *testing.T) {
tmpFile, err := os.CreateTemp("", "example")
assert.NoError(t, err)
defer func() {
assert.NoError(t, tmpFile.Close())
assert.NoError(t, os.Remove(tmpFile.Name()))
}()
config := fmt.Sprintf(configTemplate, 0, defaultNumberOfVerifierWorkers)
_, err = tmpFile.WriteString(config)
assert.NoError(t, err)
cfg, err := NewConfig(tmpFile.Name())
assert.NoError(t, err)
assert.Equal(t, uint8(defaultNumberOfSessionRetryAttempts), cfg.ProverManager.SessionAttempts)
})
}

View File

@@ -31,16 +31,8 @@ func (a *AuthController) Login(c *gin.Context) (interface{}, error) {
if err := c.ShouldBind(&login); err != nil {
return "", fmt.Errorf("missing the public_key, err:%w", err)
}
// check login parameter's token is equal to bearer token, the Authorization must be existed
// if not exist, the jwt token will intercept it
brearToken := c.GetHeader("Authorization")
if brearToken != "Bearer "+login.Message.Challenge {
return "", fmt.Errorf("check challenge failure for the not equal challenge string")
}
// check the challenge is used, if used, return failure
if err := a.loginLogic.InsertChallengeString(c, login.Message.Challenge); err != nil {
if err := a.loginLogic.InsertChallengeString(c, login.Signature); err != nil {
return "", fmt.Errorf("login insert challenge string failure:%w", err)
}
return login, nil
@@ -56,9 +48,8 @@ func (a *AuthController) PayloadFunc(data interface{}) jwt.MapClaims {
// recover the public key
authMsg := message.AuthMsg{
Identity: &message.Identity{
Challenge: v.Message.Challenge,
ProverName: v.Message.ProverName,
ProverVersion: v.Message.ProverVersion,
Challenge: v.Message.Challenge,
ProverName: v.Message.ProverName,
},
Signature: v.Signature,
}
@@ -69,9 +60,8 @@ func (a *AuthController) PayloadFunc(data interface{}) jwt.MapClaims {
}
return jwt.MapClaims{
types.PublicKey: publicKey,
types.ProverName: v.Message.ProverName,
types.ProverVersion: v.Message.ProverVersion,
types.PublicKey: publicKey,
types.ProverName: v.Message.ProverName,
}
}
@@ -85,9 +75,5 @@ func (a *AuthController) IdentityHandler(c *gin.Context) interface{} {
if publicKey, ok := claims[types.PublicKey]; ok {
c.Set(types.PublicKey, publicKey)
}
if proverVersion, ok := claims[types.ProverVersion]; ok {
c.Set(types.ProverVersion, proverVersion)
}
return nil
}

View File

@@ -20,6 +20,6 @@ func NewLoginLogic(db *gorm.DB) *LoginLogic {
}
// InsertChallengeString insert and check the challenge string is existed
func (l *LoginLogic) InsertChallengeString(ctx *gin.Context, challenge string) error {
return l.challengeOrm.InsertChallenge(ctx, challenge)
func (l *LoginLogic) InsertChallengeString(ctx *gin.Context, signature string) error {
return l.challengeOrm.InsertChallenge(ctx, signature)
}

View File

@@ -50,11 +50,6 @@ func (bp *BatchProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
return nil, fmt.Errorf("get prover name from contex failed")
}
proverVersion, proverVersionExist := ctx.Get(coordinatorType.ProverVersion)
if !proverVersionExist {
return nil, fmt.Errorf("get prover version from contex failed")
}
batchTasks, err := bp.batchOrm.UpdateUnassignedBatchReturning(ctx, 1)
if err != nil {
return nil, fmt.Errorf("failed to get unassigned batch proving tasks, error:%w", err)
@@ -69,7 +64,7 @@ func (bp *BatchProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
}
batchTask := batchTasks[0]
log.Info("start batch proof generation session", "id", batchTask.Hash, "public key", publicKey, "prover name", proverName)
log.Info("start batch proof generation session", "id", batchTask.Hash)
if !bp.checkAttemptsExceeded(batchTask.Hash, message.ProofTypeBatch) {
return nil, fmt.Errorf("the batch task id:%s check attempts have reach the maximum", batchTask.Hash)
@@ -80,7 +75,6 @@ func (bp *BatchProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
ProverPublicKey: publicKey.(string),
TaskType: int16(message.ProofTypeBatch),
ProverName: proverName.(string),
ProverVersion: proverVersion.(string),
ProvingStatus: int16(types.ProverAssigned),
FailureType: int16(types.ProverTaskFailureTypeUndefined),
// here why need use UTC time. see scroll/common/databased/db.go

View File

@@ -50,11 +50,6 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
return nil, fmt.Errorf("get prover name from contex failed")
}
proverVersion, proverVersionExist := ctx.Get(coordinatorType.ProverVersion)
if !proverVersionExist {
return nil, fmt.Errorf("get prover version from contex failed")
}
// load and send chunk tasks
chunkTasks, err := cp.chunkOrm.UpdateUnassignedChunkReturning(ctx, getTaskParameter.ProverHeight, 1)
if err != nil {
@@ -71,7 +66,7 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
chunkTask := chunkTasks[0]
log.Info("start chunk generation session", "id", chunkTask.Hash, "public key", publicKey, "prover name", proverName)
log.Info("start chunk generation session", "id", chunkTask.Hash)
if !cp.checkAttemptsExceeded(chunkTask.Hash, message.ProofTypeChunk) {
return nil, fmt.Errorf("chunk proof hash id:%s check attempts have reach the maximum", chunkTask.Hash)
@@ -82,7 +77,6 @@ func (cp *ChunkProverTask) Assign(ctx *gin.Context, getTaskParameter *coordinato
ProverPublicKey: publicKey.(string),
TaskType: int16(message.ProofTypeChunk),
ProverName: proverName.(string),
ProverVersion: proverVersion.(string),
ProvingStatus: int16(types.ProverAssigned),
FailureType: int16(types.ProverTaskFailureTypeUndefined),
// here why need use UTC time. see scroll/common/databased/db.go

View File

@@ -50,7 +50,7 @@ func (b *BaseProverTask) checkAttemptsExceeded(hash string, taskType message.Pro
if len(proverTasks) >= int(b.cfg.ProverManager.SessionAttempts) {
coordinatorSessionsTimeoutTotalCounter.Inc(1)
log.Warn("proof generation prover task reach the max attempts", "hash", hash)
log.Warn("proof generation prover task %s ended because reach the max attempts", hash)
transErr := b.db.Transaction(func(tx *gorm.DB) error {
switch message.ProofType(proverTasks[0].TaskType) {

View File

@@ -87,7 +87,7 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofMsg *message.P
if errors.Is(err, ErrValidatorFailureProofMsgStatusNotOk) {
m.proofFailure(ctx, proofMsg.ID, pk, proofMsg.Type)
}
return err
return nil
}
proofTime := time.Since(proverTask.CreatedAt)
@@ -134,24 +134,23 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofMsg *message.P
}
if verifyErr != nil || !success {
if verifyErr != nil {
// TODO: this is only a temp workaround for testnet, we should return err in real cases
log.Error("failed to verify zk proof", "proof id", proofMsg.ID, "prover pk", pk, "prove type",
proofMsg.Type, "proof time", proofTimeSec, "error", verifyErr)
}
m.proofFailure(ctx, proofMsg.ID, pk, proofMsg.Type)
// TODO: Prover needs to be slashed if proof is invalid.
coordinatorProofsVerifiedFailedTimeTimer.Update(proofTime)
log.Info("proof verified by coordinator failed", "proof id", proofMsg.ID, "prover name", proverTask.ProverName,
"prover pk", pk, "prove type", proofMsg.Type, "proof time", proofTimeSec, "error", verifyErr)
if verifyErr == nil {
verifyErr = fmt.Errorf("verification succeeded and it's an invalid proof")
}
return verifyErr
return nil
}
log.Info("proof verified and valid", "proof id", proofMsg.ID, "prover name", proverTask.ProverName,
"prover pk", pk, "prove type", proofMsg.Type, "proof time", proofTimeSec)
if err := m.closeProofTask(ctx, proofMsg.ID, pk, proofMsg); err != nil {
m.proofRecover(ctx, proofMsg.ID, pk, proofMsg.Type)
return err
}
coordinatorProofsVerifiedSuccessTimeTimer.Update(proofTime)

View File

@@ -294,7 +294,6 @@ func (o *Batch) UpdateUnassignedBatchReturning(ctx context.Context, limit int) (
var batches []*Batch
db = db.Model(&batches).Clauses(clause.Returning{})
db = db.Where("index = (?)", subQueryDB)
db = db.Where("proving_status = ?", types.ProvingTaskUnassigned)
if err := db.Update("proving_status", types.ProvingTaskAssigned).Error; err != nil {
return nil, fmt.Errorf("Batch.UpdateUnassignedBatchReturning error: %w", err)
}

View File

@@ -343,11 +343,8 @@ func (o *Chunk) UpdateBatchHashInRange(ctx context.Context, startIndex uint64, e
// UpdateUnassignedChunkReturning update the unassigned batch which end_block_number <= height and return the update record
func (o *Chunk) UpdateUnassignedChunkReturning(ctx context.Context, height, limit int) ([]*Chunk, error) {
if height <= 0 {
return nil, errors.New("Chunk.UpdateUnassignedBatchReturning error: height must be larger than zero")
}
if limit < 0 {
return nil, errors.New("Chunk.UpdateUnassignedBatchReturning error: limit must not be smaller than zero")
return nil, errors.New("limit must not be smaller than zero")
}
if limit == 0 {
return nil, nil
@@ -364,7 +361,6 @@ func (o *Chunk) UpdateUnassignedChunkReturning(ctx context.Context, height, limi
var chunks []*Chunk
db = db.Model(&chunks).Clauses(clause.Returning{})
db = db.Where("index = (?)", subQueryDB)
db = db.Where("proving_status = ?", types.ProvingTaskUnassigned)
if err := db.Update("proving_status", types.ProvingTaskAssigned).Error; err != nil {
return nil, fmt.Errorf("Chunk.UpdateUnassignedBatchReturning error: %w", err)
}

View File

@@ -22,7 +22,6 @@ type ProverTask struct {
// prover
ProverPublicKey string `json:"prover_public_key" gorm:"column:prover_public_key"`
ProverName string `json:"prover_name" gorm:"column:prover_name"`
ProverVersion string `json:"prover_version" gorm:"column:prover_version"`
// task
TaskID string `json:"task_id" gorm:"column:task_id"`
@@ -137,7 +136,7 @@ func (o *ProverTask) SetProverTask(ctx context.Context, proverTask *ProverTask,
db = db.Model(&ProverTask{})
db = db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "task_type"}, {Name: "task_id"}, {Name: "prover_public_key"}},
DoUpdates: clause.AssignmentColumns([]string{"prover_version", "proving_status", "failure_type", "assigned_at"}),
DoUpdates: clause.AssignmentColumns([]string{"proving_status", "failure_type", "assigned_at"}),
})
if err := db.Create(&proverTask).Error; err != nil {

View File

@@ -17,8 +17,6 @@ func Route(router *gin.Engine, cfg *config.Config) {
func v1(router *gin.RouterGroup, conf *config.Config) {
r := router.Group("/v1")
r.GET("/health", api.HealthCheck.HealthCheck)
challengeMiddleware := middleware.ChallengeMiddleware(conf)
r.GET("/challenge", challengeMiddleware.LoginHandler)
@@ -28,6 +26,7 @@ func v1(router *gin.RouterGroup, conf *config.Config) {
// need jwt token api
r.Use(loginMiddleware.MiddlewareFunc())
{
r.GET("/healthz", api.HealthCheck.HealthCheck)
r.POST("/get_task", api.GetTask.GetTasks)
r.POST("/submit_proof", api.SubmitProof.SubmitProof)
}

View File

@@ -7,15 +7,12 @@ const (
PublicKey = "public_key"
// ProverName the prover name key for context
ProverName = "prover_name"
// ProverVersion the prover version for context
ProverVersion = "prover_version"
)
// Message the login message struct
type Message struct {
Challenge string `form:"challenge" json:"challenge" binding:"required"`
ProverVersion string `form:"prover_version" json:"prover_version" binding:"required"`
ProverName string `form:"prover_name" json:"prover_name" binding:"required"`
Challenge string `form:"challenge" json:"challenge" binding:"required"`
ProverName string `form:"prover_name" json:"prover_name" binding:"required"`
}
// LoginParameter for /login api

View File

@@ -2,8 +2,9 @@ package types
// GetTaskParameter for ProverTasks request parameter
type GetTaskParameter struct {
ProverHeight int `form:"prover_height" json:"prover_height"`
TaskType int `form:"task_type" json:"task_type"`
ProverVersion string `form:"prover_version" json:"prover_version" binding:"required"`
ProverHeight int `form:"prover_height" json:"prover_height" binding:"required"`
TaskType int `form:"task_type" json:"task_type"`
}
// GetTaskSchema the schema data return to prover for get prover task

View File

@@ -0,0 +1,21 @@
package types
import (
"scroll-tech/common/types"
"scroll-tech/common/types/message"
)
// ProversInfo is assigned provers info of a task (session)
type ProversInfo struct {
ID string `json:"id"`
ProverStatusList []*ProverStatus `json:"provers"`
StartTimestamp int64 `json:"start_timestamp"`
ProveType message.ProofType `json:"prove_type,omitempty"`
}
// ProverStatus is the prover name and prover prove status
type ProverStatus struct {
PublicKey string `json:"public_key"`
Name string `json:"name"`
Status types.ProverProveStatus `json:"status"`
}

View File

@@ -101,8 +101,6 @@ func setupCoordinator(t *testing.T, proversPerSession uint8, coordinatorURL stri
assert.NoError(t, runErr)
}
}()
time.Sleep(time.Second * 2)
return proofCollector, srv
}
@@ -172,7 +170,9 @@ func testHandshake(t *testing.T) {
}()
chunkProver := newMockProver(t, "prover_chunk_test", coordinatorURL, message.ProofTypeChunk)
assert.True(t, chunkProver.healthCheckSuccess(t))
token := chunkProver.connectToCoordinator(t)
assert.NotEmpty(t, token)
assert.True(t, chunkProver.healthCheck(t, token, types.Success))
}
func testFailedHandshake(t *testing.T) {
@@ -181,17 +181,21 @@ func testFailedHandshake(t *testing.T) {
proofCollector, httpHandler := setupCoordinator(t, 1, coordinatorURL)
defer func() {
proofCollector.Stop()
assert.NoError(t, httpHandler.Shutdown(context.Background()))
}()
// Try to perform handshake without token
chunkProver := newMockProver(t, "prover_chunk_test", coordinatorURL, message.ProofTypeChunk)
assert.True(t, chunkProver.healthCheckSuccess(t))
token := chunkProver.connectToCoordinator(t)
assert.NotEmpty(t, token)
assert.True(t, chunkProver.healthCheck(t, token, types.Success))
// Try to perform handshake with server shutdown
assert.NoError(t, httpHandler.Shutdown(context.Background()))
time.Sleep(time.Second)
// Try to perform handshake with timeouted token
batchProver := newMockProver(t, "prover_batch_test", coordinatorURL, message.ProofTypeBatch)
assert.True(t, batchProver.healthCheckFailure(t))
token = chunkProver.connectToCoordinator(t)
assert.NotEmpty(t, token)
<-time.After(time.Duration(tokenTimeout+1) * time.Second)
assert.True(t, batchProver.healthCheck(t, token, types.ErrJWTTokenExpired))
}
func testValidProof(t *testing.T) {
@@ -231,7 +235,7 @@ func testValidProof(t *testing.T) {
}
proverTask := provers[i].getProverTask(t, proofType)
assert.NotNil(t, proverTask)
provers[i].submitProof(t, proverTask, proofStatus, types.Success)
provers[i].submitProof(t, proverTask, proofStatus)
}
// verify proof status
@@ -292,7 +296,7 @@ func testInvalidProof(t *testing.T) {
provers[i] = newMockProver(t, "prover_test"+strconv.Itoa(i), coordinatorURL, proofType)
proverTask := provers[i].getProverTask(t, proofType)
assert.NotNil(t, proverTask)
provers[i].submitProof(t, proverTask, verifiedFailed, types.ErrCoordinatorHandleZkProofFailure)
provers[i].submitProof(t, proverTask, verifiedFailed)
}
// verify proof status
@@ -353,7 +357,7 @@ func testProofGeneratedFailed(t *testing.T) {
provers[i] = newMockProver(t, "prover_test"+strconv.Itoa(i), coordinatorURL, proofType)
proverTask := provers[i].getProverTask(t, proofType)
assert.NotNil(t, proverTask)
provers[i].submitProof(t, proverTask, generatedFailed, types.ErrCoordinatorHandleZkProofFailure)
provers[i].submitProof(t, proverTask, generatedFailed)
}
// verify proof status
@@ -427,12 +431,12 @@ func testTimeoutProof(t *testing.T) {
chunkProver2 := newMockProver(t, "prover_test"+strconv.Itoa(2), coordinatorURL, message.ProofTypeChunk)
proverChunkTask2 := chunkProver2.getProverTask(t, message.ProofTypeChunk)
assert.NotNil(t, proverChunkTask2)
chunkProver2.submitProof(t, proverChunkTask2, verifiedSuccess, types.Success)
chunkProver2.submitProof(t, proverChunkTask2, verifiedSuccess)
batchProver2 := newMockProver(t, "prover_test"+strconv.Itoa(3), coordinatorURL, message.ProofTypeBatch)
proverBatchTask2 := batchProver2.getProverTask(t, message.ProofTypeBatch)
assert.NotNil(t, proverBatchTask2)
batchProver2.submitProof(t, proverBatchTask2, verifiedSuccess, types.Success)
batchProver2.submitProof(t, proverBatchTask2, verifiedSuccess)
// verify proof status, it should be verified now, because second prover sent valid proof
chunkProofStatus2, err := chunkOrm.GetProvingStatusByHash(context.Background(), dbChunk.Hash)

View File

@@ -76,15 +76,14 @@ func (r *mockProver) challenge(t *testing.T) string {
func (r *mockProver) login(t *testing.T, challengeString string) string {
authMsg := message.AuthMsg{
Identity: &message.Identity{
Challenge: challengeString,
ProverName: "test",
ProverVersion: "v1.0.0",
Challenge: challengeString,
ProverName: "test",
},
}
assert.NoError(t, authMsg.SignWithKey(r.privKey))
body := fmt.Sprintf("{\"message\":{\"challenge\":\"%s\",\"prover_name\":\"%s\", \"prover_version\":\"%s\"},\"signature\":\"%s\"}",
authMsg.Identity.Challenge, authMsg.Identity.ProverName, authMsg.Identity.ProverVersion, authMsg.Signature)
body := fmt.Sprintf("{\"message\":{\"challenge\":\"%s\",\"prover_name\":\"%s\"},\"signature\":\"%s\"}",
authMsg.Identity.Challenge, authMsg.Identity.ProverName, authMsg.Signature)
var result types.Response
client := resty.New()
@@ -108,27 +107,17 @@ func (r *mockProver) login(t *testing.T, challengeString string) string {
return loginData.Token
}
func (r *mockProver) healthCheckSuccess(t *testing.T) bool {
func (r *mockProver) healthCheck(t *testing.T, token string, errCode int) bool {
var result types.Response
client := resty.New()
resp, err := client.R().
SetHeader("Content-Type", "application/json").
SetHeader("Authorization", fmt.Sprintf("Bearer %s", token)).
SetResult(&result).
Get("http://" + r.coordinatorURL + "/coordinator/v1/health")
Get("http://" + r.coordinatorURL + "/coordinator/v1/healthz")
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode())
assert.Equal(t, ctypes.Success, result.ErrCode)
return true
}
func (r *mockProver) healthCheckFailure(t *testing.T) bool {
var result types.Response
client := resty.New()
resp, err := client.R().
SetResult(&result).
Get("http://" + r.coordinatorURL + "/coordinator/v1/health")
assert.Error(t, err)
assert.Equal(t, 0, resp.StatusCode())
assert.Equal(t, 0, result.ErrCode)
assert.Equal(t, errCode, result.ErrCode)
return true
}
@@ -148,7 +137,7 @@ func (r *mockProver) getProverTask(t *testing.T, proofType message.ProofType) *t
resp, err := client.R().
SetHeader("Content-Type", "application/json").
SetHeader("Authorization", fmt.Sprintf("Bearer %s", token)).
SetBody(map[string]interface{}{"prover_height": 100, "task_type": int(proofType)}).
SetBody(map[string]interface{}{"prover_version": "v1.0.0", "prover_height": 100, "task_type": int(proofType)}).
SetResult(&result).
Post("http://" + r.coordinatorURL + "/coordinator/v1/get_task")
assert.NoError(t, err)
@@ -161,7 +150,7 @@ func (r *mockProver) getProverTask(t *testing.T, proofType message.ProofType) *t
return &result.Data
}
func (r *mockProver) submitProof(t *testing.T, proverTaskSchema *types.GetTaskSchema, proofStatus proofStatus, errCode int) {
func (r *mockProver) submitProof(t *testing.T, proverTaskSchema *types.GetTaskSchema, proofStatus proofStatus) {
proof := &message.ProofMsg{
ProofDetail: &message.ProofDetail{
ID: proverTaskSchema.TaskID,
@@ -216,5 +205,5 @@ func (r *mockProver) submitProof(t *testing.T, proverTaskSchema *types.GetTaskSc
Post("http://" + r.coordinatorURL + "/coordinator/v1/submit_proof")
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode())
assert.Equal(t, errCode, result.ErrCode)
assert.Equal(t, ctypes.Success, result.ErrCode)
}

View File

@@ -8,7 +8,6 @@ create table prover_task
-- prover
prover_public_key VARCHAR NOT NULL,
prover_name VARCHAR NOT NULL,
prover_version VARCHAR NOT NULL,
-- task
task_id VARCHAR NOT NULL,

View File

@@ -1,8 +1,4 @@
.PHONY: clean build test docker
IMAGE_NAME=prover-stats-api
IMAGE_VERSION=latest
REPO_ROOT_DIR=./..
.PHONY: clean build test
build:
GOBIN=$(PWD)/build/bin go build -o $(PWD)/build/bin/prover-stats-api ./cmd
@@ -18,6 +14,3 @@ test:
lint: ## Lint the files - used for CI
GOBIN=$(PWD)/build/bin go run ../build/lint.go
docker:
DOCKER_BUILDKIT=1 docker build -t scrolltech/${IMAGE_NAME}:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/prover-stats-api.Dockerfile

View File

@@ -20,7 +20,6 @@ type ProverTask struct {
TaskID string `json:"task_id" gorm:"column:task_id"`
ProverPublicKey string `json:"prover_public_key" gorm:"column:prover_public_key"`
ProverName string `json:"prover_name" gorm:"column:prover_name"`
ProverVersion string `json:"prover_version" gorm:"column:prover_version"`
TaskType int16 `json:"task_type" gorm:"column:task_type;default:0"`
ProvingStatus int16 `json:"proving_status" gorm:"column:proving_status;default:0"`
FailureType int16 `json:"failure_type" gorm:"column:failure_type;default:0"`
@@ -95,7 +94,7 @@ func (o *ProverTask) SetProverTask(ctx context.Context, proverTask *ProverTask,
db = db.Model(&ProverTask{})
db = db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "task_type"}, {Name: "task_id"}, {Name: "prover_public_key"}},
DoUpdates: clause.AssignmentColumns([]string{"prover_version", "proving_status", "failure_type", "assigned_at"}),
DoUpdates: clause.AssignmentColumns([]string{"proving_status", "failure_type", "assigned_at"}),
})
if err := db.Create(&proverTask).Error; err != nil {

View File

@@ -1,21 +1,21 @@
.PHONY: lint docker clean prover mock-prover
ifeq (4.3,$(firstword $(sort $(MAKE_VERSION) 4.3)))
ZKEVM_VERSION=$(shell grep -m 1 "scroll-prover" ../common/libzkp/impl/Cargo.lock | cut -d "#" -f2 | cut -c-7)
HALO2_VERSION=$(shell grep -m 1 "halo2.git" ../common/libzkp/impl/Cargo.lock | cut -d "#" -f2 | cut -c-7)
ZKEVM_VERSION=$(shell grep -m 1 "scroll-prover" ../common/libzkp/impl/Cargo.lock | cut -d "#" -f2 | cut -c-7)
HALO2_VERSION=$(shell grep -m 1 "halo2.git" ../common/libzkp/impl/Cargo.lock | cut -d "#" -f2 | cut -c-7)
else
ZKEVM_VERSION=$(shell grep -m 1 "scroll-prover" ../common/libzkp/impl/Cargo.lock | cut -d "\#" -f2 | cut -c-7)
HALO2_VERSION=$(shell grep -m 1 "halo2.git" ../common/libzkp/impl/Cargo.lock | cut -d "\#" -f2 | cut -c-7)
ZKEVM_VERSION=$(shell grep -m 1 "scroll-prover" ../common/libzkp/impl/Cargo.lock | cut -d "\#" -f2 | cut -c-7)
HALO2_VERSION=$(shell grep -m 1 "halo2.git" ../common/libzkp/impl/Cargo.lock | cut -d "\#" -f2 | cut -c-7)
endif
HALO2_GPU_VERSION=$(shell ./print_halo2gpu_version.sh | sed -n '2p')
ifeq (${HALO2_GPU_VERSION},)
# use halo2_proofs with CPU
ZK_VERSION=${ZKEVM_VERSION}-${HALO2_VERSION}
ZK_VERSION=${ZKEVM_VERSION}-${HALO2_VERSION}
else
# use halo2_gpu
ZK_VERSION=${ZKEVM_VERSION}-${HALO2_GPU_VERSION}
ZK_VERSION=${ZKEVM_VERSION}-${HALO2_GPU_VERSION}
endif
libzkp:

View File

@@ -14,7 +14,6 @@ import (
"scroll-tech/common/types"
"scroll-tech/common/types/message"
"scroll-tech/common/version"
)
// CoordinatorClient is a client used for interacting with the Coordinator service.
@@ -66,9 +65,8 @@ func (c *CoordinatorClient) Login(ctx context.Context) error {
// Prepare and sign the login request
authMsg := &message.AuthMsg{
Identity: &message.Identity{
ProverVersion: version.Version,
ProverName: c.proverName,
Challenge: challengeResult.Data.Token,
ProverName: c.proverName,
Challenge: challengeResult.Data.Token,
},
}
@@ -80,23 +78,19 @@ func (c *CoordinatorClient) Login(ctx context.Context) error {
// Login to coordinator
loginReq := &LoginRequest{
Message: struct {
Challenge string `json:"challenge"`
ProverName string `json:"prover_name"`
ProverVersion string `json:"prover_version"`
Challenge string `json:"challenge"`
ProverName string `json:"prover_name"`
}{
Challenge: authMsg.Identity.Challenge,
ProverName: authMsg.Identity.ProverName,
ProverVersion: authMsg.Identity.ProverVersion,
Challenge: authMsg.Identity.Challenge,
ProverName: authMsg.Identity.ProverName,
},
Signature: authMsg.Signature,
}
// store JWT token for login requests
c.client.SetAuthToken(challengeResult.Data.Token)
var loginResult LoginResponse
loginResp, err := c.client.R().
SetHeader("Content-Type", "application/json").
SetHeader("Authorization", fmt.Sprintf("Bearer %s", challengeResult.Data.Token)).
SetBody(loginReq).
SetResult(&loginResult).
Post("/coordinator/v1/login")
@@ -138,11 +132,10 @@ func (c *CoordinatorClient) GetTask(ctx context.Context, req *GetTaskRequest) (*
}
if result.ErrCode == types.ErrJWTTokenExpired {
log.Info("JWT expired, attempting to re-login")
log.Debug("JWT expired, attempting to re-login")
if err := c.Login(ctx); err != nil {
return nil, fmt.Errorf("JWT expired, re-login failed: %v", err)
}
log.Info("re-login success")
return c.GetTask(ctx, req)
}
if result.ErrCode != types.Success {
@@ -171,11 +164,10 @@ func (c *CoordinatorClient) SubmitProof(ctx context.Context, req *SubmitProofReq
}
if result.ErrCode == types.ErrJWTTokenExpired {
log.Info("JWT expired, attempting to re-login")
log.Debug("JWT expired, attempting to re-login")
if err := c.Login(ctx); err != nil {
return fmt.Errorf("JWT expired, re-login failed: %v", err)
}
log.Info("re-login success")
return c.SubmitProof(ctx, req)
}
if result.ErrCode != types.Success {

Some files were not shown because too many files have changed in this diff Show More