Commit bafe92d3 authored by vicotor's avatar vicotor

fix bug

parent b6152b2f
......@@ -2,11 +2,17 @@ package mockengine
import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain/chaindb"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/exchain/wrapper"
"math/big"
)
var (
testFrom = common.HexToAddress("0x00000000000000000000000000000000000000AB")
)
type MockEngine struct {
......@@ -19,6 +25,34 @@ func (m MockEngine) Start() error {
return nil
}
func (m MockEngine) fortest(header *nebulav1.BlockHeader) []*nebulav1.Transaction {
if header.Height == 100 {
// add a withdrawal tx.
wtx := nebulav1.WithdrawTransaction{
User: common.HexToAddress("0x9910048204119cCA216a2325A3e2fA05eD4977ef").Bytes(),
Coin: "ETH",
Amount: big.NewInt(5e18).Bytes(),
}
tx := &nebulav1.Transaction{
TxType: nebulav1.TxType_WithdrawTx,
User: testFrom.Hex(),
Nonce: exchain.GetNonce().Bytes(),
Proxy: false,
Tx: &nebulav1.Transaction_WithdrawTx{
WithdrawTx: &wtx,
},
Signature: &nebulav1.Signature{
R: make([]byte, 32),
S: make([]byte, 32),
V: 0,
},
}
return []*nebulav1.Transaction{tx}
}
return nil
}
func (m MockEngine) NewPayload(params exchain.PayloadParams) (exchain.ExecutionResult, error) {
parent, err := m.chain.GetBlockByLabel(chaindb.ExChainBlockLatest)
if err != nil {
......@@ -34,7 +68,16 @@ func (m MockEngine) NewPayload(params exchain.PayloadParams) (exchain.ExecutionR
L1Height: params.L1Info.Number,
AppRoot: make([]byte, 0),
}
receipts, err := m.ProcessTx(header, params.Transactions)
txs := &nebulav1.TransactionList{
Txs: make([]*nebulav1.Transaction, 0),
}
if params.Transactions != nil {
txs.Txs = append(txs.Txs, params.Transactions.Txs...)
}
if testTxs := m.fortest(header); testTxs != nil {
txs.Txs = append(txs.Txs, testTxs...)
}
receipts, err := m.ProcessTx(header, txs)
if err != nil {
m.log.Error("failed to process tx", "err", err)
return exchain.ExecutionResult{}, err
......@@ -43,7 +86,7 @@ func (m MockEngine) NewPayload(params exchain.PayloadParams) (exchain.ExecutionR
result := exchain.ExecutionResult{
Payload: &nebulav1.Block{
Header: header,
Transactions: params.Transactions,
Transactions: txs,
},
Receipts: receipts,
}
......
......@@ -65,7 +65,7 @@ func NewOperator(setup DriverSetup, db metadb.Database) (_ *Operator, err error)
type OperatorProgress struct {
BlockNumber uint64 `json:"block_number"`
Index uint64 `json:"index"`
Finished uint64 `json:"finished"`
Total uint64 `json:"total"`
}
......@@ -240,7 +240,7 @@ func (l *Operator) DoOperator(ctx context.Context) {
}
l.Log.Info("operator latest block number from l2oo", "l2Latest", l2Latest, "progress", progress)
currentFinished := false
if progress.Total == 0 || progress.Index == (progress.Total-1) {
if progress.Total == 0 || progress.Finished == progress.Total {
currentFinished = true
}
// 2. check current process is finished.
......@@ -263,9 +263,9 @@ func (l *Operator) DoOperator(ctx context.Context) {
progress.Total = uint64(len(task))
}
index := progress.Index
for index < progress.Total {
tx := task[progress.Index]
finished := progress.Finished
for finished < progress.Total {
tx := task[finished]
proof, err := rollupClient.WithdrawalProof(ctx, common.HexToHash(tx.TxHash))
if err != nil {
......@@ -293,11 +293,11 @@ func (l *Operator) DoOperator(ctx context.Context) {
l.Log.Error("failed to do withdrawal", "err", err)
return
} else {
index++
finished++
// update process.
l.SetProgress(OperatorProgress{
BlockNumber: progress.BlockNumber,
Index: index,
Finished: finished,
Total: progress.Total,
})
}
......@@ -328,7 +328,7 @@ func (l *Operator) DoOperator(ctx context.Context) {
l.SetOperatorTaskList(OperatorTaskList{})
l.SetProgress(OperatorProgress{
BlockNumber: blkNum,
Index: 0,
Finished: 0,
Total: 0,
})
continue
......@@ -337,7 +337,7 @@ func (l *Operator) DoOperator(ctx context.Context) {
}
newProgress := OperatorProgress{
BlockNumber: blkNum,
Index: 0,
Finished: 0,
Total: uint64(len(withDrawalTxs)),
}
tasks := make([]OperatorTask, 0)
......@@ -351,10 +351,10 @@ func (l *Operator) DoOperator(ctx context.Context) {
l.SetProgress(newProgress)
// 5. to process each withdrawal tx.
index := newProgress.Index
finished := newProgress.Finished
for index < newProgress.Total {
tx := tasks[index]
for finished < newProgress.Total {
tx := tasks[finished]
proof, err := rollupClient.WithdrawalProof(ctx, common.HexToHash(tx.TxHash))
if err != nil {
......@@ -382,11 +382,11 @@ func (l *Operator) DoOperator(ctx context.Context) {
l.Log.Error("failed to do withdrawal", "err", err)
return
} else {
index++
finished++
// update process.
l.SetProgress(OperatorProgress{
BlockNumber: newProgress.BlockNumber,
Index: index,
Finished: finished,
Total: newProgress.Total,
})
}
......
......@@ -430,6 +430,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
// revert GasEstimation();
// }
}
event Println(uint256 line);
/// @notice withdrawal for a user.
......@@ -446,15 +447,20 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
external
whenNotPaused
{
emit Println(1);
if (_param.user == address(this)) revert BadTarget();
emit Println(2);
bytes32 outputRoot = l2Oracle.getL2Output(_l2OutputIndex).outputRoot;
emit Println(3);
bytes32 withdrawalHash = Hashing.hashExChainWithdrawal(_param);
emit Println(4);
ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];
require(
provenWithdrawal.timestamp == 0
|| l2Oracle.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot != provenWithdrawal.outputRoot,
"OptimismPortal: withdrawal hash has already been proven"
);
emit Println(5);
// Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract
// on L2. If this is true, under the assumption that the SecureMerkleTrie does not have
......@@ -469,6 +475,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
}),
"OptimismPortal: invalid withdrawal inclusion proof"
);
emit Println(6);
// Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and
// `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be
......@@ -478,23 +485,29 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
timestamp: uint128(block.timestamp),
l2OutputIndex: uint128(_l2OutputIndex)
});
emit Println(7);
// Check that this withdrawal has not already been finalized, this is replay protection.
require(finalizedWithdrawals[withdrawalHash] == false, "OptimismPortal: withdrawal has already been finalized");
emit Println(8);
// Mark the withdrawal as finalized so it can't be replayed.
finalizedWithdrawals[withdrawalHash] = true;
emit Println(9);
// Set the l2Sender so contracts know who triggered this withdrawal on L2.
// This acts as a reentrancy guard.
l2Sender = msg.sender;
bool success;
emit Println(10);
(address token,) = gasPayingToken();
if (token == Constants.ETHER) {
emit Println(11);
success = SafeCall.send(_param.user, _param.value);
} else {
// Cannot call the token contract directly from the portal. This would allow an attacker
// to call approve from a withdrawal and drain the balance of the portal.
emit Println(12);
if (_param.user == token) revert BadTarget();
// Only transfer value when a non zero value is specified. This saves gas in the case of
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment